1# Copyright 2018 The Bazel Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Common attributes for Android rules.""" 16 17load(":utils.bzl", "log") 18load(":native_toolchain_attrs.bzl", "ANDROID_SDK_TOOLCHAIN_TYPE_DEFAULT") 19 20def _add(attrs, *others): 21 new = {} 22 new.update(attrs) 23 for o in others: 24 for name in o.keys(): 25 if name in new: 26 log.error("Attr '%s' is defined twice." % name) 27 new[name] = o[name] 28 return new 29 30def _replace(attrs, **kwargs): 31 # Verify that new values are replacing existing ones, not adding. 32 for name in kwargs.keys(): 33 if name not in attrs: 34 log.error("Attr '%s' is not defined, replacement failed." % name) 35 new = dict() 36 new.update(attrs) 37 new.update(kwargs) 38 return new 39 40def _make_tristate_attr(default, doc = "", mandatory = False): 41 return attr.int( 42 default = default, 43 doc = doc, 44 mandatory = mandatory, 45 values = [-1, 0, 1], 46 ) 47 48def _normalize_tristate(attr_value): 49 """Normalizes the tristate value going into a rule. 50 51 This is required because "tristate" is not officially supported as an 52 attribute type. An equivalent attribute type is an in with a constrained 53 set of values, namely [-1, 0, 1]. Unfortunately, tristate accepts 54 multiple types, integers, booleans and strings ("auto"). As a result, this 55 method normalizes the inputs to an integer. 56 57 This method needs to be applied to attributes that were formally tristate 58 to normalize the inputs. 59 """ 60 if type(attr_value) == "int": 61 return attr_value 62 63 if type(attr_value) == "string": 64 if attr_value.lower() == "auto": 65 return -1 66 67 if type(attr_value) == "bool": 68 return int(attr_value) 69 70 return attr_value # Return unknown type, let the rule fail. 71 72_tristate = struct( 73 create = _make_tristate_attr, 74 normalize = _normalize_tristate, 75 yes = 1, 76 no = 0, 77 auto = -1, 78) 79 80_JAVA_RUNTIME = dict( 81 _host_javabase = attr.label( 82 cfg = "exec", 83 default = Label("//tools/jdk:current_java_runtime"), 84 ), 85) 86 87 88# Android SDK attribute. 89_ANDROID_SDK = dict( 90 _android_sdk = attr.label( 91 allow_rules = ["android_sdk"], 92 default = configuration_field( 93 fragment = "android", 94 name = "android_sdk_label", 95 ), 96 providers = [AndroidSdkInfo], 97 ), 98) 99 100# Compilation attributes for Android rules. 101_COMPILATION = _add( 102 dict( 103 assets = attr.label_list( 104 allow_files = True, 105 cfg = "target", 106 doc = ("The list of assets to be packaged. This is typically a glob of " + 107 "all files under the assets directory. You can also reference " + 108 "other rules (any rule that produces files) or exported files in " + 109 "the other packages, as long as all those files are under the " + 110 "assets_dir directory in the corresponding package."), 111 ), 112 assets_dir = attr.string( 113 doc = ("The string giving the path to the files in assets. " + 114 "The pair assets and assets_dir describe packaged assets and either both " + 115 "attributes should be provided or none of them."), 116 ), 117 custom_package = attr.string( 118 doc = ("Java package for which java sources will be generated. " + 119 "By default the package is inferred from the directory where the BUILD file " + 120 "containing the rule is. You can specify a different package but this is " + 121 "highly discouraged since it can introduce classpath conflicts with other " + 122 "libraries that will only be detected at runtime."), 123 ), 124 manifest = attr.label( 125 allow_single_file = [".xml"], 126 doc = ("The name of the Android manifest file, normally " + 127 "AndroidManifest.xml. Must be defined if resource_files or assets are defined."), 128 ), 129 resource_files = attr.label_list( 130 allow_files = True, 131 doc = ("The list of resources to be packaged. This " + 132 "is typically a glob of all files under the res directory. Generated files " + 133 "(from genrules) can be referenced by Label here as well. The only " + 134 "restriction is that the generated outputs must be under the same \"res\" " + 135 "directory as any other resource files that are included."), 136 ), 137 data = attr.label_list( 138 allow_files = True, 139 doc = ( 140 "Files needed by this rule at runtime. May list file or rule targets. Generally allows any target.\n\n" + 141 "The default outputs and runfiles of targets in the `data` attribute should appear in the `*.runfiles` area of" + 142 "any executable which is output by or has a runtime dependency on this target. " + 143 "This may include data files or binaries used when this target's " + 144 "[srcs](https://docs.bazel.build/versions/main/be/common-definitions.html#typical.srcs) are executed. " + 145 "See the [data dependencies](https://docs.bazel.build/versions/main/build-ref.html#data) section " + 146 "for more information about how to depend on and use data files.\n\n" + 147 "New rules should define a `data` attribute if they process inputs which might use other inputs at runtime. " + 148 "Rules' implementation functions must also " + 149 "[populate the target's runfiles](https://docs.bazel.build/versions/main/skylark/rules.html#runfiles) " + 150 "from the outputs and runfiles of any `data` attribute, as well as runfiles from any dependency attribute " + 151 "which provides either source code or runtime dependencies." 152 ), 153 ), 154 plugins = attr.label_list( 155 providers = [JavaPluginInfo], 156 cfg = "exec", 157 doc = ( 158 "Java compiler plugins to run at compile-time. " + 159 "Every `java_plugin` specified in the plugins attribute will be run whenever this rule is built. " + 160 "A library may also inherit plugins from dependencies that use [exported_plugins](https://docs.bazel.build/versions/main/be/java.html#java_library.exported_plugins). " + 161 "Resources generated by the plugin will be included in the resulting jar of this rule." 162 ), 163 ), 164 javacopts = attr.string_list( 165 doc = ( 166 "Extra compiler options for this library. " + 167 "Subject to \"[Make variable](https://docs.bazel.build/versions/main/be/make-variables.html)\" substitution and " + 168 "[Bourne shell tokenization](https://docs.bazel.build/versions/main/be/common-definitions.html#sh-tokenization).\n" + 169 "These compiler options are passed to javac after the global compiler options." 170 ), 171 ), 172 # TODO: Expose getPlugins() in JavaConfiguration.java 173 # com/google/devtools/build/lib/rules/java/JavaConfiguration.java 174 # com/google/devtools/build/lib/rules/java/JavaOptions.java 175 # 176 # _java_plugins = attr.label( 177 # allow_rules = ["java_plugin"], 178 # default = configuration_field( 179 # fragment = "java", 180 # name = "plugin", 181 # ), 182 # ), 183 ), 184 _JAVA_RUNTIME, 185) 186 187# Attributes for rules that use the AndroidDataContext android_data.make_context 188_DATA_CONTEXT = _add( 189 dict( 190 # Additional attrs needed for AndroidDataContext 191 _add_g3itr_xslt = attr.label( 192 cfg = "exec", 193 default = Label("//tools/android/xslt:add_g3itr.xslt"), 194 allow_single_file = True, 195 ), 196 _android_manifest_merge_tool = attr.label( 197 cfg = "exec", 198 default = Label("//tools/android:merge_manifests"), 199 executable = True, 200 ), 201 # TODO(b/145617058) Switching back to head RPBB until the Android rules release process is improved 202 _android_resources_busybox = attr.label( 203 cfg = "exec", 204 default = Label("//rules:ResourceProcessorBusyBox"), 205 executable = True, 206 ), 207 _xsltproc_tool = attr.label( 208 cfg = "exec", 209 default = Label("//tools/android/xslt:xslt"), 210 allow_files = True, 211 ), 212 ), 213 _ANDROID_SDK, 214) 215 216 217 218 219 220 221 222ANDROID_SDK_ATTRS = dict( 223 aapt = attr.label( 224 allow_single_file = True, 225 cfg = "exec", 226 executable = True, 227 mandatory = True, 228 ), 229 aapt2 = attr.label( 230 allow_single_file = True, 231 cfg = "exec", 232 executable = True, 233 ), 234 aidl = attr.label( 235 allow_files = True, 236 cfg = "exec", 237 executable = True, 238 mandatory = True, 239 ), 240 aidl_lib = attr.label( 241 allow_files = [".jar"], 242 ), 243 android_jar = attr.label( 244 allow_single_file = [".jar"], 245 cfg = "exec", 246 mandatory = True, 247 ), 248 annotations_jar = attr.label( 249 allow_single_file = [".jar"], 250 cfg = "exec", 251 ), 252 apkbuilder = attr.label( 253 allow_files = True, 254 cfg = "exec", 255 executable = True, 256 ), 257 apksigner = attr.label( 258 allow_files = True, 259 cfg = "exec", 260 executable = True, 261 mandatory = True, 262 ), 263 adb = attr.label( 264 allow_single_file = True, 265 cfg = "exec", 266 executable = True, 267 mandatory = True, 268 ), 269 build_tools_version = attr.string(), 270 dx = attr.label( 271 allow_files = True, 272 cfg = "exec", 273 executable = True, 274 mandatory = True, 275 ), 276 framework_aidl = attr.label( 277 allow_single_file = True, 278 cfg = "exec", 279 mandatory = True, 280 ), 281 legacy_main_dex_list_generator = attr.label( 282 allow_files = True, 283 cfg = "exec", 284 executable = True, 285 ), 286 main_dex_classes = attr.label( 287 allow_single_file = True, 288 cfg = "exec", 289 mandatory = True, 290 ), 291 main_dex_list_creator = attr.label( 292 allow_files = True, 293 cfg = "exec", 294 executable = True, 295 mandatory = True, 296 ), 297 proguard = attr.label( 298 allow_files = True, 299 cfg = "exec", 300 executable = True, 301 mandatory = True, 302 ), 303 shrinked_android_jar = attr.label( 304 allow_single_file = True, 305 cfg = "exec", 306 ), 307 source_properties = attr.label( 308 allow_single_file = True, 309 cfg = "exec", 310 ), 311 zipalign = attr.label( 312 allow_single_file = True, 313 cfg = "exec", 314 executable = True, 315 mandatory = True, 316 ), 317 _proguard = attr.label( 318 cfg = "exec", 319 default = configuration_field( 320 fragment = "java", 321 name = "proguard_top", 322 ), 323 ), 324 _system = attr.label( 325 default = Label("//tools/android:bootclasspath_android_only"), 326 ), 327) 328 329# Attributes for resolving platform-based toolchains. Only needed by the native 330# DexArchiveAspect. 331_ANDROID_TOOLCHAIN_ATTRS = dict( 332 _android_sdk_toolchain_type = attr.label( 333 allow_rules = ["toolchain_type"], 334 default = ANDROID_SDK_TOOLCHAIN_TYPE_DEFAULT, 335 ), 336) 337 338ANDROID_TOOLS_DEFAULTS_JAR_ATTRS = _add(_ANDROID_SDK) 339 340attrs = struct( 341 ANDROID_SDK = _ANDROID_SDK, 342 COMPILATION = _COMPILATION, 343 DATA_CONTEXT = _DATA_CONTEXT, 344 JAVA_RUNTIME = _JAVA_RUNTIME, 345 ANDROID_TOOLCHAIN_ATTRS = _ANDROID_TOOLCHAIN_ATTRS, 346 tristate = _tristate, 347 add = _add, 348 replace = _replace, 349) 350