• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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