aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Humesky <ahumesky@google.com>2021-03-12 18:54:21 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-03-12 18:54:21 +0000
commitbe08255c526ee9364a5f5089a4cd5c2afe4024ed (patch)
tree1235b70b3a0d7150512ecc273c4db0294c76d6ca
parentb8983ae9e51d225bb60d3298bd670284b615cc68 (diff)
parent133707eb387b773f4a253698e8995ec39a3b5a87 (diff)
downloadbazelbuild-rules_android-be08255c526ee9364a5f5089a4cd5c2afe4024ed.tar.gz
Merge remote-tracking branch 'remotes/aosp/upstream-pre-alpha' into import am: 6c9db3a63b am: 05eb06d367 am: 133707eb38
Original change: https://android-review.googlesource.com/c/platform/external/bazelbuild-rules_android/+/1628943 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I5453e8816ff6422f5babefaf9847202d4ffa7318
-rw-r--r--.bazelci/postsubmit.yml22
-rw-r--r--AUTHORS9
-rw-r--r--CODEOWNERS1
-rw-r--r--CONTRIBUTING.md39
-rw-r--r--CONTRIBUTORS16
-rw-r--r--LICENSE202
-rw-r--r--README.md51
-rw-r--r--ROADMAP.md71
-rw-r--r--WORKSPACE3
-rw-r--r--rules/BUILD18
-rw-r--r--rules/aar_import/BUILD21
-rw-r--r--rules/aar_import/attrs.bzl64
-rw-r--r--rules/aar_import/impl.bzl547
-rw-r--r--rules/aar_import/rule.bzl26
-rw-r--r--rules/acls.bzl318
-rw-r--r--rules/acls/BUILD6
-rw-r--r--rules/acls/aar_import_deps_checker.bzl27
-rw-r--r--rules/acls/aar_import_explicit_exports_manifest.bzl19
-rw-r--r--rules/acls/aar_import_exports_r_java.bzl19
-rw-r--r--rules/acls/aar_import_package_check.bzl21
-rw-r--r--rules/acls/aar_propagate_resources.bzl24
-rw-r--r--rules/acls/ait_install_snapshots.bzl23
-rw-r--r--rules/acls/ait_virtual_device.bzl21
-rw-r--r--rules/acls/allow_resource_conflicts.bzl20
-rw-r--r--rules/acls/android_archive_dogfood.bzl20
-rw-r--r--rules/acls/android_binary_starlark_resources.bzl22
-rw-r--r--rules/acls/android_build_stamping_rollout.bzl22
-rw-r--r--rules/acls/android_device_plugin_rollout.bzl26
-rw-r--r--rules/acls/android_feature_splits_dogfood.bzl24
-rw-r--r--rules/acls/android_instrumentation_binary_starlark_resources.bzl22
-rw-r--r--rules/acls/android_library_implicit_exports.bzl23
-rw-r--r--rules/acls/android_library_resources_without_srcs.bzl19
-rw-r--r--rules/acls/android_library_starlark_resources.bzl23
-rw-r--r--rules/acls/android_lint_rollout.bzl19
-rw-r--r--rules/acls/android_test_lockdown.bzl21
-rw-r--r--rules/acls/android_test_platform_rollout.bzl26
-rw-r--r--rules/acls/android_test_starlark_resources.bzl17
-rw-r--r--rules/acls/b122039567.bzl18
-rw-r--r--rules/acls/b123854163.bzl18
-rw-r--r--rules/acls/dex2oat_opts.bzl19
-rw-r--r--rules/acls/fix_application_id.bzl27
-rw-r--r--rules/acls/fix_export_exporting_rollout.bzl24
-rw-r--r--rules/acls/fix_resource_transitivity_rollout.bzl22
-rw-r--r--rules/acls/host_dex2oat_rollout.bzl27
-rw-r--r--rules/acls/install_apps_in_data.bzl18
-rw-r--r--rules/acls/kt_android_library_rollout.bzl24
-rw-r--r--rules/acls/library_rollout.bzl23
-rw-r--r--rules/acls/library_rollout_override.bzl17
-rw-r--r--rules/acls/local_test_multi_proto.bzl23
-rw-r--r--rules/acls/local_test_rollout.bzl22
-rw-r--r--rules/acls/local_test_starlark_resources.bzl22
-rw-r--r--rules/acls/nitrogen_test_runner_rollout.bzl28
-rw-r--r--rules/acls/partial_jetification_targets.bzl20
-rw-r--r--rules/acls/sourceless_binary_rollout.bzl21
-rw-r--r--rules/acls/starlark_resources_diff.bzl18
-rw-r--r--rules/acls/test_to_instrument_test_rollout.bzl21
-rw-r--r--rules/android_binary.bzl42
-rw-r--r--rules/android_library/BUILD21
-rw-r--r--rules/android_library/attrs.bzl73
-rw-r--r--rules/android_library/impl.bzl534
-rw-r--r--rules/android_library/rule.bzl135
-rw-r--r--rules/android_local_test.bzl27
-rw-r--r--rules/android_ndk_repository.bzl25
-rw-r--r--rules/android_packaged_resources/BUILD25
-rw-r--r--rules/android_packaged_resources/attrs.bzl69
-rw-r--r--rules/android_packaged_resources/impl.bzl111
-rw-r--r--rules/android_packaged_resources/rule.bzl91
-rw-r--r--rules/android_sdk.bzl53
-rw-r--r--rules/android_sdk_repository.bzl25
-rw-r--r--rules/android_tools_defaults_jar.bzl32
-rw-r--r--rules/attrs.bzl286
-rw-r--r--rules/busybox.bzl1033
-rw-r--r--rules/common.bzl111
-rw-r--r--rules/data_binding.bzl286
-rw-r--r--rules/data_binding_annotation_template.txt15
-rw-r--r--rules/flags/BUILD22
-rw-r--r--rules/flags/flag_defs.bzl92
-rw-r--r--rules/flags/flags.bzl255
-rw-r--r--rules/idl.bzl264
-rw-r--r--rules/intellij.bzl165
-rw-r--r--rules/java.bzl447
-rw-r--r--rules/migration_tag_DONOTUSE.bzl25
-rw-r--r--rules/path.bzl102
-rw-r--r--rules/platforms/BUILD33
-rw-r--r--rules/processing_pipeline.bzl161
-rw-r--r--rules/proguard.bzl110
-rw-r--r--rules/providers.bzl118
-rw-r--r--rules/res_v3_dummy_AndroidManifest.xml2
-rw-r--r--rules/res_v3_dummy_R.txt1
-rw-r--r--rules/resources.bzl1638
-rw-r--r--rules/robolectric_properties_template.txt5
-rw-r--r--rules/rules.bzl129
-rw-r--r--rules/toolchains/emulator/BUILD27
-rw-r--r--rules/toolchains/emulator/toolchain.bzl59
-rw-r--r--rules/utils.bzl451
-rw-r--r--test/rules/resources/BUILD4
-rw-r--r--toolchains/android/BUILD52
-rw-r--r--toolchains/android/toolchain.bzl167
-rwxr-xr-xtoolchains/android/zip.sh25
-rw-r--r--toolchains/android_sdk/BUILD27
-rw-r--r--toolchains/emulator/BUILD27
-rw-r--r--tools/android/BUILD13
-rw-r--r--tools/android/defs.bzl27
-rw-r--r--tools/android/xslt/BUILD7
-rw-r--r--tools/android/xslt/add_g3itr.xslt7
-rwxr-xr-xtools/android/xslt/xslt.sh17
-rw-r--r--tools/jdk/BUILD11
107 files changed, 9768 insertions, 0 deletions
diff --git a/.bazelci/postsubmit.yml b/.bazelci/postsubmit.yml
new file mode 100644
index 0000000..c1218a6
--- /dev/null
+++ b/.bazelci/postsubmit.yml
@@ -0,0 +1,22 @@
+---
+platforms:
+ ubuntu1604:
+ build_targets:
+ - "//..."
+ # test_targets:
+ # - "//..."
+ ubuntu1804:
+ build_targets:
+ - "//..."
+ # test_targets:
+ # - "//..."
+ macos:
+ build_targets:
+ - "//..."
+ # test_targets:
+ # - "//..."
+ windows:
+ build_targets:
+ - "//..."
+ # test_targets:
+ # - "//..."
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..dc35af2
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,9 @@
+# This the official list of authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as:
+# Name or Organization <email address>
+# The email address is not required for organizations.
+
+Google LLC
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 0000000..6902cfb
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1 @@
+* @djwhang @jin @ahumesky @mauriciogg @timpeut @git-str
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..99da6f8
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,39 @@
+Want to contribute? Great! First, read this page (including the small print at
+the end).
+
+### Before you contribute
+**Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
+(CLA)**, which you can do online.
+
+The CLA is necessary mainly because you own the copyright to your changes,
+even after your contribution becomes part of our codebase, so we need your
+permission to use and distribute your code. We also need to be sure of
+various other things — for instance that you'll tell us if you know that
+your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+
+### The small print
+Contributions made by corporations are covered by a different agreement than
+the one above, the
+[Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
+
+### Contribution process
+
+1. Explain your idea and discuss your plan with members of the team. The best
+ way to do this is to create
+ an [issue](https://github.com/bazelbuild/rules_android/issues) or comment on
+ an existing issue.
+1. Prepare a git commit with your change. Don't forget to
+ add [tests](https://github.com/bazelbuild/rules_android/tree/master/tests).
+ Run the existing tests with `bazel test //...`. Update
+ [README.md](https://github.com/bazelbuild/rules_android/blob/master/README.md)
+ if appropriate.
+1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/).
+ This will start the code review process. **All submissions, including
+ submissions by project members, require review.**
+1. You may be asked to make some changes. You'll also need to sign the CLA at
+ this point, if you haven't done so already. Our continuous integration bots
+ will test your change automatically on supported platforms. Once everything
+ looks good, your change will be merged.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
index 0000000..8fc0e51
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,16 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people. For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# Names should be added to this file as:
+# Name <email address>
+Daniel Whang <djwhang@google.com>
+Mauricio Galindo <mauriciogg@google.com>
+Stefan Ramsauer <str@google.com>
+Tim Peut <timpeut@google.com>
+Alex Humesky <ahumesky@google.com>
+Jingwen Chen <jingwen@google.com>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6cba04f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,51 @@
+# Android support in Bazel
+
+## Disclaimer
+
+NOTE: This branch contains a development preview of the Starlark implementation of Android rules for Bazel. This code is incomplete and may not function as-is.
+
+Bazel 4.0.0 or newer and the following flags are necessary to use these rules:
+```
+--experimental_enable_android_migration_apis
+--experimental_google_legacy_api
+--incompatible_java_common_parameters
+--android_databinding_use_v3_4_args
+--experimental_android_databinding_v2
+```
+
+Also, register the Android toolchains in the `WORKSPACE` file with:
+```
+register_toolchains(
+ "@build_bazel_rules_android//toolchains/android:android_default_toolchain",
+ "@build_bazel_rules_android//toolchains/android_sdk:android_sdk_tools",
+)
+```
+(Assuming that the Android rules repository in the `WORKSPACE` file is named `build_bazel_rules_android`.)
+
+## Overview
+
+This repository contains the Starlark implementation of Android rules in Bazel.
+
+The rules are being incrementally converted from their native implementations
+in the [Bazel source
+tree](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/android/).
+
+For the list of Android rules, see the Bazel [documentation](https://docs.bazel.build/versions/master/be/android.html).
+
+## Getting Started
+To use the new Bazel Android rules, add the following to your WORKSPACE file:
+
+ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+ http_archive(
+ name = "build_bazel_rules_android",
+ urls = ["https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"],
+ sha256 = "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
+ strip_prefix = "rules_android-0.1.1",
+ )
+
+Then, in your BUILD files, import and use the rules:
+
+ load("@build_bazel_rules_android//rules:rules.bzl", "android_library")
+ android_library(
+ ...
+ )
diff --git a/ROADMAP.md b/ROADMAP.md
new file mode 100644
index 0000000..57e46c3
--- /dev/null
+++ b/ROADMAP.md
@@ -0,0 +1,71 @@
+
+# Android Bazel Roadmap
+
+This document describes the major release milestones for the Android Bazel
+Rules. There are three major pillars that we are focused on when developing the
+Android rules - **Performance**, **Features**, and **Developer Experience** -
+and for each milestone we list the main items for each pillar. Progress on each
+item is tracked via an issue.
+
+If you have feedback on this roadmap (including feature and reprioritization
+requests) please open an issue or comment on the existing one.
+
+## Rules Alpha (est. mid 2019)
+
+The primary goal of the Rules Alpha release is to start collecting feedback from
+projects and developers that are interested in being early adopters of the
+rules. Our intention is for Rules Alpha to be a 1:1 identical drop-in
+replacement for the native Android rules, although undoubtedly there will be
+missing features and we cannot always guarantee 100% backwards compatibility.
+
+### Performance
+
+* Use AAPT2 for resource processing
+* Use D8 for Dexing
+
+### Features
+
+* Support android_instrumentation_test on macOS
+* Support building and testing on Google Cloud Platform Remote Build Execution
+* Support new Android App Bundle format
+* Accept APKs directly into android_instrumentation_test
+* Simplified package and dependency management
+* Improve Kotlin interoperability
+* Integration with Bazel's platforms and toolchains support
+* Modern and correct NDK support
+
+### Developer Experience
+
+* Documentation for Android with Bazel compatibility across Windows, macOS,
+ Linux
+* Documentation for Android with Bazel compatibility across Android Studio
+ versions
+* Stable and reliable CI
+* NDK documentation and samples
+
+## Rules Beta (est. late 2019)
+
+The goal for the Rules Beta release is to provide a stable, (mostly) feature
+complete version of the rules for all developers and projects. We intend the
+Rules Beta release to be the first version of the rules to be broadly adopted,
+and will comply with Bazel's backwards compatibility guarantees.
+
+### Performance
+
+* Improve resource processing speed and incrementality
+* Decouple Java compilation from R.class generation
+* Launch Bazel mobile-install v2
+
+### Features
+
+* New android_application rule for app packaging / sourceless binary /
+ android_application
+* Improved support for AAR creation
+* Support Databinding 3.4.0 (v2)
+* Support `bazel coverage` for all test rules
+* Integration with Android Lint
+
+### Developer Experience
+
+* Document best practices
+* Best in class tutorials and migration guides
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..9c8339a
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,3 @@
+workspace(name = "build_bazel_rules_android")
+
+register_toolchains("//android/toolchains/emulator:all")
diff --git a/rules/BUILD b/rules/BUILD
new file mode 100644
index 0000000..b233605
--- /dev/null
+++ b/rules/BUILD
@@ -0,0 +1,18 @@
+exports_files([
+ "data_binding_annotation_template.txt",
+ "res_v3_dummy_AndroidManifest.xml",
+ "res_v3_dummy_R.txt",
+ "robolectric_properties_template.txt",
+])
+
+alias(
+ name = "ResourceProcessorBusyBox",
+ actual = "@bazel_tools//tools/android:busybox",
+ visibility = ["//visibility:public"],
+)
+
+alias(
+ name = "current_java_runtime",
+ actual = "@bazel_tools//tools/jdk:current_java_runtime",
+ visibility = ["//visibility:public"],
+)
diff --git a/rules/aar_import/BUILD b/rules/aar_import/BUILD
new file mode 100644
index 0000000..50d41fe
--- /dev/null
+++ b/rules/aar_import/BUILD
@@ -0,0 +1,21 @@
+# The aar_import rule.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+licenses(["notice"])
+
+exports_files(["rule.bzl"])
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+)
+
+bzl_library(
+ name = "bzl",
+ srcs = glob(["*.bzl"]),
+ deps = [
+ "@rules_android//rules:common_bzl",
+ "@rules_android//rules/flags:bzl",
+ ],
+)
diff --git a/rules/aar_import/attrs.bzl b/rules/aar_import/attrs.bzl
new file mode 100644
index 0000000..5ac9c7a
--- /dev/null
+++ b/rules/aar_import/attrs.bzl
@@ -0,0 +1,64 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Attributes."""
+
+load(
+ "@rules_android//rules:attrs.bzl",
+ _attrs = "attrs",
+)
+
+ATTRS = _attrs.add(
+ dict(
+ aar = attr.label(
+ allow_single_file = [".aar"],
+ mandatory = True,
+ ),
+ data = attr.label_list(allow_files = True),
+ deps = attr.label_list(
+ allow_files = False,
+ providers = [JavaInfo],
+ ),
+ exports = attr.label_list(
+ allow_files = False,
+ allow_rules = ["aar_import", "java_import"],
+ ),
+ has_lint_jar = attr.bool(
+ default = False,
+ doc = "Whether the aar contains a lint.jar. This is required to " +
+ "know at analysis time if a lint jar is included in the aar.",
+ ),
+ package = attr.string(
+ doc = "Package to use while processing the aar at analysis time. " +
+ "This needs to be the same value as the manifest's package.",
+ ),
+ srcjar = attr.label(
+ allow_single_file = [".srcjar"],
+ doc =
+ "A srcjar file that contains the source code for the JVM " +
+ "artifacts stored within the AAR.",
+ ),
+ _flags = attr.label(
+ default = "@rules_android//rules/flags",
+ ),
+ _java_toolchain = attr.label(
+ default = Label("//tools/jdk:toolchain_android_only"),
+ ),
+ _host_javabase = attr.label(
+ cfg = "host",
+ default = Label("//tools/jdk:current_java_runtime"),
+ ),
+ ),
+ _attrs.DATA_CONTEXT,
+)
diff --git a/rules/aar_import/impl.bzl b/rules/aar_import/impl.bzl
new file mode 100644
index 0000000..96baa2b
--- /dev/null
+++ b/rules/aar_import/impl.bzl
@@ -0,0 +1,547 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation."""
+
+load(
+ "@rules_android//rules:acls.bzl",
+ _acls = "acls",
+)
+load(
+ "@rules_android//rules:common.bzl",
+ _common = "common",
+)
+load("@rules_android//rules:intellij.bzl", "intellij")
+load(
+ "@rules_android//rules:java.bzl",
+ _java = "java",
+)
+load("@rules_android//rules:providers.bzl", "AndroidLintRulesInfo")
+load(
+ "@rules_android//rules:resources.bzl",
+ _resources = "resources",
+)
+load(
+ "@rules_android//rules:utils.bzl",
+ _get_android_toolchain = "get_android_toolchain",
+ _utils = "utils",
+)
+
+RULE_PREFIX = "_aar"
+ANDROID_MANIFEST = "AndroidManifest.xml"
+LINT_JAR = "lint.jar"
+_UNEXPECTED_LINT_JAR_ERROR = (
+ "In target %s, has_lint_jar attribute is required when the aar contains " +
+ "a lint.jar file."
+)
+
+def _create_aar_artifact(ctx, name):
+ return ctx.actions.declare_file("%s/%s/%s" % (RULE_PREFIX, ctx.label.name, name))
+
+def _create_aar_tree_artifact(ctx, name):
+ return ctx.actions.declare_directory("%s/unzipped/%s/%s" % (RULE_PREFIX, name, ctx.label.name))
+
+# Create an action to extract a file (specified by the parameter filename) from an AAR file.
+def _extract_single_file(
+ ctx,
+ out_file,
+ aar,
+ filename,
+ unzip_tool):
+ args = ctx.actions.args()
+ args.add(aar)
+ args.add(filename)
+ args.add("-d", out_file.dirname)
+
+ ctx.actions.run(
+ executable = unzip_tool,
+ arguments = [args],
+ inputs = [aar],
+ outputs = [out_file],
+ mnemonic = "AarFileExtractor",
+ progress_message = "Extracting %s from %s" % (filename, aar.basename),
+ )
+
+def _extract_resources(
+ ctx,
+ out_resources_dir,
+ out_assets_dir,
+ aar,
+ aar_resources_extractor_tool):
+ args = ctx.actions.args()
+ args.add("--input_aar", aar)
+ args.add("--output_res_dir", out_resources_dir.path)
+ args.add("--output_assets_dir", out_assets_dir.path)
+ ctx.actions.run(
+ executable = aar_resources_extractor_tool,
+ arguments = [args],
+ inputs = [aar],
+ outputs = [out_resources_dir, out_assets_dir],
+ mnemonic = "AarResourcesExtractor",
+ progress_message = "Extracting resources and assets from %s" % aar.basename,
+ )
+
+def _extract_native_libs(
+ ctx,
+ output_zip,
+ aar,
+ android_cpu,
+ aar_native_libs_zip_creator_tool):
+ args = ctx.actions.args()
+ args.add("--input_aar", aar)
+ args.add("--cpu", android_cpu)
+ args.add("--output_zip", output_zip)
+ ctx.actions.run(
+ executable = aar_native_libs_zip_creator_tool,
+ arguments = [args],
+ inputs = [aar],
+ outputs = [output_zip],
+ mnemonic = "AarNativeLibsFilter",
+ progress_message = "Filtering AAR native libs by architecture",
+ )
+
+def _process_resources(
+ ctx,
+ aar,
+ manifest,
+ deps,
+ aar_resources_extractor_tool,
+ unzip_tool):
+ # Extract resources and assets, if they exist.
+ resources = _create_aar_tree_artifact(ctx, "resources")
+ assets = _create_aar_tree_artifact(ctx, "assets")
+ _extract_resources(
+ ctx,
+ resources,
+ assets,
+ aar,
+ aar_resources_extractor_tool,
+ )
+
+ resources_ctx = _resources.process_starlark(
+ ctx,
+ manifest = manifest,
+ assets = [assets],
+ assets_dir = assets.path,
+ resource_files = [resources],
+ stamp_manifest = False,
+ deps = ctx.attr.deps,
+ exports = ctx.attr.exports,
+ exports_manifest = getattr(ctx.attr, "exports_manifest", True),
+
+ # Tool and Processing related inputs
+ aapt = _get_android_toolchain(ctx).aapt2.files_to_run,
+ android_jar = ctx.attr._android_sdk[AndroidSdkInfo].android_jar,
+ android_kit = _get_android_toolchain(ctx).android_kit.files_to_run,
+ busybox = _get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+ java_toolchain = _common.get_java_toolchain(ctx),
+ host_javabase = _common.get_host_javabase(ctx),
+ instrument_xslt = _utils.only(_get_android_toolchain(ctx).add_g3itr_xslt.files.to_list()),
+ xsltproc = _get_android_toolchain(ctx).xsltproc_tool.files_to_run,
+ )
+
+ # TODO: replace android_data
+ # data_ctx = android_data.make_context(ctx.actions, ctx.attr)
+ # resource_apk = android_data.process_aar_import_data(
+ # data_ctx,
+ # resources,
+ # assets,
+ # manifest,
+ # deps = deps,
+ # )
+ # resources_ctx["validation_results"].append(
+ # _utils.only(resource_apk[AndroidResourcesInfo].direct_android_resources.to_list()).java_class_jar,
+ # )
+ # resources_ctx["providers"].append(resource_apk[AndroidResourcesInfo])
+ # resources_ctx["providers"].append(resource_apk[AndroidAssetsInfo])
+
+ if not _acls.in_aar_propagate_resources(str(ctx.label)):
+ resources_ctx["providers"] = []
+
+ return struct(**resources_ctx)
+
+def _extract_jars(
+ ctx,
+ out_jars_tree_artifact,
+ out_jars_params_file,
+ aar,
+ aar_embedded_jars_extractor_tool):
+ args = ctx.actions.args()
+ args.add("--input_aar", aar)
+ args.add("--output_dir", out_jars_tree_artifact.path)
+ args.add("--output_singlejar_param_file", out_jars_params_file)
+ ctx.actions.run(
+ executable = aar_embedded_jars_extractor_tool,
+ arguments = [args],
+ inputs = [aar],
+ outputs = [out_jars_tree_artifact, out_jars_params_file],
+ mnemonic = "AarEmbeddedJarsExtractor",
+ progress_message = "Extracting classes.jar and libs/*.jar from %s" % aar.basename,
+ )
+
+def _merge_jars(
+ ctx,
+ out_jar,
+ jars_tree_artifact,
+ jars_param_file,
+ single_jar_tool):
+ args = ctx.actions.args()
+ args.add("--output", out_jar)
+ args.add("--dont_change_compression")
+ args.add("--normalize")
+ args.add("@" + jars_param_file.path)
+ ctx.actions.run(
+ executable = single_jar_tool,
+ arguments = [args],
+ inputs = [jars_tree_artifact, jars_param_file],
+ outputs = [out_jar],
+ mnemonic = "AarJarsMerger",
+ progress_message = "Merging AAR embedded jars",
+ )
+
+def _extract_and_merge_jars(
+ ctx,
+ out_jar,
+ aar,
+ aar_embedded_jars_extractor_tool,
+ single_jar_tool):
+ """Extracts all the Jars within the AAR and produces a single jar.
+
+ An AAR may have multiple Jar files embedded within it. This method
+ extracts and merges all Jars.
+ """
+ jars_tree_artifact = _create_aar_tree_artifact(ctx, "jars")
+ jars_params_file = _create_aar_artifact(ctx, "jar_merging_params")
+ _extract_jars(
+ ctx,
+ jars_tree_artifact,
+ jars_params_file,
+ aar,
+ aar_embedded_jars_extractor_tool,
+ )
+ _merge_jars(
+ ctx,
+ out_jar,
+ jars_tree_artifact,
+ jars_params_file,
+ single_jar_tool,
+ )
+
+def _create_import_deps_check(
+ ctx,
+ jars_to_check,
+ declared_deps,
+ transitive_deps,
+ bootclasspath,
+ jdeps_output,
+ import_deps_checker_tool,
+ host_javabase):
+ args = ctx.actions.args()
+ args.add_all(jars_to_check, before_each = "--input")
+ args.add_all(declared_deps, before_each = "--directdep")
+ args.add_all(transitive_deps, before_each = "--classpath_entry")
+ args.add_all(bootclasspath, before_each = "--bootclasspath_entry")
+ args.add("--checking_mode=error")
+ args.add("--jdeps_output", jdeps_output)
+ args.add("--rule_label", ctx.label)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = import_deps_checker_tool,
+ arguments = [args],
+ inputs = depset(
+ jars_to_check,
+ transitive = [
+ declared_deps,
+ transitive_deps,
+ bootclasspath,
+ ],
+ ),
+ outputs = [jdeps_output],
+ mnemonic = "ImportDepsChecker",
+ progress_message = "Checking the completeness of the deps for %s" % jars_to_check,
+ )
+
+def _process_jars(
+ ctx,
+ out_jar,
+ aar,
+ source_jar,
+ r_java,
+ deps,
+ exports,
+ enable_desugar_java8,
+ enable_imports_deps_check,
+ bootclasspath,
+ desugar_java8_extra_bootclasspath,
+ aar_embedded_jars_extractor_tool,
+ import_deps_checker_tool,
+ single_jar_tool,
+ java_toolchain,
+ host_javabase):
+ providers = []
+ validation_results = []
+ r_java_info = [r_java] if r_java else []
+
+ # An aar may have multple Jar files, extract and merge into a single jar.
+ _extract_and_merge_jars(
+ ctx,
+ out_jar,
+ aar,
+ aar_embedded_jars_extractor_tool,
+ single_jar_tool,
+ )
+
+ java_infos = deps + exports
+
+ if enable_desugar_java8:
+ bootclasspath = depset(transitive = [
+ desugar_java8_extra_bootclasspath,
+ bootclasspath,
+ ])
+
+ merged_java_info = java_common.merge(java_infos + r_java_info)
+ jdeps_artifact = _create_aar_artifact(ctx, "jdeps.proto")
+ _create_import_deps_check(
+ ctx,
+ [out_jar],
+ merged_java_info.compile_jars,
+ merged_java_info.transitive_compile_time_jars,
+ bootclasspath,
+ jdeps_artifact,
+ import_deps_checker_tool,
+ host_javabase,
+ )
+ if enable_imports_deps_check:
+ validation_results.append(jdeps_artifact)
+
+ java_info = JavaInfo(
+ out_jar,
+ compile_jar = java_common.stamp_jar(
+ actions = ctx.actions,
+ jar = out_jar,
+ target_label = ctx.label,
+ java_toolchain = java_toolchain,
+ ),
+ source_jar = source_jar,
+ neverlink = False,
+ deps = r_java_info + java_infos, # TODO(djwhang): Exports are not deps.
+ exports =
+ (r_java_info if _acls.in_aar_import_exports_r_java(str(ctx.label)) else []) +
+ java_infos, # TODO(djwhang): Deps are not exports.
+ # TODO(djwhang): AarImportTest is not expecting jdeps, enable or remove it completely
+ # jdeps = jdeps_artifact,
+ )
+ providers.append(java_info)
+
+ return struct(
+ java_info = java_info,
+ providers = providers,
+ validation_results = validation_results,
+ )
+
+def _validate_rule(
+ ctx,
+ aar,
+ manifest,
+ checks):
+ package = _java.resolve_package_from_label(ctx.label, ctx.attr.package)
+ validation_output = ctx.actions.declare_file("%s_validation_output" % ctx.label.name)
+
+ args = ctx.actions.args()
+ args.add("-aar", aar)
+ inputs = [aar]
+ args.add("-label", str(ctx.label))
+ if _acls.in_aar_import_pkg_check(str(ctx.label)):
+ args.add("-pkg", package)
+ args.add("-manifest", manifest)
+ inputs.append(manifest)
+ if ctx.attr.has_lint_jar:
+ args.add("-has_lint_jar")
+ args.add("-output", validation_output)
+
+ ctx.actions.run(
+ executable = checks,
+ arguments = [args],
+ inputs = inputs,
+ outputs = [validation_output],
+ mnemonic = "ValidateAAR",
+ progress_message = "Validating aar_import %s" % str(ctx.label),
+ )
+ return validation_output
+
+def _process_lint_rules(
+ ctx,
+ aar,
+ unzip_tool):
+ providers = []
+
+ if ctx.attr.has_lint_jar:
+ lint_jar = _create_aar_artifact(ctx, LINT_JAR)
+ _extract_single_file(
+ ctx,
+ lint_jar,
+ aar,
+ LINT_JAR,
+ unzip_tool,
+ )
+ providers.append(AndroidLintRulesInfo(
+ lint_jar = lint_jar,
+ ))
+
+ providers.extend(_utils.collect_providers(
+ AndroidLintRulesInfo,
+ ctx.attr.exports,
+ ))
+ return providers
+
+def impl(ctx):
+ """The rule implementation.
+
+ Args:
+ ctx: The context.
+
+ Returns:
+ A list of providers.
+ """
+ providers = []
+ validation_outputs = []
+
+ aar = _utils.only(ctx.files.aar)
+ unzip_tool = _get_android_toolchain(ctx).unzip_tool.files_to_run
+
+ # Extract the AndroidManifest.xml from the AAR.
+ android_manifest = _create_aar_artifact(ctx, ANDROID_MANIFEST)
+ _extract_single_file(
+ ctx,
+ android_manifest,
+ aar,
+ ANDROID_MANIFEST,
+ unzip_tool,
+ )
+
+ resources_ctx = _process_resources(
+ ctx,
+ aar = aar,
+ manifest = android_manifest,
+ deps = ctx.attr.deps,
+ aar_resources_extractor_tool =
+ _get_android_toolchain(ctx).aar_resources_extractor.files_to_run,
+ unzip_tool = unzip_tool,
+ )
+ providers.extend(resources_ctx.providers)
+
+ merged_jar = _create_aar_artifact(ctx, "classes_and_libs_merged.jar")
+ jvm_ctx = _process_jars(
+ ctx,
+ out_jar = merged_jar,
+ aar = aar,
+ source_jar = ctx.file.srcjar,
+ deps = _utils.collect_providers(JavaInfo, ctx.attr.deps),
+ r_java = resources_ctx.r_java,
+ exports = _utils.collect_providers(JavaInfo, ctx.attr.exports),
+ enable_desugar_java8 = ctx.fragments.android.desugar_java8,
+ enable_imports_deps_check =
+ _acls.in_aar_import_deps_checker(str(ctx.label)),
+ aar_embedded_jars_extractor_tool =
+ _get_android_toolchain(ctx).aar_embedded_jars_extractor.files_to_run,
+ bootclasspath =
+ ctx.attr._java_toolchain[java_common.JavaToolchainInfo].bootclasspath,
+ desugar_java8_extra_bootclasspath =
+ _get_android_toolchain(ctx).desugar_java8_extra_bootclasspath.files,
+ import_deps_checker_tool =
+ _get_android_toolchain(ctx).import_deps_checker.files_to_run,
+ single_jar_tool =
+ ctx.attr._java_toolchain[java_common.JavaToolchainInfo].single_jar,
+ java_toolchain =
+ ctx.attr._java_toolchain[java_common.JavaToolchainInfo],
+ host_javabase = ctx.attr._host_javabase,
+ )
+ providers.extend(jvm_ctx.providers)
+ validation_outputs.extend(jvm_ctx.validation_results)
+
+ native_libs = _create_aar_artifact(ctx, "native_libs.zip")
+ _extract_native_libs(
+ ctx,
+ native_libs,
+ aar = aar,
+ android_cpu = ctx.fragments.android.android_cpu,
+ aar_native_libs_zip_creator_tool =
+ _get_android_toolchain(ctx).aar_native_libs_zip_creator.files_to_run,
+ )
+ native_libs_infos = _utils.collect_providers(
+ AndroidNativeLibsInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ )
+ providers.append(
+ AndroidNativeLibsInfo(
+ depset(
+ [native_libs],
+ transitive = [info.native_libs for info in native_libs_infos],
+ ),
+ ),
+ )
+
+ lint_providers = _process_lint_rules(
+ ctx,
+ aar = aar,
+ unzip_tool = unzip_tool,
+ )
+ providers.extend(lint_providers)
+
+ validation_outputs.append(_validate_rule(
+ ctx,
+ aar = aar,
+ manifest = android_manifest,
+ checks = _get_android_toolchain(ctx).aar_import_checks.files_to_run,
+ ))
+
+ providers.append(
+ intellij.make_android_ide_info(
+ ctx,
+ java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.package),
+ manifest = resources_ctx.merged_manifest,
+ defines_resources = resources_ctx.defines_resources,
+ merged_manifest = resources_ctx.merged_manifest,
+ resources_apk = resources_ctx.resources_apk,
+ r_jar = _utils.only(resources_ctx.r_java.outputs.jars) if resources_ctx.r_java else None,
+ java_info = jvm_ctx.java_info,
+ signed_apk = None, # signed_apk, always empty for aar_import
+ apks_under_test = [], # apks_under_test, always empty for aar_import
+ native_libs = dict(), # nativelibs, always empty for aar_import
+ idlclass = _get_android_toolchain(ctx).idlclass.files_to_run,
+ host_javabase = _common.get_host_javabase(ctx),
+ ),
+ )
+
+ providers.append(OutputGroupInfo(_validation = depset(validation_outputs)))
+
+ # There isn't really any use case for building an aar_import target on its own, so the files to
+ # build could be empty. The R class JAR and merged JARs are added here as a sanity check for
+ # Bazel developers so that `bazel build java/com/my_aar_import` will fail if the resource
+ # processing or JAR merging steps fail.
+ files_to_build = []
+ files_to_build.extend(resources_ctx.validation_results) # TODO(djwhang): This should be validation.
+ files_to_build.append(merged_jar)
+
+ providers.append(
+ DefaultInfo(
+ files = depset(files_to_build),
+ runfiles = ctx.runfiles(),
+ ),
+ )
+
+ return providers
diff --git a/rules/aar_import/rule.bzl b/rules/aar_import/rule.bzl
new file mode 100644
index 0000000..fa78a88
--- /dev/null
+++ b/rules/aar_import/rule.bzl
@@ -0,0 +1,26 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""aar_import rule."""
+
+load(":attrs.bzl", _ATTRS = "ATTRS")
+load(":impl.bzl", _impl = "impl")
+
+aar_import = rule(
+ attrs = _ATTRS,
+ fragments = ["android"],
+ implementation = _impl,
+ provides = [AndroidNativeLibsInfo, JavaInfo],
+ toolchains = ["@rules_android//toolchains/android:toolchain_type"],
+)
diff --git a/rules/acls.bzl b/rules/acls.bzl
new file mode 100644
index 0000000..ade99db
--- /dev/null
+++ b/rules/acls.bzl
@@ -0,0 +1,318 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Access Control Lists.
+
+To create a new list:
+ 1. Create new .bzl file in this directory with a list of targets.
+ 2. Create matching method in this file.
+ 3. Add matching method to struct.
+
+To check an ACL:
+ 1. Import the `acls` struct.
+ 2. Check `acls.list_name(fqn)` using the //fully/qualified:target
+
+To update a list:
+ 1. Directly add/remove/edit targets in the appropriate .bzl file
+"""
+
+load("@rules_android//rules/acls:aar_import_deps_checker.bzl", "AAR_IMPORT_DEPS_CHECKER_FALLBACK", "AAR_IMPORT_DEPS_CHECKER_ROLLOUT")
+load("@rules_android//rules/acls:aar_import_explicit_exports_manifest.bzl", "AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST")
+load("@rules_android//rules/acls:aar_import_exports_r_java.bzl", "AAR_IMPORT_EXPORTS_R_JAVA")
+load("@rules_android//rules/acls:aar_import_package_check.bzl", "AAR_IMPORT_PKG_CHECK_FALLBACK", "AAR_IMPORT_PKG_CHECK_ROLLOUT")
+load("@rules_android//rules/acls:aar_propagate_resources.bzl", "AAR_PROPAGATE_RESOURCES_FALLBACK", "AAR_PROPAGATE_RESOURCES_ROLLOUT")
+load("@rules_android//rules/acls:ait_install_snapshots.bzl", "APP_INSTALLATION_SNAPSHOT", "APP_INSTALLATION_SNAPSHOT_FALLBACK")
+load("@rules_android//rules/acls:ait_virtual_device.bzl", "AIT_VIRTUAL_DEVICE_FALLBACK", "AIT_VIRTUAL_DEVICE_ROLLOUT")
+load("@rules_android//rules/acls:allow_resource_conflicts.bzl", "ALLOW_RESOURCE_CONFLICTS")
+load("@rules_android//rules/acls:android_archive_dogfood.bzl", "ANDROID_ARCHIVE_DOGFOOD")
+load("@rules_android//rules/acls:android_test_lockdown.bzl", "ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS", "ANDROID_TEST_LOCKDOWN_TARGETS")
+load("@rules_android//rules/acls:android_device_plugin_rollout.bzl", "ANDROID_DEVICE_PLUGIN_FALLBACK", "ANDROID_DEVICE_PLUGIN_ROLLOUT")
+load("@rules_android//rules/acls:android_instrumentation_binary_starlark_resources.bzl", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT")
+load("@rules_android//rules/acls:android_feature_splits_dogfood.bzl", "ANDROID_FEATURE_SPLITS_DOGFOOD")
+load("@rules_android//rules/acls:android_library_implicit_exports.bzl", "ANDROID_LIBRARY_IMPLICIT_EXPORTS", "ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS")
+load("@rules_android//rules/acls:android_library_resources_without_srcs.bzl", "ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS", "ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS")
+load("@rules_android//rules/acls:android_lint_rollout.bzl", "ANDROID_LINT_ROLLOUT")
+load("@rules_android//rules/acls:android_build_stamping_rollout.bzl", "ANDROID_BUILD_STAMPING_FALLBACK", "ANDROID_BUILD_STAMPING_ROLLOUT")
+load("@rules_android//rules/acls:b122039567.bzl", "B122039567")
+load("@rules_android//rules/acls:b123854163.bzl", "B123854163")
+load("@rules_android//rules/acls:dex2oat_opts.bzl", "CAN_USE_DEX2OAT_OPTIONS")
+load("@rules_android//rules/acls:fix_application_id.bzl", "FIX_APPLICATION_ID_FALLBACK", "FIX_APPLICATION_ID_ROLLOUT")
+load("@rules_android//rules/acls:fix_export_exporting_rollout.bzl", "FIX_EXPORT_EXPORTING_FALLBACK", "FIX_EXPORT_EXPORTING_ROLLOUT")
+load("@rules_android//rules/acls:fix_resource_transitivity_rollout.bzl", "FIX_RESOURCE_TRANSITIVITY_FALLBACK", "FIX_RESOURCE_TRANSITIVITY_ROLLOUT")
+load("@rules_android//rules/acls:host_dex2oat_rollout.bzl", "AIT_USE_HOST_DEX2OAT_ROLLOUT", "AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK")
+load("@rules_android//rules/acls:install_apps_in_data.bzl", "INSTALL_APPS_IN_DATA")
+load("@rules_android//rules/acls:local_test_multi_proto.bzl", "LOCAL_TEST_MULTI_PROTO_PKG")
+load("@rules_android//rules/acls:local_test_rollout.bzl", "LOCAL_TEST_FALLBACK", "LOCAL_TEST_ROLLOUT")
+load("@rules_android//rules/acls:local_test_starlark_resources.bzl", "LOCAL_TEST_STARLARK_RESOURCES_FALLBACK", "LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT")
+load("@rules_android//rules/acls:nitrogen_test_runner_rollout.bzl", "NITROGEN_AT_TEST_RUNNER_ROLLOUT", "NITROGEN_TEST_RUNNER_FALLBACK", "NITROGEN_TEST_RUNNER_ROLLOUT")
+load("@rules_android//rules/acls:android_test_platform_rollout.bzl", "ANDROID_TEST_PLATFORM_FALLBACK", "ANDROID_TEST_PLATFORM_ROLLOUT")
+load("@rules_android//rules/acls:sourceless_binary_rollout.bzl", "SOURCELESS_BINARY_FALLBACK", "SOURCELESS_BINARY_ROLLOUT")
+load("@rules_android//rules/acls:test_to_instrument_test_rollout.bzl", "TEST_TO_INSTRUMENT_TEST_FALLBACK", "TEST_TO_INSTRUMENT_TEST_ROLLOUT")
+load(
+ "@rules_android//rules/acls:partial_jetification_targets.bzl",
+ "PARTIAL_JETIFICATION_TARGETS_FALLBACK",
+ "PARTIAL_JETIFICATION_TARGETS_ROLLOUT",
+)
+load("@rules_android//rules/acls:kt_android_library_rollout.bzl", "KT_ANDROID_LIBRARY_FALLBACK", "KT_ANDROID_LIBRARY_ROLLOUT")
+
+def _in_aar_import_deps_checker(fqn):
+ return not _matches(fqn, AAR_IMPORT_DEPS_CHECKER_FALLBACK_DICT) and _matches(fqn, AAR_IMPORT_DEPS_CHECKER_ROLLOUT_DICT)
+
+def _in_aar_import_explicit_exports_manifest(fqn):
+ return _matches(fqn, AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST_DICT)
+
+def _in_aar_import_exports_r_java(fqn):
+ return _matches(fqn, AAR_IMPORT_EXPORTS_R_JAVA_DICT)
+
+def _in_aar_import_pkg_check(fqn):
+ return not _matches(fqn, AAR_IMPORT_PKG_CHECK_FALLBACK_DICT) and _matches(fqn, AAR_IMPORT_PKG_CHECK_ROLLOUT_DICT)
+
+def _in_aar_propagate_resources(fqn):
+ return not _matches(fqn, AAR_PROPAGATE_RESOURCES_FALLBACK_DICT) and _matches(fqn, AAR_PROPAGATE_RESOURCES_ROLLOUT_DICT)
+
+def _in_ait_virtual_device(fqn):
+ return not _matches(fqn, AIT_VIRTUAL_DEVICE_FALLBACK_DICT) and _matches(fqn, AIT_VIRTUAL_DEVICE_ROLLOUT_DICT)
+
+def _in_android_archive_dogfood(fqn):
+ return _matches(fqn, ANDROID_ARCHIVE_DOGFOOD_DICT)
+
+def _in_android_device_plugin_rollout(fqn):
+ return not _matches(fqn, ANDROID_DEVICE_PLUGIN_FALLBACK_DICT) and _matches(fqn, ANDROID_DEVICE_PLUGIN_ROLLOUT_DICT)
+
+def _in_android_instrumentation_binary_starlark_resources(fqn):
+ return not _matches(fqn, ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK_DICT) and _matches(fqn, ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT_DICT)
+
+def _in_android_feature_splits_dogfood(fqn):
+ return _matches(fqn, ANDROID_FEATURE_SPLITS_DOGFOOD_DICT)
+
+def _in_android_lint_rollout(fqn):
+ return _matches(fqn, ANDROID_LINT_ROLLOUT_DICT)
+
+def _in_android_build_stamping_rollout(fqn):
+ return not _matches(fqn, ANDROID_BUILD_STAMPING_FALLBACK_DICT) and _matches(fqn, ANDROID_BUILD_STAMPING_ROLLOUT_DICT)
+
+def _in_android_test_lockdown_allowlist(fqn, generator):
+ return _matches(fqn, ANDROID_TEST_LOCKDOWN_TARGETS_DICT) or generator in ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS_DICT
+
+def _in_b122039567(fqn):
+ return _matches(fqn, B122039567_DICT)
+
+def _in_b123854163(fqn):
+ return _matches(fqn, B123854163_DICT)
+
+def _in_android_library_implicit_exports(fqn):
+ return _matches(fqn, ANDROID_LIBRARY_IMPLICIT_EXPORTS_DICT)
+
+def _in_android_library_implicit_exports_generator_functions(gfn):
+ return gfn in ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS_DICT
+
+def _in_android_library_resources_without_srcs(fqn):
+ return _matches(fqn, ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_DICT)
+
+def _in_android_library_resources_without_srcs_generator_functions(gfn):
+ return gfn in ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS_DICT
+
+def _in_app_installation_snapshot(fqn):
+ return not _matches(fqn, APP_INSTALLATION_SNAPSHOT_FALLBACK_DICT) and _matches(fqn, APP_INSTALLATION_SNAPSHOT_DICT)
+
+def _in_dex2oat_opts(fqn):
+ return _matches(fqn, CAN_USE_DEX2OAT_OPTIONS_DICT)
+
+def _in_fix_application_id(fqn):
+ return not _matches(fqn, FIX_APPLICATION_ID_FALLBACK_DICT) and _matches(fqn, FIX_APPLICATION_ID_ROLLOUT_DICT)
+
+def _in_fix_export_exporting_rollout(fqn):
+ return not _matches(fqn, FIX_EXPORT_EXPORTING_FALLBACK_DICT) and _matches(fqn, FIX_EXPORT_EXPORTING_ROLLOUT_DICT)
+
+def _in_fix_resource_transivity_rollout(fqn):
+ return not _matches(fqn, FIX_RESOURCE_TRANSIVITY_FALLBACK_DICT) and _matches(fqn, FIX_RESOURCE_TRANSIVITY_ROLLOUT_DICT)
+
+def _in_host_dex2oat_rollout(fqn):
+ return not _matches(fqn, AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK_DICT) and _matches(fqn, AIT_USE_HOST_DEX2OAT_ROLLOUT_DICT)
+
+def _in_install_apps_in_data(fqn):
+ return _matches(fqn, AIT_INSTALL_APPS_IN_DATA_DICT)
+
+def _in_local_test_multi_proto(fqn):
+ return _matches(fqn, LOCAL_TEST_MULTI_PROTO_PKG_DICT)
+
+def _in_local_test_rollout(fqn):
+ return not _matches(fqn, LOCAL_TEST_FALLBACK_DICT) and _matches(fqn, LOCAL_TEST_ROLLOUT_DICT)
+
+def _in_local_test_starlark_resources(fqn):
+ return not _matches(fqn, LOCAL_TEST_STARLARK_RESOURCES_FALLBACK_DICT) and _matches(fqn, LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT_DICT)
+
+def _in_nitrogen_test_runner_rollout(fqn):
+ return not _matches(fqn, NITROGEN_TEST_RUNNER_FALLBACK_DICT) and _matches(fqn, NITROGEN_TEST_RUNNER_ROLLOUT_DICT)
+
+def _in_nitrogen_at_test_runner_rollout(fqn):
+ return not _matches(fqn, NITROGEN_TEST_RUNNER_FALLBACK_DICT) and _matches(fqn, NITROGEN_AT_TEST_RUNNER_ROLLOUT_DICT)
+
+def _in_android_test_platform_rollout(fqn):
+ return not _matches(fqn, ANDROID_TEST_PLATFORM_FALLBACK_DICT) and _matches(fqn, ANDROID_TEST_PLATFORM_ROLLOUT_DICT)
+
+def _in_sourceless_binary_rollout(fqn):
+ return not _matches(fqn, SOURCELESS_BINARY_FALLBACK_DICT) and _matches(fqn, SOURCELESS_BINARY_ROLLOUT_DICT)
+
+def _in_test_to_instrument_test_rollout(fqn):
+ return not _matches(fqn, TEST_TO_INSTRUMENT_TEST_FALLBACK_DICT) and _matches(fqn, TEST_TO_INSTRUMENT_TEST_ROLLOUT_DICT)
+
+def _in_allow_resource_conflicts(fqn):
+ return _matches(fqn, ALLOW_RESOURCE_CONFLICTS_DICT)
+
+def _in_partial_jetification_targets(fqn):
+ return not _matches(fqn, PARTIAL_JETIFICATION_TARGETS_FALLBACK_DICT) and _matches(fqn, PARTIAL_JETIFICATION_TARGETS_ROLLOUT_DICT)
+
+def _in_kt_android_library_rollout(fqn):
+ return not _matches(fqn, KT_ANDROID_LIBRARY_FALLBACK_DICT) and _matches(fqn, KT_ANDROID_LIBRARY_ROLLOUT_DICT)
+
+def _make_dict(lst):
+ """Do not use this method outside of this file."""
+ return {t: True for t in lst}
+
+AAR_IMPORT_DEPS_CHECKER_FALLBACK_DICT = _make_dict(AAR_IMPORT_DEPS_CHECKER_FALLBACK)
+AAR_IMPORT_DEPS_CHECKER_ROLLOUT_DICT = _make_dict(AAR_IMPORT_DEPS_CHECKER_ROLLOUT)
+AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST_DICT = _make_dict(AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST)
+AAR_IMPORT_EXPORTS_R_JAVA_DICT = _make_dict(AAR_IMPORT_EXPORTS_R_JAVA)
+AAR_IMPORT_PKG_CHECK_FALLBACK_DICT = _make_dict(AAR_IMPORT_PKG_CHECK_FALLBACK)
+AAR_IMPORT_PKG_CHECK_ROLLOUT_DICT = _make_dict(AAR_IMPORT_PKG_CHECK_ROLLOUT)
+AAR_PROPAGATE_RESOURCES_FALLBACK_DICT = _make_dict(AAR_PROPAGATE_RESOURCES_FALLBACK)
+AAR_PROPAGATE_RESOURCES_ROLLOUT_DICT = _make_dict(AAR_PROPAGATE_RESOURCES_ROLLOUT)
+AIT_VIRTUAL_DEVICE_FALLBACK_DICT = _make_dict(AIT_VIRTUAL_DEVICE_FALLBACK)
+AIT_VIRTUAL_DEVICE_ROLLOUT_DICT = _make_dict(AIT_VIRTUAL_DEVICE_ROLLOUT)
+ANDROID_ARCHIVE_DOGFOOD_DICT = _make_dict(ANDROID_ARCHIVE_DOGFOOD)
+ANDROID_DEVICE_PLUGIN_ROLLOUT_DICT = _make_dict(ANDROID_DEVICE_PLUGIN_ROLLOUT)
+ANDROID_DEVICE_PLUGIN_FALLBACK_DICT = _make_dict(ANDROID_DEVICE_PLUGIN_FALLBACK)
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT_DICT = _make_dict(ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT)
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK_DICT = _make_dict(ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK)
+ANDROID_FEATURE_SPLITS_DOGFOOD_DICT = _make_dict(ANDROID_FEATURE_SPLITS_DOGFOOD)
+ANDROID_LIBRARY_IMPLICIT_EXPORTS_DICT = _make_dict(ANDROID_LIBRARY_IMPLICIT_EXPORTS)
+ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS_DICT = _make_dict(ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS)
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_DICT = _make_dict(ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS)
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS_DICT = _make_dict(ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS)
+ANDROID_LINT_ROLLOUT_DICT = _make_dict(ANDROID_LINT_ROLLOUT)
+ANDROID_BUILD_STAMPING_ROLLOUT_DICT = _make_dict(ANDROID_BUILD_STAMPING_ROLLOUT)
+ANDROID_BUILD_STAMPING_FALLBACK_DICT = _make_dict(ANDROID_BUILD_STAMPING_FALLBACK)
+ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS_DICT = _make_dict(ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS)
+ANDROID_TEST_LOCKDOWN_TARGETS_DICT = _make_dict(ANDROID_TEST_LOCKDOWN_TARGETS)
+APP_INSTALLATION_SNAPSHOT_DICT = _make_dict(APP_INSTALLATION_SNAPSHOT)
+APP_INSTALLATION_SNAPSHOT_FALLBACK_DICT = _make_dict(APP_INSTALLATION_SNAPSHOT_FALLBACK)
+B122039567_DICT = _make_dict(B122039567)
+B123854163_DICT = _make_dict(B123854163)
+CAN_USE_DEX2OAT_OPTIONS_DICT = _make_dict(CAN_USE_DEX2OAT_OPTIONS)
+FIX_APPLICATION_ID_FALLBACK_DICT = _make_dict(FIX_APPLICATION_ID_FALLBACK)
+FIX_APPLICATION_ID_ROLLOUT_DICT = _make_dict(FIX_APPLICATION_ID_ROLLOUT)
+FIX_RESOURCE_TRANSIVITY_FALLBACK_DICT = _make_dict(FIX_RESOURCE_TRANSITIVITY_FALLBACK)
+FIX_RESOURCE_TRANSIVITY_ROLLOUT_DICT = _make_dict(FIX_RESOURCE_TRANSITIVITY_ROLLOUT)
+FIX_EXPORT_EXPORTING_FALLBACK_DICT = _make_dict(FIX_EXPORT_EXPORTING_FALLBACK)
+FIX_EXPORT_EXPORTING_ROLLOUT_DICT = _make_dict(FIX_EXPORT_EXPORTING_ROLLOUT)
+AIT_USE_HOST_DEX2OAT_ROLLOUT_DICT = _make_dict(AIT_USE_HOST_DEX2OAT_ROLLOUT)
+AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK_DICT = _make_dict(AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK)
+AIT_INSTALL_APPS_IN_DATA_DICT = _make_dict(INSTALL_APPS_IN_DATA)
+LOCAL_TEST_MULTI_PROTO_PKG_DICT = _make_dict(LOCAL_TEST_MULTI_PROTO_PKG)
+LOCAL_TEST_FALLBACK_DICT = _make_dict(LOCAL_TEST_FALLBACK)
+LOCAL_TEST_ROLLOUT_DICT = _make_dict(LOCAL_TEST_ROLLOUT)
+LOCAL_TEST_STARLARK_RESOURCES_FALLBACK_DICT = _make_dict(LOCAL_TEST_STARLARK_RESOURCES_FALLBACK)
+LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT_DICT = _make_dict(LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT)
+NITROGEN_TEST_RUNNER_FALLBACK_DICT = _make_dict(NITROGEN_TEST_RUNNER_FALLBACK)
+NITROGEN_TEST_RUNNER_ROLLOUT_DICT = _make_dict(NITROGEN_TEST_RUNNER_ROLLOUT)
+NITROGEN_AT_TEST_RUNNER_ROLLOUT_DICT = _make_dict(NITROGEN_AT_TEST_RUNNER_ROLLOUT)
+ANDROID_TEST_PLATFORM_FALLBACK_DICT = _make_dict(ANDROID_TEST_PLATFORM_FALLBACK)
+ANDROID_TEST_PLATFORM_ROLLOUT_DICT = _make_dict(ANDROID_TEST_PLATFORM_ROLLOUT)
+SOURCELESS_BINARY_FALLBACK_DICT = _make_dict(SOURCELESS_BINARY_FALLBACK)
+SOURCELESS_BINARY_ROLLOUT_DICT = _make_dict(SOURCELESS_BINARY_ROLLOUT)
+TEST_TO_INSTRUMENT_TEST_FALLBACK_DICT = _make_dict(TEST_TO_INSTRUMENT_TEST_FALLBACK)
+TEST_TO_INSTRUMENT_TEST_ROLLOUT_DICT = _make_dict(TEST_TO_INSTRUMENT_TEST_ROLLOUT)
+ALLOW_RESOURCE_CONFLICTS_DICT = _make_dict(ALLOW_RESOURCE_CONFLICTS)
+PARTIAL_JETIFICATION_TARGETS_ROLLOUT_DICT = _make_dict(PARTIAL_JETIFICATION_TARGETS_ROLLOUT)
+PARTIAL_JETIFICATION_TARGETS_FALLBACK_DICT = _make_dict(PARTIAL_JETIFICATION_TARGETS_FALLBACK)
+KT_ANDROID_LIBRARY_ROLLOUT_DICT = _make_dict(KT_ANDROID_LIBRARY_ROLLOUT)
+KT_ANDROID_LIBRARY_FALLBACK_DICT = _make_dict(KT_ANDROID_LIBRARY_FALLBACK)
+
+def _matches(fqn, dct):
+ if not fqn.startswith("//"):
+ fail("Fully qualified target should start with '//', got: " + fqn)
+
+ if fqn in dct:
+ return True
+
+ pkg_and_target = fqn.split(":")
+ if len(pkg_and_target) != 2:
+ fail("Expected fully qualified target, got: " + fqn)
+ pkg = pkg_and_target[0]
+
+ if (pkg + ":__pkg__") in dct:
+ return True
+
+ pkg = pkg.lstrip("//")
+ pkg_parts = pkg.split("/")
+ ancestor_pkg = "//"
+
+ if (ancestor_pkg + ":__subpackages__") in dct:
+ return True
+
+ for pkg_part in pkg_parts:
+ ancestor_pkg = (
+ (ancestor_pkg + "/" + pkg_part) if ancestor_pkg != "//" else ("//" + pkg_part)
+ )
+ if (ancestor_pkg + ":__subpackages__") in dct:
+ return True
+
+ return False
+
+acls = struct(
+ in_aar_import_deps_checker = _in_aar_import_deps_checker,
+ in_aar_import_pkg_check = _in_aar_import_pkg_check,
+ in_aar_import_explicit_exports_manifest = _in_aar_import_explicit_exports_manifest,
+ in_aar_import_exports_r_java = _in_aar_import_exports_r_java,
+ in_aar_propagate_resources = _in_aar_propagate_resources,
+ in_ait_virtual_device = _in_ait_virtual_device,
+ in_b122039567 = _in_b122039567,
+ in_b123854163 = _in_b123854163,
+ in_android_archive_dogfood = _in_android_archive_dogfood,
+ in_android_device_plugin_rollout = _in_android_device_plugin_rollout,
+ in_android_instrumentation_binary_starlark_resources = _in_android_instrumentation_binary_starlark_resources,
+ in_android_feature_splits_dogfood = _in_android_feature_splits_dogfood,
+ in_android_library_implicit_exports = _in_android_library_implicit_exports,
+ in_android_library_implicit_exports_generator_functions = _in_android_library_implicit_exports_generator_functions,
+ in_android_library_resources_without_srcs = _in_android_library_resources_without_srcs,
+ in_android_library_resources_without_srcs_generator_functions = _in_android_library_resources_without_srcs_generator_functions,
+ in_android_lint_rollout = _in_android_lint_rollout,
+ in_android_build_stamping_rollout = _in_android_build_stamping_rollout,
+ in_android_test_lockdown_allowlist = _in_android_test_lockdown_allowlist,
+ in_app_installation_snapshot = _in_app_installation_snapshot,
+ in_dex2oat_opts = _in_dex2oat_opts,
+ in_fix_application_id = _in_fix_application_id,
+ in_fix_export_exporting_rollout = _in_fix_export_exporting_rollout,
+ in_fix_resource_transivity_rollout = _in_fix_resource_transivity_rollout,
+ in_host_dex2oat_rollout = _in_host_dex2oat_rollout,
+ in_install_apps_in_data = _in_install_apps_in_data,
+ in_local_test_multi_proto = _in_local_test_multi_proto,
+ in_local_test_rollout = _in_local_test_rollout,
+ in_local_test_starlark_resources = _in_local_test_starlark_resources,
+ in_nitrogen_test_runner_rollout = _in_nitrogen_test_runner_rollout,
+ in_nitrogen_at_test_runner_rollout = _in_nitrogen_at_test_runner_rollout,
+ in_android_test_platform_rollout = _in_android_test_platform_rollout,
+ in_sourceless_binary_rollout = _in_sourceless_binary_rollout,
+ in_test_to_instrument_test_rollout = _in_test_to_instrument_test_rollout,
+ in_allow_resource_conflicts = _in_allow_resource_conflicts,
+ in_partial_jetification_targets = _in_partial_jetification_targets,
+ in_kt_android_library_rollout = _in_kt_android_library_rollout,
+)
+
+# Visible for testing
+testing = struct(
+ matches = _matches,
+ make_dict = _make_dict,
+)
diff --git a/rules/acls/BUILD b/rules/acls/BUILD
new file mode 100644
index 0000000..3c45ae3
--- /dev/null
+++ b/rules/acls/BUILD
@@ -0,0 +1,6 @@
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+bzl_library(
+ name = "bzl",
+ srcs = glob(["*.bzl"]),
+)
diff --git a/rules/acls/aar_import_deps_checker.bzl b/rules/acls/aar_import_deps_checker.bzl
new file mode 100644
index 0000000..dabfd31
--- /dev/null
+++ b/rules/acls/aar_import_deps_checker.bzl
@@ -0,0 +1,27 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist to run ImportDepsChecker on aar_import.
+
+See b/148478031 for context.
+"""
+
+# keep sorted
+AAR_IMPORT_DEPS_CHECKER_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+# keep sorted
+AAR_IMPORT_DEPS_CHECKER_FALLBACK = [
+]
diff --git a/rules/acls/aar_import_explicit_exports_manifest.bzl b/rules/acls/aar_import_explicit_exports_manifest.bzl
new file mode 100644
index 0000000..fb3a0b9
--- /dev/null
+++ b/rules/acls/aar_import_explicit_exports_manifest.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for aar_import rule to explcitly set exports_manifest."""
+
+# keep sorted
+AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST = [
+]
diff --git a/rules/acls/aar_import_exports_r_java.bzl b/rules/acls/aar_import_exports_r_java.bzl
new file mode 100644
index 0000000..c0a07a4
--- /dev/null
+++ b/rules/acls/aar_import_exports_r_java.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for aar_import rule to export the R.java."""
+
+# keep sorted
+AAR_IMPORT_EXPORTS_R_JAVA = [
+]
diff --git a/rules/acls/aar_import_package_check.bzl b/rules/acls/aar_import_package_check.bzl
new file mode 100644
index 0000000..54b2b51
--- /dev/null
+++ b/rules/acls/aar_import_package_check.bzl
@@ -0,0 +1,21 @@
+# Copyright 2021 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for checking the package value with the manifest."""
+AAR_IMPORT_PKG_CHECK_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+AAR_IMPORT_PKG_CHECK_FALLBACK = [
+]
diff --git a/rules/acls/aar_propagate_resources.bzl b/rules/acls/aar_propagate_resources.bzl
new file mode 100644
index 0000000..48ab3ba
--- /dev/null
+++ b/rules/acls/aar_propagate_resources.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for propagating resources and assets from aar_import (b/138322659)."""
+
+# keep sorted
+AAR_PROPAGATE_RESOURCES_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+# keep sorted
+AAR_PROPAGATE_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/ait_install_snapshots.bzl b/rules/acls/ait_install_snapshots.bzl
new file mode 100644
index 0000000..ff11e64
--- /dev/null
+++ b/rules/acls/ait_install_snapshots.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Packages in this list will use devices with app installation snapshots."""
+
+# keep sorted
+APP_INSTALLATION_SNAPSHOT = [
+]
+
+# keep sorted
+APP_INSTALLATION_SNAPSHOT_FALLBACK = [
+]
diff --git a/rules/acls/ait_virtual_device.bzl b/rules/acls/ait_virtual_device.bzl
new file mode 100644
index 0000000..f5ec1b6
--- /dev/null
+++ b/rules/acls/ait_virtual_device.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for switching to virtual_device in android_instrumentation_test."""
+AIT_VIRTUAL_DEVICE_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+AIT_VIRTUAL_DEVICE_FALLBACK = [
+]
diff --git a/rules/acls/allow_resource_conflicts.bzl b/rules/acls/allow_resource_conflicts.bzl
new file mode 100644
index 0000000..d4f9742
--- /dev/null
+++ b/rules/acls/allow_resource_conflicts.bzl
@@ -0,0 +1,20 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+""" Packages of android_binary, android_test, and android_local_test targets that are allowed to contain resource conflicts.
+
+See b/125484033.
+"""
+
+ALLOW_RESOURCE_CONFLICTS = []
diff --git a/rules/acls/android_archive_dogfood.bzl b/rules/acls/android_archive_dogfood.bzl
new file mode 100644
index 0000000..2320db3
--- /dev/null
+++ b/rules/acls/android_archive_dogfood.bzl
@@ -0,0 +1,20 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for targets able to use the android_archive rule."""
+
+# keep sorted
+ANDROID_ARCHIVE_DOGFOOD = [
+ "//:__subpackages__",
+]
diff --git a/rules/acls/android_binary_starlark_resources.bzl b/rules/acls/android_binary_starlark_resources.bzl
new file mode 100644
index 0000000..0291cb6
--- /dev/null
+++ b/rules/acls/android_binary_starlark_resources.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for rollout of Starlark resource processing pipeline in android_binary."""
+
+ANDROID_BINARY_STARLARK_RESOURCES_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+ANDROID_BINARY_STARLARK_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/android_build_stamping_rollout.bzl b/rules/acls/android_build_stamping_rollout.bzl
new file mode 100644
index 0000000..5b1169a
--- /dev/null
+++ b/rules/acls/android_build_stamping_rollout.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for build stamping in the Android Rules."""
+
+# keep sorted
+ANDROID_BUILD_STAMPING_ROLLOUT = [
+]
+
+# keep sorted
+ANDROID_BUILD_STAMPING_FALLBACK = []
diff --git a/rules/acls/android_device_plugin_rollout.bzl b/rules/acls/android_device_plugin_rollout.bzl
new file mode 100644
index 0000000..310da7d
--- /dev/null
+++ b/rules/acls/android_device_plugin_rollout.bzl
@@ -0,0 +1,26 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for ATP Device Plugin rollout."""
+
+# Targets for ATP Device Plugin Rollout
+ANDROID_DEVICE_PLUGIN_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+_READY_TO_ROLLOUT_IN_NEXT_RELEASE = [
+]
+
+ANDROID_DEVICE_PLUGIN_FALLBACK = [
+] + _READY_TO_ROLLOUT_IN_NEXT_RELEASE
diff --git a/rules/acls/android_feature_splits_dogfood.bzl b/rules/acls/android_feature_splits_dogfood.bzl
new file mode 100644
index 0000000..159ef42
--- /dev/null
+++ b/rules/acls/android_feature_splits_dogfood.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for packages able to use Android feature splits.
+
+Dynamic feature splits are still in development and at this stage are only suitable for use
+in an experimental capacity.
+"""
+
+# keep sorted
+ANDROID_FEATURE_SPLITS_DOGFOOD = [
+ "//:__subpackages__",
+]
diff --git a/rules/acls/android_instrumentation_binary_starlark_resources.bzl b/rules/acls/android_instrumentation_binary_starlark_resources.bzl
new file mode 100644
index 0000000..0e55315
--- /dev/null
+++ b/rules/acls/android_instrumentation_binary_starlark_resources.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for rollout of Starlark resource processing pipeline in instrumentation binaries."""
+
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/android_library_implicit_exports.bzl b/rules/acls/android_library_implicit_exports.bzl
new file mode 100644
index 0000000..521c2ac
--- /dev/null
+++ b/rules/acls/android_library_implicit_exports.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/144163743 - deprecated implicit exports."""
+
+# These macros can create android_library targets with deps and no srcs with no way for
+# their users to control this.
+ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS = [
+]
+
+ANDROID_LIBRARY_IMPLICIT_EXPORTS = [
+]
diff --git a/rules/acls/android_library_resources_without_srcs.bzl b/rules/acls/android_library_resources_without_srcs.bzl
new file mode 100644
index 0000000..b376e30
--- /dev/null
+++ b/rules/acls/android_library_resources_without_srcs.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/144163743, allowing implicit export of deps when resources and deps are present."""
+
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS = []
+
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS = ["//:__subpackages__"]
diff --git a/rules/acls/android_library_starlark_resources.bzl b/rules/acls/android_library_starlark_resources.bzl
new file mode 100644
index 0000000..46e68a5
--- /dev/null
+++ b/rules/acls/android_library_starlark_resources.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for diff test for android_library native resource processing vs Starlark processed resources."""
+
+# keep sorted
+ANDROID_LIBRARY_STARLARK_RESOURCES_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+ANDROID_LIBRARY_STARLARK_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/android_lint_rollout.bzl b/rules/acls/android_lint_rollout.bzl
new file mode 100644
index 0000000..65f9ff7
--- /dev/null
+++ b/rules/acls/android_lint_rollout.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for Android Lint in the Android Rules."""
+
+# keep sorted
+ANDROID_LINT_ROLLOUT = [
+]
diff --git a/rules/acls/android_test_lockdown.bzl b/rules/acls/android_test_lockdown.bzl
new file mode 100644
index 0000000..8dce844
--- /dev/null
+++ b/rules/acls/android_test_lockdown.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist of macro and targets that are allowed to use android_test."""
+
+ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS = [
+]
+
+ANDROID_TEST_LOCKDOWN_TARGETS = [
+]
diff --git a/rules/acls/android_test_platform_rollout.bzl b/rules/acls/android_test_platform_rollout.bzl
new file mode 100644
index 0000000..47b879e
--- /dev/null
+++ b/rules/acls/android_test_platform_rollout.bzl
@@ -0,0 +1,26 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for Android Test Platform rollout"""
+
+# Targets for Android Test Platform Rollout
+ANDROID_TEST_PLATFORM_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+_READY_TO_ROLLOUT_IN_NEXT_RELEASE = [
+]
+
+ANDROID_TEST_PLATFORM_FALLBACK = [
+] + _READY_TO_ROLLOUT_IN_NEXT_RELEASE
diff --git a/rules/acls/android_test_starlark_resources.bzl b/rules/acls/android_test_starlark_resources.bzl
new file mode 100644
index 0000000..2510931
--- /dev/null
+++ b/rules/acls/android_test_starlark_resources.bzl
@@ -0,0 +1,17 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for diff test for android_test native vs Starlark processed resources."""
+
+ANDROID_TEST_STARLARK_RESOURCES = []
diff --git a/rules/acls/b122039567.bzl b/rules/acls/b122039567.bzl
new file mode 100644
index 0000000..907b08e
--- /dev/null
+++ b/rules/acls/b122039567.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/122039567."""
+
+B122039567 = [
+]
diff --git a/rules/acls/b123854163.bzl b/rules/acls/b123854163.bzl
new file mode 100644
index 0000000..d23efb5
--- /dev/null
+++ b/rules/acls/b123854163.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/123854163."""
+
+B123854163 = [
+]
diff --git a/rules/acls/dex2oat_opts.bzl b/rules/acls/dex2oat_opts.bzl
new file mode 100644
index 0000000..b935a1f
--- /dev/null
+++ b/rules/acls/dex2oat_opts.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Packages in this list are allowed to specify custom dex2oat options."""
+
+# keep sorted
+CAN_USE_DEX2OAT_OPTIONS = [
+]
diff --git a/rules/acls/fix_application_id.bzl b/rules/acls/fix_application_id.bzl
new file mode 100644
index 0000000..41c18b7
--- /dev/null
+++ b/rules/acls/fix_application_id.bzl
@@ -0,0 +1,27 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for fixing the implicit application ID in manifest processing.
+
+See b/111923269 for context.
+"""
+
+# keep sorted
+FIX_APPLICATION_ID_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+# keep sorted
+FIX_APPLICATION_ID_FALLBACK = [
+]
diff --git a/rules/acls/fix_export_exporting_rollout.bzl b/rules/acls/fix_export_exporting_rollout.bzl
new file mode 100644
index 0000000..cb68adf
--- /dev/null
+++ b/rules/acls/fix_export_exporting_rollout.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for making exports actually be exported."""
+
+# keep sorted
+FIX_EXPORT_EXPORTING_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+# keep sorted
+FIX_EXPORT_EXPORTING_FALLBACK = [
+]
diff --git a/rules/acls/fix_resource_transitivity_rollout.bzl b/rules/acls/fix_resource_transitivity_rollout.bzl
new file mode 100644
index 0000000..bdde15f
--- /dev/null
+++ b/rules/acls/fix_resource_transitivity_rollout.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for fixing resource dependencies passing through rules with no manifest."""
+
+# keep sorted
+FIX_RESOURCE_TRANSITIVITY_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+FIX_RESOURCE_TRANSITIVITY_FALLBACK = []
diff --git a/rules/acls/host_dex2oat_rollout.bzl b/rules/acls/host_dex2oat_rollout.bzl
new file mode 100644
index 0000000..b3da4ee
--- /dev/null
+++ b/rules/acls/host_dex2oat_rollout.bzl
@@ -0,0 +1,27 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Whitelist for using host dex2oat with android_instrumentation_test."""
+
+ANDROID_TEST_HOST_DEX2OAT_ROLLOUT = [
+ "//...",
+]
+
+# keep sorted
+AIT_USE_HOST_DEX2OAT_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK = [
+]
diff --git a/rules/acls/install_apps_in_data.bzl b/rules/acls/install_apps_in_data.bzl
new file mode 100644
index 0000000..58994bf
--- /dev/null
+++ b/rules/acls/install_apps_in_data.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Whitelist for using installing apps in data attr in android_instrumentation_test."""
+
+INSTALL_APPS_IN_DATA = [
+]
diff --git a/rules/acls/kt_android_library_rollout.bzl b/rules/acls/kt_android_library_rollout.bzl
new file mode 100644
index 0000000..50c43a4
--- /dev/null
+++ b/rules/acls/kt_android_library_rollout.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list to rollout the kt_android_library rule from rules_android."""
+
+# keep sorted
+KT_ANDROID_LIBRARY_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+# keep sorted
+KT_ANDROID_LIBRARY_FALLBACK = [
+]
diff --git a/rules/acls/library_rollout.bzl b/rules/acls/library_rollout.bzl
new file mode 100644
index 0000000..cb42a88
--- /dev/null
+++ b/rules/acls/library_rollout.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for Starlark android_library rollout"""
+
+LIBRARY_ROLLOUT = [
+ # keep sorted
+ "//:__subpackages__",
+]
+
+LIBRARY_FALLBACK = [
+]
diff --git a/rules/acls/library_rollout_override.bzl b/rules/acls/library_rollout_override.bzl
new file mode 100644
index 0000000..805bf0f
--- /dev/null
+++ b/rules/acls/library_rollout_override.bzl
@@ -0,0 +1,17 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A Starlark android_library rollout override switch, for testing."""
+
+LIBRARY_ROLLOUT_OVERRIDE = None # A tristate: None, True or False.
diff --git a/rules/acls/local_test_multi_proto.bzl b/rules/acls/local_test_multi_proto.bzl
new file mode 100644
index 0000000..e0bc06b
--- /dev/null
+++ b/rules/acls/local_test_multi_proto.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for android_local_test targets allowed to depend on java_proto_library.
+
+See b/120162253 for context.
+"""
+
+LOCAL_TEST_MULTI_PROTO = [
+]
+
+LOCAL_TEST_MULTI_PROTO_PKG = [x + ":__pkg__" for x in LOCAL_TEST_MULTI_PROTO]
diff --git a/rules/acls/local_test_rollout.bzl b/rules/acls/local_test_rollout.bzl
new file mode 100644
index 0000000..889d82c
--- /dev/null
+++ b/rules/acls/local_test_rollout.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for Starlark android_local_test rollout"""
+
+LOCAL_TEST_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+LOCAL_TEST_FALLBACK = [
+]
diff --git a/rules/acls/local_test_starlark_resources.bzl b/rules/acls/local_test_starlark_resources.bzl
new file mode 100644
index 0000000..19c1777
--- /dev/null
+++ b/rules/acls/local_test_starlark_resources.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for android_local_test Starlark processed resources."""
+
+LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT = [
+]
+
+LOCAL_TEST_STARLARK_RESOURCES_FALLBACK = [
+ "//:__subpackages__",
+]
diff --git a/rules/acls/nitrogen_test_runner_rollout.bzl b/rules/acls/nitrogen_test_runner_rollout.bzl
new file mode 100644
index 0000000..891671e
--- /dev/null
+++ b/rules/acls/nitrogen_test_runner_rollout.bzl
@@ -0,0 +1,28 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for Nitrogen rollout"""
+
+# Nitrogen targets for android_instrumentation_test rollout
+NITROGEN_TEST_RUNNER_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+# Nitrogen targets for android_test rollout
+NITROGEN_AT_TEST_RUNNER_ROLLOUT = [
+ "//:__subpackages__",
+]
+
+NITROGEN_TEST_RUNNER_FALLBACK = [
+]
diff --git a/rules/acls/partial_jetification_targets.bzl b/rules/acls/partial_jetification_targets.bzl
new file mode 100644
index 0000000..490c3ea
--- /dev/null
+++ b/rules/acls/partial_jetification_targets.bzl
@@ -0,0 +1,20 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for targets or subsets of targets to partially jetify at build time"""
+
+PARTIAL_JETIFICATION_TARGETS_ROLLOUT = [
+]
+
+PARTIAL_JETIFICATION_TARGETS_FALLBACK = []
diff --git a/rules/acls/sourceless_binary_rollout.bzl b/rules/acls/sourceless_binary_rollout.bzl
new file mode 100644
index 0000000..132ba10
--- /dev/null
+++ b/rules/acls/sourceless_binary_rollout.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for sourceless android_binary rollout"""
+
+SOURCELESS_BINARY_ROLLOUT = [
+]
+
+SOURCELESS_BINARY_FALLBACK = [
+]
diff --git a/rules/acls/starlark_resources_diff.bzl b/rules/acls/starlark_resources_diff.bzl
new file mode 100644
index 0000000..ed7752e
--- /dev/null
+++ b/rules/acls/starlark_resources_diff.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for diff test for native vs Starlark resource processing pipelines."""
+
+STARLARK_RESOURCES_DIFF = [
+]
diff --git a/rules/acls/test_to_instrument_test_rollout.bzl b/rules/acls/test_to_instrument_test_rollout.bzl
new file mode 100644
index 0000000..835880d
--- /dev/null
+++ b/rules/acls/test_to_instrument_test_rollout.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for android_test to android_instrumentation_test rollout"""
+
+TEST_TO_INSTRUMENT_TEST_ROLLOUT = [
+]
+
+TEST_TO_INSTRUMENT_TEST_FALLBACK = [
+]
diff --git a/rules/android_binary.bzl b/rules/android_binary.bzl
new file mode 100644
index 0000000..1760e75
--- /dev/null
+++ b/rules/android_binary.bzl
@@ -0,0 +1,42 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for building an APK."""
+
+load(":migration_tag_DONOTUSE.bzl", "add_migration_tag")
+load("@rules_android//rules/android_packaged_resources:rule.bzl", "android_packaged_resources_macro")
+
+def android_binary(**attrs):
+ """Bazel android_binary rule.
+
+ https://docs.bazel.build/versions/master/be/android.html#android_binary
+
+ Args:
+ **attrs: Rule attributes
+ """
+ packaged_resources_name = ":%s_RESOURCES_DO_NOT_USE" % attrs["name"]
+ android_packaged_resources_macro(
+ **dict(
+ attrs,
+ name = packaged_resources_name[1:],
+ visibility = ["//visibility:private"],
+ )
+ )
+
+ attrs.pop("$enable_manifest_merging", None)
+
+ native.android_binary(
+ application_resources = packaged_resources_name,
+ **add_migration_tag(attrs)
+ )
diff --git a/rules/android_library/BUILD b/rules/android_library/BUILD
new file mode 100644
index 0000000..09ca5b8
--- /dev/null
+++ b/rules/android_library/BUILD
@@ -0,0 +1,21 @@
+# The android_library rule.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+licenses(["notice"])
+
+exports_files(["rule.bzl"])
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+)
+
+bzl_library(
+ name = "bzl",
+ srcs = glob(["*.bzl"]),
+ deps = [
+ "@rules_android//rules:common_bzl",
+ "@rules_android//rules/flags:bzl",
+ ],
+)
diff --git a/rules/android_library/attrs.bzl b/rules/android_library/attrs.bzl
new file mode 100644
index 0000000..16a18e7
--- /dev/null
+++ b/rules/android_library/attrs.bzl
@@ -0,0 +1,73 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Attributes."""
+
+load(
+ "@rules_android//rules:attrs.bzl",
+ _attrs = "attrs",
+)
+
+ATTRS = _attrs.add(
+ dict(
+ deps = attr.label_list(
+ providers = [
+ [CcInfo],
+ [JavaInfo],
+ ],
+ ),
+ enable_data_binding = attr.bool(default = False),
+ exported_plugins = attr.label_list(
+ allow_rules = [
+ "java_plugin",
+ ],
+ cfg = "host",
+ ),
+ exports = attr.label_list(
+ providers = [
+ [CcInfo],
+ [JavaInfo],
+ ],
+ ),
+ exports_manifest =
+ _attrs.tristate.create(default = _attrs.tristate.no),
+ idl_import_root = attr.string(),
+ idl_parcelables = attr.label_list(allow_files = [".aidl"]),
+ idl_preprocessed = attr.label_list(allow_files = [".aidl"]),
+ idl_srcs = attr.label_list(allow_files = [".aidl"]),
+ neverlink = attr.bool(default = False),
+ proguard_specs = attr.label_list(allow_files = True),
+ srcs = attr.label_list(
+ allow_files = [".java", ".srcjar"],
+ ),
+ # TODO(b/127517031): Remove these entries once fixed.
+ _defined_assets = attr.bool(default = False),
+ _defined_assets_dir = attr.bool(default = False),
+ _defined_idl_import_root = attr.bool(default = False),
+ _defined_idl_parcelables = attr.bool(default = False),
+ _defined_idl_srcs = attr.bool(default = False),
+ _defined_local_resources = attr.bool(default = False),
+ _java_toolchain = attr.label(
+ cfg = "host",
+ default = Label("//tools/jdk:toolchain_android_only"),
+ ),
+ # TODO(str): Remove when fully migrated to android_instrumentation_test
+ _android_test_migration = attr.bool(default = False),
+ _flags = attr.label(
+ default = "@rules_android//rules/flags",
+ ),
+ ),
+ _attrs.COMPILATION,
+ _attrs.DATA_CONTEXT,
+)
diff --git a/rules/android_library/impl.bzl b/rules/android_library/impl.bzl
new file mode 100644
index 0000000..232899c
--- /dev/null
+++ b/rules/android_library/impl.bzl
@@ -0,0 +1,534 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation."""
+
+load("@rules_android//rules:acls.bzl", "acls")
+load("@rules_android//rules:attrs.bzl", _attrs = "attrs")
+load("@rules_android//rules:common.bzl", _common = "common")
+load("@rules_android//rules:data_binding.bzl", _data_binding = "data_binding")
+load("@rules_android//rules:idl.bzl", _idl = "idl")
+load("@rules_android//rules:intellij.bzl", _intellij = "intellij")
+load("@rules_android//rules:java.bzl", _java = "java")
+load(
+ "@rules_android//rules:processing_pipeline.bzl",
+ "ProviderInfo",
+ "processing_pipeline",
+)
+load("@rules_android//rules:proguard.bzl", _proguard = "proguard")
+load("@rules_android//rules:resources.bzl", _resources = "resources")
+load("@rules_android//rules:utils.bzl", "get_android_sdk", "get_android_toolchain", "log", "utils")
+load("@rules_android//rules/flags:flags.bzl", _flags = "flags")
+
+_USES_DEPRECATED_IMPLICIT_EXPORT_ERROR = (
+ "The android_library rule will be deprecating the use of deps to export " +
+ "targets implicitly. " +
+ "Please use android_library.exports to explicitly specify the exported " +
+ "targets of %s."
+)
+
+_SRCS_CONTAIN_RESOURCE_LABEL_ERROR = (
+ "The srcs attribute of an android_library rule should not contain label " +
+ "with resources %s"
+)
+
+_IDL_IMPORT_ROOT_SET_WITHOUT_SRCS_OR_PARCELABLES_ERROR = (
+ "The 'idl_import_root' attribute of the android_library rule was set, " +
+ "but neither 'idl_srcs' nor 'idl_parcelables' were specified."
+)
+
+_IDL_SRC_FROM_DIFFERENT_PACKAGE_ERROR = (
+ "Do not import '%s' directly. You should either move the file to this " +
+ "package or depend on an appropriate rule there."
+)
+
+# Android library AAR context attributes.
+_PROVIDERS = "providers"
+_VALIDATION_OUTPUTS = "validation_outputs"
+
+_AARContextInfo = provider(
+ "Android library AAR context object",
+ fields = {
+ _PROVIDERS: "The list of all providers to propagate.",
+ _VALIDATION_OUTPUTS: "List of outputs given to OutputGroupInfo _validation group",
+ },
+)
+
+def _uses_deprecated_implicit_export(ctx):
+ if not ctx.attr.deps:
+ return False
+ return not (ctx.files.srcs or
+ ctx.files.idl_srcs or
+ ctx.attr._defined_assets or
+ ctx.files.resource_files or
+ ctx.attr.manifest)
+
+def _uses_resources_and_deps_without_srcs(ctx):
+ if not ctx.attr.deps:
+ return False
+ if not (ctx.attr._defined_assets or
+ ctx.files.resource_files or
+ ctx.attr.manifest):
+ return False
+ return not (ctx.files.srcs or ctx.files.idl_srcs)
+
+def _check_deps_without_java_srcs(ctx):
+ if not ctx.attr.deps or ctx.files.srcs or ctx.files.idl_srcs:
+ return False
+ gfn = getattr(ctx.attr, "generator_function", "")
+ if _uses_deprecated_implicit_export(ctx):
+ if (acls.in_android_library_implicit_exports_generator_functions(gfn) or
+ acls.in_android_library_implicit_exports(str(ctx.label))):
+ return True
+ else:
+ # TODO(b/144163743): add a test for this.
+ log.error(_USES_DEPRECATED_IMPLICIT_EXPORT_ERROR % ctx.label)
+ if _uses_resources_and_deps_without_srcs(ctx):
+ if (acls.in_android_library_resources_without_srcs_generator_functions(gfn) or
+ acls.in_android_library_resources_without_srcs(str(ctx.label))):
+ return True
+ return False
+
+def _validate_rule_context(ctx):
+ # Verify that idl_import_root is specified with idl_src or idl_parcelables.
+ if (ctx.attr._defined_idl_import_root and
+ not (ctx.attr._defined_idl_srcs or ctx.attr._defined_idl_parcelables)):
+ log.error(_IDL_IMPORT_ROOT_SET_WITHOUT_SRCS_OR_PARCELABLES_ERROR)
+
+ # Verify that idl_srcs are not from another package.
+ for idl_src in ctx.attr.idl_srcs:
+ if ctx.label.package != idl_src.label.package:
+ log.error(_IDL_SRC_FROM_DIFFERENT_PACKAGE_ERROR % idl_src.label)
+
+ return struct(
+ enable_deps_without_srcs = _check_deps_without_java_srcs(ctx),
+ )
+
+def _exceptions_processor(ctx, **unused_ctxs):
+ return ProviderInfo(
+ name = "exceptions_ctx",
+ value = _validate_rule_context(ctx),
+ )
+
+def _process_resources(ctx, java_package, **unused_ctxs):
+ # exports_manifest can be overridden by a bazel flag.
+ if ctx.attr.exports_manifest == _attrs.tristate.auto:
+ exports_manifest = ctx.fragments.android.get_exports_manifest_default
+ else:
+ exports_manifest = ctx.attr.exports_manifest == _attrs.tristate.yes
+
+ # Process Android Resources
+ resources_ctx = _resources.process(
+ ctx,
+ manifest = ctx.file.manifest,
+ resource_files = ctx.attr.resource_files,
+ defined_assets = ctx.attr._defined_assets,
+ assets = ctx.attr.assets,
+ defined_assets_dir = ctx.attr._defined_assets_dir,
+ assets_dir = ctx.attr.assets_dir,
+ exports_manifest = exports_manifest,
+ java_package = java_package,
+ custom_package = ctx.attr.custom_package,
+ neverlink = ctx.attr.neverlink,
+ enable_data_binding = ctx.attr.enable_data_binding,
+ deps = ctx.attr.deps,
+ exports = ctx.attr.exports,
+
+ # Processing behavior changing flags.
+ enable_res_v3 = _flags.get(ctx).android_enable_res_v3,
+ # TODO(b/144163743): remove fix_resource_transitivity, which was only added to emulate
+ # misbehavior on the Java side.
+ fix_resource_transitivity = bool(ctx.attr.srcs),
+ fix_export_exporting = acls.in_fix_export_exporting_rollout(str(ctx.label)),
+ android_test_migration = ctx.attr._android_test_migration,
+
+ # Tool and Processing related inputs
+ aapt = get_android_toolchain(ctx).aapt2.files_to_run,
+ android_jar = get_android_sdk(ctx).android_jar,
+ android_kit = get_android_toolchain(ctx).android_kit.files_to_run,
+ busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+ java_toolchain = _common.get_java_toolchain(ctx),
+ host_javabase = _common.get_host_javabase(ctx),
+ instrument_xslt = utils.only(get_android_toolchain(ctx).add_g3itr_xslt.files.to_list()),
+ res_v3_dummy_manifest = utils.only(
+ get_android_toolchain(ctx).res_v3_dummy_manifest.files.to_list(),
+ ),
+ res_v3_dummy_r_txt = utils.only(
+ get_android_toolchain(ctx).res_v3_dummy_r_txt.files.to_list(),
+ ),
+ xsltproc = get_android_toolchain(ctx).xsltproc_tool.files_to_run,
+ zip_tool = get_android_toolchain(ctx).zip_tool.files_to_run,
+ )
+
+ # TODO(b/139305816): Remove the ability for android_library to be added in
+ # the srcs attribute of another android_library.
+ if resources_ctx.defines_resources:
+ # Verify that srcs do no contain labels.
+ for src in ctx.attr.srcs:
+ if AndroidResourcesInfo in src:
+ log.error(_SRCS_CONTAIN_RESOURCE_LABEL_ERROR %
+ src[AndroidResourcesInfo].label)
+
+ return ProviderInfo(
+ name = "resources_ctx",
+ value = resources_ctx,
+ )
+
+def _process_idl(ctx, **unused_sub_ctxs):
+ return ProviderInfo(
+ name = "idl_ctx",
+ value = _idl.process(
+ ctx,
+ idl_srcs = ctx.files.idl_srcs,
+ idl_parcelables = ctx.files.idl_parcelables,
+ idl_import_root =
+ ctx.attr.idl_import_root if ctx.attr._defined_idl_import_root else None,
+ idl_preprocessed = ctx.files.idl_preprocessed,
+ deps = utils.collect_providers(AndroidIdlInfo, ctx.attr.deps),
+ exports = utils.collect_providers(AndroidIdlInfo, ctx.attr.exports),
+ aidl = get_android_sdk(ctx).aidl,
+ aidl_lib = get_android_sdk(ctx).aidl_lib,
+ aidl_framework = get_android_sdk(ctx).framework_aidl,
+ ),
+ )
+
+def _process_data_binding(ctx, java_package, resources_ctx, **unused_sub_ctxs):
+ return ProviderInfo(
+ name = "db_ctx",
+ value = _data_binding.process(
+ ctx,
+ defines_resources = resources_ctx.defines_resources,
+ enable_data_binding = ctx.attr.enable_data_binding,
+ java_package = java_package,
+ deps = utils.collect_providers(DataBindingV2Info, ctx.attr.deps),
+ exports = utils.collect_providers(DataBindingV2Info, ctx.attr.exports),
+ data_binding_exec = get_android_toolchain(ctx).data_binding_exec.files_to_run,
+ data_binding_annotation_processor =
+ get_android_toolchain(ctx).data_binding_annotation_processor[JavaInfo],
+ data_binding_annotation_template =
+ utils.only(get_android_toolchain(ctx).data_binding_annotation_template.files.to_list()),
+ ),
+ )
+
+def _process_proguard(ctx, idl_ctx, **unused_sub_ctxs):
+ return ProviderInfo(
+ name = "proguard_ctx",
+ value = _proguard.process(
+ ctx,
+ proguard_configs = ctx.files.proguard_specs,
+ proguard_spec_providers = utils.collect_providers(
+ ProguardSpecProvider,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ ctx.attr.plugins,
+ ctx.attr.exported_plugins,
+ idl_ctx.idl_deps,
+ ),
+ proguard_allowlister =
+ get_android_toolchain(ctx).proguard_allowlister.files_to_run,
+ ),
+ )
+
+def _process_jvm(ctx, exceptions_ctx, resources_ctx, idl_ctx, db_ctx, **unused_sub_ctxs):
+ java_info = _java.compile_android(
+ ctx,
+ ctx.outputs.lib_jar,
+ ctx.outputs.lib_src_jar,
+ srcs = ctx.files.srcs + idl_ctx.idl_java_srcs + db_ctx.java_srcs,
+ javac_opts = ctx.attr.javacopts + db_ctx.javac_opts,
+ r_java = resources_ctx.r_java,
+ deps =
+ utils.collect_providers(JavaInfo, ctx.attr.deps, idl_ctx.idl_deps),
+ exports = utils.collect_providers(JavaInfo, ctx.attr.exports),
+ plugins = (
+ utils.collect_providers(JavaInfo, ctx.attr.plugins) +
+ db_ctx.java_plugins
+ ),
+ exported_plugins = utils.collect_providers(
+ JavaInfo,
+ ctx.attr.exported_plugins,
+ ),
+ annotation_processor_additional_outputs = (
+ db_ctx.java_annotation_processor_additional_outputs
+ ),
+ annotation_processor_additional_inputs = (
+ db_ctx.java_annotation_processor_additional_inputs
+ ),
+ enable_deps_without_srcs = exceptions_ctx.enable_deps_without_srcs,
+ neverlink = ctx.attr.neverlink,
+ strict_deps = "DEFAULT",
+ java_toolchain = _common.get_java_toolchain(ctx),
+ )
+
+ return ProviderInfo(
+ name = "jvm_ctx",
+ value = struct(
+ java_info = java_info,
+ providers = [java_info],
+ ),
+ )
+
+def _process_aar(ctx, java_package, resources_ctx, proguard_ctx, **unused_ctx):
+ aar_ctx = {
+ _PROVIDERS: [],
+ _VALIDATION_OUTPUTS: [],
+ }
+
+ starlark_aar = _resources.make_aar(
+ ctx,
+ manifest = resources_ctx.starlark_processed_manifest,
+ assets = ctx.files.assets,
+ assets_dir = ctx.attr.assets_dir,
+ resource_files = resources_ctx.starlark_processed_resources if not ctx.attr.neverlink else [],
+ class_jar = ctx.outputs.lib_jar,
+ r_txt = resources_ctx.starlark_r_txt,
+ proguard_specs = proguard_ctx.proguard_configs,
+ busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+ host_javabase = _common.get_host_javabase(ctx),
+ )
+
+ # TODO(b/170409221): Clean this up once Starlark migration is complete. Create and propagate
+ # a native aar info provider with the Starlark artifacts to avoid breaking downstream
+ # targets.
+ if not ctx.attr.neverlink:
+ aar_ctx[_PROVIDERS].append(AndroidLibraryAarInfo(
+ aar = starlark_aar,
+ manifest = resources_ctx.starlark_processed_manifest,
+ aars_from_deps = utils.collect_providers(
+ AndroidLibraryAarInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ ),
+ defines_local_resources = resources_ctx.defines_resources,
+ ))
+
+ return ProviderInfo(
+ name = "aar_ctx",
+ value = _AARContextInfo(**aar_ctx),
+ )
+
+def _process_native(ctx, idl_ctx, **unused_ctx):
+ return ProviderInfo(
+ name = "native_ctx",
+ value = struct(
+ providers = [
+ AndroidNativeLibsInfo(
+ depset(
+ transitive = [
+ p.native_libs
+ for p in utils.collect_providers(
+ AndroidNativeLibsInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ )
+ ],
+ order = "preorder",
+ ),
+ ),
+ AndroidCcLinkParamsInfo(
+ cc_common.merge_cc_infos(
+ cc_infos = [
+ info.cc_info
+ for info in utils.collect_providers(
+ JavaCcLinkParamsInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ idl_ctx.idl_deps,
+ )
+ ] +
+ [
+ info.link_params
+ for info in utils.collect_providers(
+ AndroidCcLinkParamsInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ idl_ctx.idl_deps,
+ )
+ ] +
+ utils.collect_providers(
+ CcInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ idl_ctx.idl_deps,
+ ),
+ ),
+ ),
+ ],
+ ),
+ )
+
+def _process_intellij(ctx, java_package, resources_ctx, idl_ctx, jvm_ctx, **unused_sub_ctxs):
+ android_ide_info = _intellij.make_android_ide_info(
+ ctx,
+ java_package = java_package,
+ manifest = ctx.file.manifest,
+ defines_resources = resources_ctx.defines_resources,
+ merged_manifest = resources_ctx.merged_manifest,
+ resources_apk = resources_ctx.resources_apk,
+ r_jar = utils.only(resources_ctx.r_java.outputs.jars) if resources_ctx.r_java else None,
+ idl_import_root = idl_ctx.idl_import_root,
+ idl_srcs = idl_ctx.idl_srcs,
+ idl_java_srcs = idl_ctx.idl_java_srcs,
+ java_info = jvm_ctx.java_info,
+ signed_apk = None, # signed_apk, always empty for android_library.
+ aar = getattr(ctx.outputs, "aar", None), # Deprecate aar for android_library.
+ apks_under_test = [], # apks_under_test, always empty for android_library
+ native_libs = dict(), # nativelibs, always empty for android_library
+ idlclass = get_android_toolchain(ctx).idlclass.files_to_run,
+ host_javabase = _common.get_host_javabase(ctx),
+ )
+ return ProviderInfo(
+ name = "intellij_ctx",
+ value = struct(
+ android_ide_info = android_ide_info,
+ providers = [android_ide_info],
+ ),
+ )
+
+def _process_coverage(ctx, **unused_ctx):
+ return ProviderInfo(
+ name = "coverage_ctx",
+ value = struct(
+ providers = [
+ coverage_common.instrumented_files_info(
+ ctx,
+ dependency_attributes = ["assets", "deps", "exports"],
+ ),
+ ],
+ ),
+ )
+
+# Order dependent, as providers will not be available to downstream processors
+# that may depend on the provider. Iteration order for a dictionary is based on
+# insertion.
+PROCESSORS = dict(
+ ExceptionsProcessor = _exceptions_processor,
+ ResourceProcessor = _process_resources,
+ IdlProcessor = _process_idl,
+ DataBindingProcessor = _process_data_binding,
+ JvmProcessor = _process_jvm,
+ ProguardProcessor = _process_proguard,
+ AarProcessor = _process_aar,
+ NativeProcessor = _process_native,
+ IntelliJProcessor = _process_intellij,
+ CoverageProcessor = _process_coverage,
+)
+
+# TODO(b/119560471): Deprecate the usage of legacy providers.
+def _make_legacy_provider(intellij_ctx, jvm_ctx, providers):
+ return struct(
+ android = _intellij.make_legacy_android_provider(intellij_ctx.android_ide_info),
+ java = struct(
+ annotation_processing = jvm_ctx.java_info.annotation_processing,
+ compilation_info = jvm_ctx.java_info.compilation_info,
+ outputs = jvm_ctx.java_info.outputs,
+ source_jars = depset(jvm_ctx.java_info.source_jars),
+ transitive_deps = jvm_ctx.java_info.transitive_compile_time_jars,
+ transitive_exports = jvm_ctx.java_info.transitive_exports,
+ transitive_runtime_deps = jvm_ctx.java_info.transitive_runtime_jars,
+ transitive_source_jars = jvm_ctx.java_info.transitive_source_jars,
+ ),
+ providers = providers,
+ )
+
+def finalize(
+ ctx,
+ resources_ctx,
+ intellij_ctx,
+ jvm_ctx,
+ proguard_ctx,
+ providers,
+ validation_outputs,
+ **unused_ctxs):
+ """Creates the DefaultInfo and OutputGroupInfo providers.
+
+ Args:
+ ctx: The context.
+ resources_ctx: ProviderInfo. The resources ctx.
+ intellij_ctx: ProviderInfo. The intellij ctx.
+ jvm_ctx: ProviderInfo. The jvm ctx.
+ proguard_ctx: ProviderInfo. The proguard ctx.
+ providers: sequence of providers. The providers to propagate.
+ validation_outputs: sequence of Files. The validation outputs.
+ **unused_ctxs: Unused ProviderInfo.
+
+ Returns:
+ A struct with Android and Java legacy providers and a list of providers.
+ """
+ transitive_runfiles = []
+ if not ctx.attr.neverlink:
+ for p in utils.collect_providers(
+ DefaultInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ ):
+ transitive_runfiles.append(p.data_runfiles.files)
+ transitive_runfiles.append(p.default_runfiles.files)
+ runfiles = ctx.runfiles(
+ files = (
+ (resources_ctx.r_java.runtime_output_jars if resources_ctx.r_java and not ctx.attr.neverlink else []) +
+ ([ctx.outputs.lib_jar] if (ctx.attr.srcs or ctx.attr.idl_srcs) and not ctx.attr.neverlink else [])
+ ),
+ transitive_files = depset(transitive = transitive_runfiles),
+ collect_default = True,
+ )
+ files = [ctx.outputs.lib_jar]
+ if getattr(ctx.outputs, "resources_src_jar", None):
+ files.append(ctx.outputs.resources_src_jar)
+ if getattr(ctx.outputs, "resources_jar", None):
+ files.append(ctx.outputs.resources_jar)
+
+ providers.extend([
+ DefaultInfo(
+ files = depset(files),
+ runfiles = runfiles,
+ ),
+ OutputGroupInfo(
+ compilation_outputs = depset([ctx.outputs.lib_jar]),
+ _source_jars = depset(
+ [ctx.outputs.lib_src_jar],
+ transitive = [jvm_ctx.java_info.transitive_source_jars],
+ ),
+ _hidden_top_level_INTERNAL_ = depset(
+ resources_ctx.validation_results,
+ transitive = [
+ info._hidden_top_level_INTERNAL_
+ for info in utils.collect_providers(
+ OutputGroupInfo,
+ ctx.attr.deps,
+ ctx.attr.exports,
+ )
+ ] + [proguard_ctx.transitive_proguard_configs],
+ ),
+ _validation = depset(validation_outputs),
+ ),
+ ])
+ return _make_legacy_provider(intellij_ctx, jvm_ctx, providers)
+
+_PROCESSING_PIPELINE = processing_pipeline.make_processing_pipeline(
+ processors = PROCESSORS,
+ finalize = finalize,
+)
+
+def impl(ctx):
+ """The rule implementation.
+
+ Args:
+ ctx: The context.
+
+ Returns:
+ A legacy struct provider.
+ """
+ java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.custom_package)
+ return processing_pipeline.run(ctx, java_package, _PROCESSING_PIPELINE)
diff --git a/rules/android_library/rule.bzl b/rules/android_library/rule.bzl
new file mode 100644
index 0000000..f267b37
--- /dev/null
+++ b/rules/android_library/rule.bzl
@@ -0,0 +1,135 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""android_library rule."""
+
+load(":attrs.bzl", _ATTRS = "ATTRS")
+load(":impl.bzl", _impl = "impl")
+load(
+ "@rules_android//rules:attrs.bzl",
+ _attrs = "attrs",
+)
+
+def _outputs(_defined_local_resources):
+ outputs = dict(
+ lib_jar = "lib%{name}.jar",
+ lib_src_jar = "lib%{name}-src.jar",
+ aar = "%{name}.aar",
+ )
+
+ if _defined_local_resources:
+ # TODO(b/177261846): resource-related predeclared outputs need to be re-pointed at the
+ # corresponding artifacts in the Starlark pipeline.
+ outputs.update(
+ dict(
+ resources_src_jar = "_migrated/%{name}.srcjar",
+ resources_txt = "_migrated/%{name}_symbols/R.txt",
+ resources_jar = "_migrated/%{name}_resources.jar",
+ ),
+ )
+
+ return outputs
+
+def make_rule(
+ attrs = _ATTRS,
+ implementation = _impl,
+ outputs = _outputs,
+ additional_toolchains = []):
+ """Makes the rule.
+
+ Args:
+ attrs: A dict. The attributes for the rule.
+ implementation: A function. The rule's implementation method.
+
+ Returns:
+ A rule.
+ """
+ return rule(
+ attrs = attrs,
+ fragments = [
+ "android",
+ "java",
+ ],
+ implementation = implementation,
+ provides = [
+ AndroidCcLinkParamsInfo,
+ AndroidIdeInfo,
+ AndroidIdlInfo,
+ AndroidLibraryResourceClassJarProvider,
+ AndroidNativeLibsInfo,
+ JavaInfo,
+ ],
+ outputs = outputs,
+ toolchains = [
+ "@rules_android//toolchains/android:toolchain_type",
+ "@rules_android//toolchains/android_sdk:toolchain_type",
+ ] + additional_toolchains,
+ _skylark_testable = True,
+ )
+
+android_library = make_rule()
+
+def _is_defined(name, attrs):
+ return name in attrs and attrs[name] != None
+
+def attrs_metadata(attrs):
+ """Adds additional metadata for specific android_library attrs.
+
+ Bazel native rules have additional capabilities when inspecting attrs that
+ are not available in Starlark. For example, native rules are able to
+ determine if an attribute was set by a user and make decisions based on this
+ knowledge - sometimes the behavior may differ if the user specifies the
+ default value of the attribute. As such the Starlark android_library uses
+ this shim to provide similar capabilities.
+
+ Args:
+ attrs: The attributes passed to the android_library rule.
+
+ Returns:
+ A dictionary containing attr values with additional metadata.
+ """
+
+ # Required for the outputs.
+ attrs["$defined_local_resources"] = bool(
+ attrs.get("assets") or
+ attrs.get("assets_dir") or
+ attrs.get("assets_dir") == "" or
+ attrs.get("export_manifest") or
+ attrs.get("manifest") or
+ attrs.get("resource_files"),
+ )
+
+ # TODO(b/116691720): Remove normalization when bug is fixed.
+ if _is_defined("exports_manifest", attrs):
+ attrs["exports_manifest"] = _attrs.tristate.normalize(
+ attrs.get("exports_manifest"),
+ )
+
+ # TODO(b/127517031): Remove these entries once fixed.
+ attrs["$defined_assets"] = _is_defined("assets", attrs)
+ attrs["$defined_assets_dir"] = _is_defined("assets_dir", attrs)
+ attrs["$defined_idl_import_root"] = _is_defined("idl_import_root", attrs)
+ attrs["$defined_idl_parcelables"] = _is_defined("idl_parcelables", attrs)
+ attrs["$defined_idl_srcs"] = _is_defined("idl_srcs", attrs)
+ return attrs
+
+def android_library_macro(**attrs):
+ """Bazel android_library rule.
+
+ https://docs.bazel.build/versions/master/be/android.html#android_library
+
+ Args:
+ **attrs: Rule attributes
+ """
+ android_library(**attrs_metadata(attrs))
diff --git a/rules/android_local_test.bzl b/rules/android_local_test.bzl
new file mode 100644
index 0000000..9b1fe39
--- /dev/null
+++ b/rules/android_local_test.bzl
@@ -0,0 +1,27 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android local test."""
+
+load(":migration_tag_DONOTUSE.bzl", _add_migration_tag = "add_migration_tag")
+
+def android_local_test(**attrs):
+ """Bazel android_local_test rule.
+
+ https://docs.bazel.build/versions/master/be/android.html#android_local_test
+
+ Args:
+ **attrs: Rule attributes
+ """
+ native.android_local_test(**_add_migration_tag(attrs))
diff --git a/rules/android_ndk_repository.bzl b/rules/android_ndk_repository.bzl
new file mode 100644
index 0000000..34aa2e3
--- /dev/null
+++ b/rules/android_ndk_repository.bzl
@@ -0,0 +1,25 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android ndk repository."""
+
+def android_ndk_repository(**attrs):
+ """Bazel android_ndk_repository rule.
+
+ https://docs.bazel.build/versions/master/be/android.html#android_ndk_repository
+
+ Args:
+ **attrs: Rule attributes
+ """
+ native.android_ndk_repository(**attrs)
diff --git a/rules/android_packaged_resources/BUILD b/rules/android_packaged_resources/BUILD
new file mode 100644
index 0000000..f858689
--- /dev/null
+++ b/rules/android_packaged_resources/BUILD
@@ -0,0 +1,25 @@
+# Starlark Resource Packaging for Android Rules.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+package(
+ default_visibility =
+ ["//third_party/bazel_rules/rules_android"],
+)
+
+licenses(["notice"])
+
+exports_files(["rule.bzl"])
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+)
+
+bzl_library(
+ name = "bzl",
+ srcs = glob(["*.bzl"]),
+ deps = [
+ "@rules_android//rules:common_bzl",
+ ],
+)
diff --git a/rules/android_packaged_resources/attrs.bzl b/rules/android_packaged_resources/attrs.bzl
new file mode 100644
index 0000000..5a7bca7
--- /dev/null
+++ b/rules/android_packaged_resources/attrs.bzl
@@ -0,0 +1,69 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Attributes."""
+
+load(
+ "@rules_android//rules:attrs.bzl",
+ _attrs = "attrs",
+)
+
+ATTRS = _attrs.replace(
+ _attrs.add(
+ dict(
+ deps = attr.label_list(
+ allow_files = True,
+ allow_rules = [
+ "aar_import",
+ "android_library",
+ "cc_library",
+ "java_import",
+ "java_library",
+ "java_lite_proto_library",
+ ],
+ providers = [
+ [CcInfo],
+ [JavaInfo],
+ ["AndroidResourcesInfo", "AndroidAssetsInfo"],
+ ],
+ cfg = android_common.multi_cpu_configuration,
+ ),
+ enable_data_binding = attr.bool(),
+ instruments = attr.label(),
+ manifest_values = attr.string_dict(),
+ manifest_merger = attr.string(
+ default = "auto",
+ values = ["auto", "legacy", "android", "force_android"],
+ ),
+ native_target = attr.label(
+ allow_files = False,
+ allow_rules = ["android_binary", "android_test"],
+ ),
+ resource_configuration_filters = attr.string_list(),
+ densities = attr.string_list(),
+ nocompress_extensions = attr.string_list(),
+ shrink_resources = _attrs.tristate.create(
+ default = _attrs.tristate.auto,
+ ),
+ _defined_resource_files = attr.bool(default = False),
+ _enable_manifest_merging = attr.bool(default = True),
+ ),
+ _attrs.COMPILATION,
+ _attrs.DATA_CONTEXT,
+ ),
+ # TODO(b/167599192): don't override manifest attr to remove .xml file restriction.
+ manifest = attr.label(
+ allow_single_file = True,
+ ),
+)
diff --git a/rules/android_packaged_resources/impl.bzl b/rules/android_packaged_resources/impl.bzl
new file mode 100644
index 0000000..e3d6ac0
--- /dev/null
+++ b/rules/android_packaged_resources/impl.bzl
@@ -0,0 +1,111 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation."""
+
+load("@rules_android//rules:acls.bzl", "acls")
+load("@rules_android//rules:java.bzl", "java")
+load(
+ "@rules_android//rules:processing_pipeline.bzl",
+ "ProviderInfo",
+ "processing_pipeline",
+)
+load("@rules_android//rules:resources.bzl", _resources = "resources")
+load("@rules_android//rules:utils.bzl", "compilation_mode", "get_android_toolchain", "utils")
+
+def _process_resources(ctx, java_package, **unused_ctxs):
+ packaged_resources_ctx = _resources.package(
+ ctx,
+ assets = ctx.files.assets,
+ assets_dir = ctx.attr.assets_dir,
+ resource_files = ctx.files.resource_files,
+ manifest = ctx.file.manifest,
+ manifest_values = utils.expand_make_vars(ctx, ctx.attr.manifest_values),
+ resource_configs = ctx.attr.resource_configuration_filters,
+ densities = ctx.attr.densities,
+ nocompress_extensions = ctx.attr.nocompress_extensions,
+ java_package = java_package,
+ compilation_mode = compilation_mode.get(ctx),
+ shrink_resources = ctx.attr.shrink_resources,
+ use_android_resource_shrinking = ctx.fragments.android.use_android_resource_shrinking,
+ use_android_resource_cycle_shrinking = ctx.fragments.android.use_android_resource_cycle_shrinking,
+ use_legacy_manifest_merger = use_legacy_manifest_merger(ctx),
+ should_throw_on_conflict = not acls.in_allow_resource_conflicts(str(ctx.label)),
+ enable_data_binding = ctx.attr.enable_data_binding,
+ enable_manifest_merging = ctx.attr._enable_manifest_merging,
+ deps = ctx.attr.deps,
+ instruments = ctx.attr.instruments,
+ aapt = get_android_toolchain(ctx).aapt2.files_to_run,
+ android_jar = ctx.attr._android_sdk[AndroidSdkInfo].android_jar,
+ legacy_merger = ctx.attr._android_manifest_merge_tool.files_to_run,
+ xsltproc = ctx.attr._xsltproc_tool.files_to_run,
+ instrument_xslt = ctx.file._add_g3itr_xslt,
+ busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+ host_javabase = ctx.attr._host_javabase,
+ )
+ return ProviderInfo(
+ name = "packaged_resources_ctx",
+ value = packaged_resources_ctx,
+ )
+
+def use_legacy_manifest_merger(ctx):
+ """Whether legacy manifest merging is enabled.
+
+ Args:
+ ctx: The context.
+
+ Returns:
+ Boolean indicating whether legacy manifest merging is enabled.
+ """
+ manifest_merger = ctx.attr.manifest_merger
+ android_manifest_merger = ctx.fragments.android.manifest_merger
+
+ if android_manifest_merger == "force_android":
+ return False
+ if manifest_merger == "auto":
+ manifest_merger = android_manifest_merger
+
+ return manifest_merger == "legacy"
+
+def finalize(ctx, providers, validation_outputs, **unused_ctxs):
+ providers.append(
+ OutputGroupInfo(
+ _validation = depset(validation_outputs),
+ ),
+ )
+ return providers
+
+# Order dependent, as providers will not be available to downstream processors
+# that may depend on the provider. Iteration order for a dictionary is based on
+# insertion.
+PROCESSORS = dict(
+ ResourceProcessor = _process_resources,
+)
+
+_PROCESSING_PIPELINE = processing_pipeline.make_processing_pipeline(
+ processors = PROCESSORS,
+ finalize = finalize,
+)
+
+def impl(ctx):
+ """The rule implementation.
+
+ Args:
+ ctx: The context.
+
+ Returns:
+ A list of providers.
+ """
+ java_package = java.resolve_package_from_label(ctx.label, ctx.attr.custom_package)
+ return processing_pipeline.run(ctx, java_package, _PROCESSING_PIPELINE)
diff --git a/rules/android_packaged_resources/rule.bzl b/rules/android_packaged_resources/rule.bzl
new file mode 100644
index 0000000..db3f96a
--- /dev/null
+++ b/rules/android_packaged_resources/rule.bzl
@@ -0,0 +1,91 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Starlark Resource Packaging for Android Rules."""
+
+load(":attrs.bzl", "ATTRS")
+load(":impl.bzl", "impl")
+load(
+ "@rules_android//rules:attrs.bzl",
+ _attrs = "attrs",
+)
+
+_DEFAULT_ALLOWED_ATTRS = ["name", "visibility", "tags", "testonly", "transitive_configs", "$enable_manifest_merging"]
+
+_DEFAULT_PROVIDES = [AndroidApplicationResourceInfo, OutputGroupInfo]
+
+# TODO(b/167721629): Rename android_packaged_resources to android_binary_internal.
+def make_rule(
+ attrs = ATTRS,
+ implementation = impl,
+ provides = _DEFAULT_PROVIDES):
+ """Makes the rule.
+
+ Args:
+ attrs: A dict. The attributes for the rule.
+ implementation: A function. The rule's implementation method.
+ provides: A list. The providers that the rule must provide.
+
+ Returns:
+ A rule.
+ """
+ return rule(
+ attrs = attrs,
+ implementation = implementation,
+ provides = provides,
+ toolchains = ["@rules_android//toolchains/android:toolchain_type"],
+ _skylark_testable = True,
+ fragments = [
+ "android",
+ "java",
+ ],
+ )
+
+_android_packaged_resources = make_rule()
+
+def sanitize_attrs(attrs, allowed_attrs = ATTRS.keys()):
+ """Sanitizes the attributes.
+
+ The android_packaged_resources has a subset of the android_binary attributes, but is
+ called from the android_binary macro with the same full set of attributes. This removes
+ any unnecessary attributes.
+
+ Args:
+ attrs: A dict. The attributes for the android_packaged_resources rule.
+ allowed_attrs: The list of attribute keys to keep.
+
+ Returns:
+ A dictionary containing valid attributes.
+ """
+ for attr_name in attrs.keys():
+ if attr_name not in allowed_attrs and attr_name not in _DEFAULT_ALLOWED_ATTRS:
+ attrs.pop(attr_name, None)
+
+ # Some teams set this to a boolean/None which works for the native attribute but breaks
+ # the Starlark attribute.
+ if attr_name == "shrink_resources":
+ if attrs[attr_name] == None:
+ attrs.pop(attr_name, None)
+ else:
+ attrs[attr_name] = _attrs.tristate.normalize(attrs[attr_name])
+
+ return attrs
+
+def android_packaged_resources_macro(**attrs):
+ """android_packaged_resources rule.
+
+ Args:
+ **attrs: Rule attributes
+ """
+ _android_packaged_resources(**sanitize_attrs(attrs))
diff --git a/rules/android_sdk.bzl b/rules/android_sdk.bzl
new file mode 100644
index 0000000..cf824e1
--- /dev/null
+++ b/rules/android_sdk.bzl
@@ -0,0 +1,53 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android sdk."""
+
+load(":attrs.bzl", "ANDROID_SDK_ATTRS")
+
+def _impl(ctx):
+ proguard = ctx.attr._proguard if ctx.attr._proguard else ctx.attr.proguard
+ android_sdk_info = AndroidSdkInfo(
+ ctx.attr.build_tools_version,
+ ctx.file.framework_aidl,
+ ctx.attr.aidl_lib,
+ ctx.file.android_jar,
+ ctx.file.source_properties,
+ ctx.file.shrinked_android_jar,
+ ctx.file.main_dex_classes,
+ ctx.attr.adb.files_to_run,
+ ctx.attr.dx.files_to_run,
+ ctx.attr.main_dex_list_creator.files_to_run,
+ ctx.attr.aidl.files_to_run,
+ ctx.attr.aapt.files_to_run,
+ ctx.attr.aapt2.files_to_run,
+ ctx.attr.apkbuilder.files_to_run if ctx.attr.apkbuilder else None,
+ ctx.attr.apksigner.files_to_run,
+ proguard.files_to_run,
+ ctx.attr.zipalign.files_to_run,
+ # Passing the 'system' here is only necessary to support native android_binary.
+ # TODO(b/149114743): remove this after the migration to android_application.
+ ctx.attr._system[java_common.BootClassPathInfo] if ctx.attr._system and java_common.BootClassPathInfo in ctx.attr._system else None,
+ )
+ return [
+ android_sdk_info,
+ platform_common.ToolchainInfo(android_sdk_info = android_sdk_info),
+ ]
+
+android_sdk = rule(
+ attrs = ANDROID_SDK_ATTRS,
+ implementation = _impl,
+ fragments = ["java"],
+ provides = [AndroidSdkInfo],
+)
diff --git a/rules/android_sdk_repository.bzl b/rules/android_sdk_repository.bzl
new file mode 100644
index 0000000..f82f6e6
--- /dev/null
+++ b/rules/android_sdk_repository.bzl
@@ -0,0 +1,25 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android sdk repository."""
+
+def android_sdk_repository(**attrs):
+ """Bazel android_sdk_repository rule.
+
+ https://docs.bazel.build/versions/master/be/android.html#android_sdk_repository
+
+ Args:
+ **attrs: Rule attributes
+ """
+ native.android_sdk_repository(**attrs)
diff --git a/rules/android_tools_defaults_jar.bzl b/rules/android_tools_defaults_jar.bzl
new file mode 100644
index 0000000..b226882
--- /dev/null
+++ b/rules/android_tools_defaults_jar.bzl
@@ -0,0 +1,32 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android tools defaults jar."""
+
+load(":attrs.bzl", "ANDROID_TOOLS_DEFAULTS_JAR_ATTRS")
+load(":utils.bzl", "get_android_sdk")
+
+def _impl(ctx):
+ return [
+ DefaultInfo(
+ files = depset([get_android_sdk(ctx).android_jar]),
+ ),
+ ]
+
+android_tools_defaults_jar = rule(
+ attrs = ANDROID_TOOLS_DEFAULTS_JAR_ATTRS,
+ implementation = _impl,
+ fragments = ["android"],
+ toolchains = ["@rules_android//toolchains/android_sdk:toolchain_type"],
+)
diff --git a/rules/attrs.bzl b/rules/attrs.bzl
new file mode 100644
index 0000000..eca1947
--- /dev/null
+++ b/rules/attrs.bzl
@@ -0,0 +1,286 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Common attributes for Android rules."""
+
+load(":utils.bzl", "log")
+
+def _add(attrs, *others):
+ new = {}
+ new.update(attrs)
+ for o in others:
+ for name in o.keys():
+ if name in new:
+ log.error("Attr '%s' is defined twice." % name)
+ new[name] = o[name]
+ return new
+
+def _replace(attrs, **kwargs):
+ # Verify that new values are replacing existing ones, not adding.
+ for name in kwargs.keys():
+ if name not in attrs:
+ log.error("Attr '%s' is not defined, replacement failed." % name)
+ new = dict()
+ new.update(attrs)
+ new.update(kwargs)
+ return new
+
+def _make_tristate_attr(default, doc = "", mandatory = False):
+ return attr.int(
+ default = default,
+ doc = doc,
+ mandatory = mandatory,
+ values = [-1, 0, 1],
+ )
+
+def _normalize_tristate(attr_value):
+ """Normalizes the tristate value going into a rule.
+
+ This is required because "tristate" is not officially supported as an
+ attribute type. An equivalent attribute type is an in with a constrained
+ set of values, namely [-1, 0, 1]. Unfortunately, tristate accepts
+ multiple types, integers, booleans and strings ("auto"). As a result, this
+ method normalizes the inputs to an integer.
+
+ This method needs to be applied to attributes that were formally tristate
+ to normalize the inputs.
+ """
+ if type(attr_value) == "int":
+ return attr_value
+
+ if type(attr_value) == "string":
+ if attr_value.lower() == "auto":
+ return -1
+
+ if type(attr_value) == "bool":
+ return int(attr_value)
+
+ return attr_value # Return unknown type, let the rule fail.
+
+_tristate = struct(
+ create = _make_tristate_attr,
+ normalize = _normalize_tristate,
+ yes = 1,
+ no = 0,
+ auto = -1,
+)
+
+_JAVA_RUNTIME = dict(
+ _host_javabase = attr.label(
+ cfg = "host",
+ default = Label("@rules_android//rules:current_java_runtime"),
+ ),
+)
+
+
+# Android SDK attribute.
+_ANDROID_SDK = dict(
+ _android_sdk = attr.label(
+ allow_rules = ["android_sdk"],
+ default = configuration_field(
+ fragment = "android",
+ name = "android_sdk_label",
+ ),
+ providers = [AndroidSdkInfo],
+ ),
+)
+
+# Compilation attributes for Android rules.
+_COMPILATION = _add(
+ dict(
+ assets = attr.label_list(
+ allow_files = True,
+ cfg = "target",
+ ),
+ assets_dir = attr.string(),
+ custom_package = attr.string(),
+ manifest = attr.label(
+ allow_single_file = [".xml"],
+ ),
+ resource_files = attr.label_list(
+ allow_files = True,
+ ),
+ data = attr.label_list(
+ allow_files = True,
+ ),
+ plugins = attr.label_list(
+ allow_rules = ["java_plugin"],
+ cfg = "host",
+ ),
+ javacopts = attr.string_list(),
+ # TODO: Expose getPlugins() in JavaConfiguration.java
+ # com/google/devtools/build/lib/rules/java/JavaConfiguration.java
+ # com/google/devtools/build/lib/rules/java/JavaOptions.java
+ #
+ # _java_plugins = attr.label(
+ # allow_rules = ["java_plugin"],
+ # default = configuration_field(
+ # fragment = "java",
+ # name = "plugin",
+ # ),
+ # ),
+ ),
+ _JAVA_RUNTIME,
+)
+
+# Attributes for rules that use the AndroidDataContext android_data.make_context
+_DATA_CONTEXT = _add(
+ dict(
+ # Additional attrs needed for AndroidDataContext
+ _add_g3itr_xslt = attr.label(
+ cfg = "host",
+ default = Label("//tools/android/xslt:add_g3itr.xslt"),
+ allow_single_file = True,
+ ),
+ _android_manifest_merge_tool = attr.label(
+ cfg = "host",
+ default = Label("//tools/android:merge_manifests"),
+ executable = True,
+ ),
+ # TODO(b/145617058) Switching back to head RPBB until the Android rules release process is improved
+ _android_resources_busybox = attr.label(
+ cfg = "host",
+ default = Label("@rules_android//rules:ResourceProcessorBusyBox"),
+ executable = True,
+ ),
+ _xsltproc_tool = attr.label(
+ cfg = "host",
+ default = Label("//tools/android/xslt:xslt"),
+ allow_files = True,
+ ),
+ ),
+ _ANDROID_SDK,
+)
+
+
+
+
+
+
+
+ANDROID_SDK_ATTRS = dict(
+ aapt = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ aapt2 = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ executable = True,
+ ),
+ aidl = attr.label(
+ allow_files = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ aidl_lib = attr.label(
+ allow_files = [".jar"],
+ ),
+ android_jar = attr.label(
+ allow_single_file = [".jar"],
+ cfg = "host",
+ mandatory = True,
+ ),
+ annotations_jar = attr.label(
+ allow_single_file = [".jar"],
+ cfg = "host",
+ ),
+ apkbuilder = attr.label(
+ allow_files = True,
+ cfg = "host",
+ executable = True,
+ ),
+ apksigner = attr.label(
+ allow_files = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ adb = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ build_tools_version = attr.string(),
+ dx = attr.label(
+ allow_files = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ framework_aidl = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ mandatory = True,
+ ),
+ main_dex_classes = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ mandatory = True,
+ ),
+ main_dex_list_creator = attr.label(
+ allow_files = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ proguard = attr.label(
+ allow_files = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ shrinked_android_jar = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ mandatory = True,
+ ),
+ source_properties = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ ),
+ zipalign = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ executable = True,
+ mandatory = True,
+ ),
+ _proguard = attr.label(
+ cfg = "host",
+ default = configuration_field(
+ fragment = "java",
+ name = "proguard_top",
+ ),
+ ),
+ _system = attr.label(
+ default = Label("//tools/android:bootclasspath_android_only"),
+ ),
+)
+
+ANDROID_TOOLS_DEFAULTS_JAR_ATTRS = _add(_ANDROID_SDK)
+
+
+attrs = struct(
+ ANDROID_SDK = _ANDROID_SDK,
+ COMPILATION = _COMPILATION,
+ DATA_CONTEXT = _DATA_CONTEXT,
+ JAVA_RUNTIME = _JAVA_RUNTIME,
+ tristate = _tristate,
+ add = _add,
+ replace = _replace,
+)
diff --git a/rules/busybox.bzl b/rules/busybox.bzl
new file mode 100644
index 0000000..f0d78ac
--- /dev/null
+++ b/rules/busybox.bzl
@@ -0,0 +1,1033 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel ResourcesBusyBox Commands."""
+
+load(":java.bzl", _java = "java")
+
+_ANDROID_RESOURCES_STRICT_DEPS = "android_resources_strict_deps"
+
+def _sanitize_assets_dir(assets_dir):
+ sanitized_assets_dir = "/".join(
+ [
+ part
+ for part in assets_dir.split("/")
+ if part != "" and part != "."
+ ],
+ )
+
+ return "/" + sanitized_assets_dir if assets_dir.startswith("/") else sanitized_assets_dir
+
+def _get_unique_assets_dirs(assets, assets_dir):
+ """Find the unique assets directories, partitioned by assets_dir.
+
+ Args:
+ assets: A list of Files. List of asset files to process.
+ assets_dir: String. String giving the path to the files in assets.
+
+ Returns:
+ A list of short_paths representing unique asset dirs.
+ """
+ if not assets:
+ return []
+
+ dirs = dict()
+
+ assets_dir = _sanitize_assets_dir(assets_dir)
+ if assets_dir:
+ partition_by = "/%s/" % assets_dir.strip("/")
+ for f in assets:
+ if f.is_directory and f.path.endswith(partition_by[:-1]):
+ # If f is a directory, check if its path ends with the assets_dir.
+ dirs[f.path] = True
+ elif f.is_directory and "_aar/unzipped" in f.path:
+ # Assets from an aar_import rule are extracted in a
+ # "assets" subdirectory of the given path
+ dirs["%s/assets" % f.path] = True
+ else:
+ # Partition to remove subdirectories beneath assets_dir
+ # Also removes the trailing /
+ dirs["".join(f.path.rpartition(partition_by)[:2])[:-1]] = True
+ else:
+ # Use the dirname of the generating target if no assets_dir.
+ for f in assets:
+ if f.is_source:
+ dirs[f.owner.package] = True
+ else:
+ # Prepend the root path for generated files.
+ dirs[f.root.path + "/" + f.owner.package] = True
+ return dirs.keys()
+
+def _get_unique_res_dirs(resource_files):
+ """Find the unique res dirs.
+
+ Args:
+ resource_files: A list of Files. A list of resource_files.
+
+ Returns:
+ A list of short_paths representing unique res dirs from the given resource files.
+ """
+ dirs = dict()
+ for f in resource_files:
+ if f.is_directory:
+ dirs[f.path] = True
+ else:
+ dirs[f.dirname.rpartition("/" + f.dirname.split("/")[-1])[0]] = True
+ return dirs.keys()
+
+def _make_serialized_resources_flag(
+ assets = [],
+ assets_dir = None,
+ resource_files = [],
+ label = "",
+ symbols = None):
+ return ";".join(
+ [
+ "#".join(_get_unique_res_dirs(resource_files)),
+ "#".join(_get_unique_assets_dirs(assets, assets_dir)),
+ label,
+ symbols.path if symbols else "",
+ ],
+ ).rstrip(":")
+
+def _make_resources_flag(
+ assets = [],
+ assets_dir = None,
+ resource_files = [],
+ manifest = None,
+ r_txt = None,
+ symbols = None):
+ return ":".join(
+ [
+ "#".join(_get_unique_res_dirs(resource_files)),
+ "#".join(_get_unique_assets_dirs(assets, assets_dir)),
+ manifest.path if manifest else "",
+ r_txt.path if r_txt else "",
+ symbols.path if symbols else "",
+ ],
+ )
+
+def _path(f):
+ return f.path
+
+def _make_package_resources_flags(resources_node):
+ if not (resources_node.manifest and resources_node.r_txt and resources_node.compiled_resources):
+ return None
+ flag = _make_resources_flag(
+ resource_files = resources_node.resource_files.to_list(),
+ assets = resources_node.assets.to_list(),
+ assets_dir = resources_node.assets_dir,
+ manifest = resources_node.manifest,
+ r_txt = resources_node.r_txt,
+ symbols = resources_node.compiled_resources,
+ )
+ return flag
+
+def _make_package_assets_flags(resources_node):
+ assets = resources_node.assets.to_list()
+ if not assets:
+ return None
+ return _make_serialized_resources_flag(
+ assets = assets,
+ assets_dir = resources_node.assets_dir,
+ label = str(resources_node.label),
+ symbols = resources_node.compiled_assets,
+ )
+
+def _extract_filters(
+ raw_list):
+ """Extract densities and resource_configuration filters from raw string lists.
+
+ In BUILD files, string lists can be represented as a list of strings, a single comma-separated
+ string, or a combination of both. This method outputs a single list of individual string values,
+ which can then be passed directly to resource processing actions. Empty strings are removed and
+ the final list is sorted.
+
+ Args:
+ raw_list: List of strings. The raw densities or resource configuration filters.
+
+ Returns:
+ List of strings extracted from the raw list.
+ """
+ out_filters = []
+ for item in raw_list:
+ if "," in item:
+ item_list = item.split(",")
+ for entry in item_list:
+ stripped_entry = entry.strip()
+ if stripped_entry:
+ out_filters.append(stripped_entry)
+ elif item:
+ out_filters.append(item)
+ return sorted(out_filters)
+
+def _package(
+ ctx,
+ out_r_src_jar = None,
+ out_r_txt = None,
+ out_symbols = None,
+ out_manifest = None,
+ out_proguard_cfg = None,
+ out_main_dex_proguard_cfg = None,
+ out_resource_files_zip = None,
+ out_file = None,
+ package_type = None,
+ java_package = None,
+ manifest = None,
+ assets = [],
+ assets_dir = None,
+ resource_files = [],
+ resource_configs = None,
+ densities = [],
+ application_id = None,
+ direct_resources_nodes = [],
+ transitive_resources_nodes = [],
+ transitive_manifests = [],
+ transitive_assets = [],
+ transitive_compiled_assets = [],
+ transitive_resource_files = [],
+ transitive_compiled_resources = [],
+ transitive_r_txts = [],
+ additional_apks_to_link_against = [],
+ nocompress_extensions = [],
+ proto_format = False,
+ version_name = None,
+ version_code = None,
+ android_jar = None,
+ aapt = None,
+ busybox = None,
+ host_javabase = None,
+ should_throw_on_conflict = True, # TODO: read this from allowlist at caller
+ debug = True): # TODO: we will set this to false in prod builds
+ """Packages the compiled Android Resources with AAPT.
+
+ Args:
+ ctx: The context.
+ out_r_src_jar: A File. The R.java outputted by linking resources in a srcjar.
+ out_r_txt: A File. The resource IDs outputted by linking resources in text.
+ out_symbols: A File. The output zip containing compiled resources.
+ out_manifest: A File. The output processed manifest.
+ out_proguard_cfg: A File. The proguard config to be generated.
+ out_main_dex_proguard_cfg: A File. The main dex proguard config to be generated.
+ out_resource_files_zip: A File. The resource files zipped by linking resources.
+ out_file: A File. The Resource APK outputted by linking resources.
+ package_type: A string. The configuration type to use when packaging.
+ java_package: A string. The Java package for the generated R.java.
+ manifest: A File. The AndroidManifest.xml.
+ assets: sequence of Files. A list of Android assets files to be processed.
+ assets_dir: String. The name of the assets directory.
+ resource_files: A list of Files. The resource files.
+ resource_configs: A list of strings. The list of resource configuration
+ filters.
+ densities: A list of strings. The list of screen densities to filter for when
+ building the apk.
+ application_id: An optional string. The applicationId set in manifest values.
+ direct_resources_nodes: Depset of ResourcesNodeInfo providers. The set of
+ ResourcesNodeInfo from direct dependencies.
+ transitive_resources_nodes: Depset of ResourcesNodeInfo providers. The set
+ of ResourcesNodeInfo from transitive dependencies (not including directs).
+ transitive_manifests: List of Depsets. Depsets contain all transitive manifests.
+ transitive_assets: List of Depsets. Depsets contain all transitive assets.
+ transitive_compiled_assets: List of Depsets. Depsets contain all transitive
+ compiled_assets.
+ transitive_resource_files: List of Depsets. Depsets contain all transitive
+ resource files.
+ transitive_compiled_resources: List of Depsets. Depsets contain all transitive
+ compiled_resources.
+ transitive_r_txts: List of Depsets. Depsets contain all transitive R txt files.
+ additional_apks_to_link_against: A list of Files. Additional APKs to link
+ against. Optional.
+ nocompress_extensions: A list of strings. File extension to leave uncompressed
+ in the apk.
+ proto_format: Boolean, whether to generate the resource table in proto format.
+ version_name: A string. The version name to stamp the generated manifest with. Optional.
+ version_code: A string. The version code to stamp the generated manifest with. Optional.
+ android_jar: A File. The Android Jar.
+ aapt: A FilesToRunProvider. The AAPT executable.
+ busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+ host_javabase: Target. The host javabase.
+ should_throw_on_conflict: A boolean. Determines whether an error should be thrown
+ when a resource conflict occurs.
+ debug: A boolean. Determines whether to enable debugging.
+ """
+ if not manifest:
+ fail("No manifest given, the manifest is mandatory.")
+
+ direct_data_flag = []
+ direct_compiled_resources = []
+
+ output_files = []
+ input_files = []
+ transitive_input_files = []
+
+ args = ctx.actions.args()
+ args.use_param_file("@%s")
+ args.add("--tool", "AAPT2_PACKAGE")
+ args.add("--")
+ args.add("--aapt2", aapt.executable)
+ args.add_joined(
+ "--data",
+ transitive_resources_nodes,
+ map_each = _make_package_resources_flags,
+ join_with = ",",
+ )
+ args.add_joined(
+ "--directData",
+ direct_resources_nodes,
+ map_each = _make_package_resources_flags,
+ join_with = ",",
+ )
+ args.add_joined(
+ "--directAssets",
+ direct_resources_nodes,
+ map_each = _make_package_assets_flags,
+ join_with = "&",
+ omit_if_empty = True,
+ )
+ args.add_joined(
+ "--assets",
+ transitive_resources_nodes,
+ map_each = _make_package_assets_flags,
+ join_with = "&",
+ omit_if_empty = True,
+ )
+ transitive_input_files.extend(transitive_resource_files)
+ transitive_input_files.extend(transitive_assets)
+ transitive_input_files.extend(transitive_compiled_assets)
+ transitive_input_files.extend(transitive_compiled_resources)
+ transitive_input_files.extend(transitive_manifests)
+ transitive_input_files.extend(transitive_r_txts)
+ args.add(
+ "--primaryData",
+ _make_resources_flag(
+ manifest = manifest,
+ assets = assets,
+ assets_dir = assets_dir,
+ resource_files = resource_files,
+ ),
+ )
+ input_files.append(manifest)
+ input_files.extend(resource_files)
+ input_files.extend(assets)
+ args.add("--androidJar", android_jar)
+ input_files.append(android_jar)
+ args.add("--rOutput", out_r_txt)
+ output_files.append(out_r_txt)
+ if out_symbols:
+ args.add("--symbolsOut", out_symbols)
+ output_files.append(out_symbols)
+ args.add("--srcJarOutput", out_r_src_jar)
+ output_files.append(out_r_src_jar)
+ if out_proguard_cfg:
+ args.add("--proguardOutput", out_proguard_cfg)
+ output_files.append(out_proguard_cfg)
+ if out_main_dex_proguard_cfg:
+ args.add("--mainDexProguardOutput", out_main_dex_proguard_cfg)
+ output_files.append(out_main_dex_proguard_cfg)
+ args.add("--manifestOutput", out_manifest)
+ output_files.append(out_manifest)
+ if out_resource_files_zip:
+ args.add("--resourcesOutput", out_resource_files_zip)
+ output_files.append(out_resource_files_zip)
+ if out_file:
+ args.add("--packagePath", out_file)
+ output_files.append(out_file)
+ args.add("--useAaptCruncher=no") # Unnecessary, used for AAPT1 only but added here to minimize diffs.
+ if package_type:
+ args.add("--packageType", package_type)
+ if debug:
+ args.add("--debug")
+ if should_throw_on_conflict:
+ args.add("--throwOnResourceConflict")
+ if resource_configs:
+ args.add_joined("--resourceConfigs", _extract_filters(resource_configs), join_with = ",")
+ if densities:
+ args.add_joined("--densities", _extract_filters(densities), join_with = ",")
+ if application_id:
+ args.add("--applicationId", application_id)
+ if additional_apks_to_link_against:
+ args.add_joined(
+ "--additionalApksToLinkAgainst",
+ additional_apks_to_link_against,
+ join_with = ",",
+ map_each = _path,
+ )
+ input_files.extend(additional_apks_to_link_against)
+ if nocompress_extensions:
+ args.add_joined("--uncompressedExtensions", nocompress_extensions, join_with = ",")
+ if proto_format:
+ args.add("--resourceTableAsProto")
+ if version_name:
+ args.add("--versionName", version_name)
+ if version_code:
+ args.add("--versionCode", version_code)
+ args.add("--packageForR", java_package)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ tools = [aapt],
+ arguments = [args],
+ inputs = depset(input_files, transitive = transitive_input_files),
+ outputs = output_files,
+ mnemonic = "PackageAndroidResources",
+ progress_message = "Packaging Android Resources in %s" % ctx.label,
+ )
+
+def _parse(
+ ctx,
+ out_symbols = None,
+ assets = [],
+ assets_dir = None,
+ busybox = None,
+ host_javabase = None):
+ """Parses Android assets.
+
+ Args:
+ ctx: The context.
+ out_symbols: A File. The output bin containing parsed assets.
+ assets: sequence of Files. A list of Android assets files to be processed.
+ assets_dir: String. The name of the assets directory.
+ busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+ host_javabase: Target. The host javabase.
+ """
+ args = ctx.actions.args()
+ args.use_param_file("@%s")
+ args.add("--tool", "PARSE")
+ args.add("--")
+ args.add(
+ "--primaryData",
+ _make_resources_flag(
+ assets = assets,
+ assets_dir = assets_dir,
+ ),
+ )
+ args.add("--output", out_symbols)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ arguments = [args],
+ inputs = assets,
+ outputs = [out_symbols],
+ mnemonic = "ParseAndroidResources",
+ progress_message = "Parsing Android Resources in %s" % out_symbols.short_path,
+ )
+
+def _make_merge_assets_flags(resources_node):
+ assets = resources_node.assets.to_list()
+ if not (assets or resources_node.assets_dir):
+ return None
+ return _make_serialized_resources_flag(
+ assets = assets,
+ assets_dir = resources_node.assets_dir,
+ label = str(resources_node.label),
+ symbols = resources_node.assets_symbols,
+ )
+
+def _merge_assets(
+ ctx,
+ out_assets_zip = None,
+ assets = [],
+ assets_dir = None,
+ symbols = None,
+ transitive_assets = [],
+ transitive_assets_symbols = [],
+ direct_resources_nodes = [],
+ transitive_resources_nodes = [],
+ busybox = None,
+ host_javabase = None):
+ """Merges Android assets.
+
+ Args:
+ ctx: The context.
+ out_assets_zip: A File.
+ assets: sequence of Files. A list of Android assets files to be processed.
+ assets_dir: String. The name of the assets directory.
+ symbols: A File. The parsed assets.
+ transitive_assets: Sequence of Depsets. The list of transitive
+ assets from deps.
+ transitive_assets_symbols: Sequence of Depsets. The list of
+ transitive assets_symbols files from deps.
+ direct_resources_nodes: Sequence of ResourcesNodeInfo providers. The list
+ of ResourcesNodeInfo providers that are direct depencies.
+ transitive_resources_nodes: Sequence of ResourcesNodeInfo providers. The
+ list of ResourcesNodeInfo providers that are transitive depencies.
+ busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+ host_javabase: Target. The host javabase.
+ """
+ args = ctx.actions.args()
+ args.use_param_file("@%s")
+ args.add("--tool", "MERGE_ASSETS")
+ args.add("--")
+ args.add("--assetsOutput", out_assets_zip)
+ args.add(
+ "--primaryData",
+ _make_serialized_resources_flag(
+ assets = assets,
+ assets_dir = assets_dir,
+ label = str(ctx.label),
+ symbols = symbols,
+ ),
+ )
+ args.add_joined(
+ "--directData",
+ direct_resources_nodes,
+ map_each = _make_merge_assets_flags,
+ join_with = "&",
+ )
+ args.add_joined(
+ "--data",
+ transitive_resources_nodes,
+ map_each = _make_merge_assets_flags,
+ join_with = "&",
+ )
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ arguments = [args],
+ inputs = depset(
+ assets + [symbols],
+ transitive = transitive_assets + transitive_assets_symbols,
+ ),
+ outputs = [out_assets_zip],
+ mnemonic = "MergeAndroidAssets",
+ progress_message =
+ "Merging Android Assets in %s" % out_assets_zip.short_path,
+ )
+
+def _validate_and_link(
+ ctx,
+ out_r_src_jar = None,
+ out_r_txt = None,
+ out_file = None,
+ compiled_resources = None,
+ transitive_compiled_resources = depset(),
+ java_package = None,
+ manifest = None,
+ android_jar = None,
+ busybox = None,
+ host_javabase = None,
+ aapt = None):
+ """Links compiled Android Resources with AAPT.
+
+ Args:
+ ctx: The context.
+ out_r_src_jar: A File. The R.java outputted by linking resources in a srcjar.
+ out_r_txt: A File. The resource IDs outputted by linking resources in text.
+ out_file: A File. The Resource APK outputted by linking resources.
+ compiled_resources: A File. The symbols.zip of compiled resources for
+ this target.
+ transitive_compiled_resources: Depset of Files. The symbols.zip of the
+ compiled resources from the transitive dependencies of this target.
+ java_package: A string. The Java package for the generated R.java.
+ manifest: A File. The AndroidManifest.xml.
+ android_jar: A File. The Android Jar.
+ busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+ host_javabase: Target. The host javabase.
+ aapt: A FilesToRunProvider. The AAPT executable.
+ """
+ output_files = []
+ input_files = [android_jar]
+ transitive_input_files = []
+
+ # Retrieves the list of files at runtime when a directory is passed.
+ args = ctx.actions.args()
+ args.use_param_file("@%s")
+ args.add("--tool", "LINK_STATIC_LIBRARY")
+ args.add("--")
+ args.add("--aapt2", aapt.executable)
+ args.add("--libraries", android_jar)
+ if compiled_resources:
+ args.add("--compiled", compiled_resources)
+ input_files.append(compiled_resources)
+ args.add_joined(
+ "--compiledDep",
+ transitive_compiled_resources,
+ join_with = ":",
+ )
+ transitive_input_files.append(transitive_compiled_resources)
+ args.add("--manifest", manifest)
+ input_files.append(manifest)
+ if java_package:
+ args.add("--packageForR", java_package)
+ args.add("--sourceJarOut", out_r_src_jar)
+ output_files.append(out_r_src_jar)
+ args.add("--rTxtOut", out_r_txt)
+ output_files.append(out_r_txt)
+ args.add("--staticLibraryOut", out_file)
+ output_files.append(out_file)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ tools = [aapt],
+ arguments = [args],
+ inputs = depset(input_files, transitive = transitive_input_files),
+ outputs = output_files,
+ mnemonic = "LinkAndroidResources",
+ progress_message =
+ "Linking Android Resources in " + out_file.short_path,
+ )
+
+def _compile(
+ ctx,
+ out_file = None,
+ assets = [],
+ assets_dir = None,
+ resource_files = [],
+ busybox = None,
+ aapt = None,
+ host_javabase = None):
+ """Compile and store resources in a single archive.
+
+ Args:
+ ctx: The context.
+ out_file: File. The output zip containing compiled resources.
+ resource_files: A list of Files. The list of resource files or directories
+ assets: A list of Files. The list of assets files or directories
+ to process.
+ assets_dir: String. The name of the assets directory.
+ busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+ aapt: AAPT. Tool for compiling resources.
+ host_javabase: Target. The host javabase.
+ """
+ if not out_file:
+ fail("No output directory specified.")
+
+ # Retrieves the list of files at runtime when a directory is passed.
+ args = ctx.actions.args()
+ args.use_param_file("@%s")
+ args.add("--tool", "COMPILE_LIBRARY_RESOURCES")
+ args.add("--")
+ args.add("--aapt2", aapt.executable)
+ args.add(
+ "--resources",
+ _make_resources_flag(
+ resource_files = resource_files,
+ assets = assets,
+ assets_dir = assets_dir,
+ ),
+ )
+ args.add("--output", out_file)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ tools = [aapt],
+ arguments = [args],
+ inputs = resource_files + assets,
+ outputs = [out_file],
+ mnemonic = "CompileAndroidResources",
+ progress_message = "Compiling Android Resources in %s" % out_file.short_path,
+ )
+
+def _make_merge_compiled_flags(resources_node_info):
+ if not resources_node_info.compiled_resources:
+ return None
+ return _make_serialized_resources_flag(
+ label = str(resources_node_info.label),
+ symbols = resources_node_info.compiled_resources,
+ )
+
+def _merge_compiled(
+ ctx,
+ out_class_jar = None,
+ out_manifest = None,
+ out_aapt2_r_txt = None,
+ java_package = None,
+ manifest = None,
+ compiled_resources = None,
+ direct_resources_nodes = [],
+ transitive_resources_nodes = [],
+ direct_compiled_resources = depset(),
+ transitive_compiled_resources = depset(),
+ android_jar = None,
+ busybox = None,
+ host_javabase = None):
+ """Merges the compile resources.
+
+ Args:
+ ctx: The context.
+ out_class_jar: A File. The compiled R.java outputted by linking resources.
+ out_manifest: A File. The list of resource files or directories
+ out_aapt2_r_txt: A File. The resource IDs outputted by linking resources in text.
+ java_package: A string. The Java package for the generated R.java.
+ manifest: A File. The AndroidManifest.xml.
+ compiled_resources: A File. The symbols.zip of compiled resources for this target.
+ direct_resources_nodes: Sequence of ResourcesNodeInfo providers. The list
+ of ResourcesNodeInfo providers that are direct depencies.
+ transitive_resources_nodes: Sequence of ResourcesNodeInfo providers. The
+ list of ResourcesNodeInfo providers that are transitive depencies.
+ direct_compiled_resources: Depset of Files. A depset of symbols.zip of
+ compiled resources from direct dependencies.
+ transitive_compiled_resources: Depset of Files. A depset of symbols.zip of
+ compiled resources from transitive dependencies.
+ android_jar: A File. The Android Jar.
+ busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+ host_javabase: Target. The host javabase.
+ """
+ output_files = []
+ input_files = [android_jar]
+ transitive_input_files = []
+
+ args = ctx.actions.args()
+ args.use_param_file("@%s")
+ args.add("--tool", "MERGE_COMPILED")
+ args.add("--")
+ args.add("--classJarOutput", out_class_jar)
+ output_files.append(out_class_jar)
+ args.add("--targetLabel", ctx.label)
+ args.add("--manifestOutput", out_manifest)
+ output_files.append(out_manifest)
+ args.add("--rTxtOut", out_aapt2_r_txt)
+ output_files.append(out_aapt2_r_txt)
+ args.add("--androidJar", android_jar)
+ args.add("--primaryManifest", manifest)
+ input_files.append(manifest)
+ if java_package:
+ args.add("--packageForR", java_package)
+ args.add(
+ "--primaryData",
+ _make_serialized_resources_flag(
+ label = str(ctx.label),
+ symbols = compiled_resources,
+ ),
+ )
+ input_files.append(compiled_resources)
+ args.add_joined(
+ "--directData",
+ direct_resources_nodes,
+ map_each = _make_merge_compiled_flags,
+ join_with = "&",
+ )
+ transitive_input_files.append(direct_compiled_resources)
+ if _ANDROID_RESOURCES_STRICT_DEPS in ctx.disabled_features:
+ args.add_joined(
+ "--data",
+ transitive_resources_nodes,
+ map_each = _make_merge_compiled_flags,
+ join_with = "&",
+ )
+ transitive_input_files.append(transitive_compiled_resources)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ arguments = [args],
+ inputs = depset(input_files, transitive = transitive_input_files),
+ outputs = output_files,
+ mnemonic = "StarlarkMergeCompiledAndroidResources",
+ progress_message =
+ "Merging compiled Android Resources in " + out_class_jar.short_path,
+ )
+
+def _escape_mv(s):
+ """Escapes `:` and `,` in manifest values so they can be used as a busybox flag."""
+ return s.replace(":", "\\:").replace(",", "\\,")
+
+def _owner_label(file):
+ return "//" + file.owner.package + ":" + file.owner.name
+
+# We need to remove the "/_migrated/" path segment from file paths in order for sorting to
+# match the order of the native manifest merging action.
+def _manifest_short_path(manifest):
+ return manifest.short_path.replace("/_migrated/", "/")
+
+def _mergee_manifests_flag(manifests):
+ ordered_manifests = sorted(manifests.to_list(), key = _manifest_short_path)
+ entries = []
+ for manifest in ordered_manifests:
+ label = _owner_label(manifest).replace(":", "\\:")
+ entries.append((manifest.path + ":" + label).replace(",", "\\,"))
+ flag_entry = ",".join(entries)
+ if not flag_entry:
+ return None
+ return flag_entry
+
+def _merge_manifests(
+ ctx,
+ out_file = None,
+ out_log_file = None,
+ merge_type = "APPLICATION",
+ manifest = None,
+ mergee_manifests = depset(),
+ manifest_values = None,
+ java_package = None,
+ busybox = None,
+ host_javabase = None):
+ """Merge multiple AndroidManifest.xml files into a single one.
+
+ Args:
+ ctx: The context.
+ out_file: A File. The output merged manifest.
+ out_log_file: A File. The output log from the merge tool.
+ merge_type: A string, either APPLICATION or LIBRARY. Type of merging.
+ manifest: A File. The primary AndroidManifest.xml.
+ mergee_manifests: A depset of Files. All transitive manifests to be merged.
+ manifest_values: A dictionary. Manifest values to substitute.
+ java_package: A string. Custom java package to insert in manifest package attribute.
+ busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+ host_javabase: Target. The host javabase.
+ """
+ if merge_type not in ["APPLICATION", "LIBRARY"]:
+ fail("Unexpected manifest merge type: " + merge_type)
+
+ outputs = [out_file]
+ directs = [manifest]
+ transitives = [mergee_manifests]
+
+ # Args for busybox
+ args = ctx.actions.args()
+ args.use_param_file("@%s", use_always = True)
+ args.add("--tool", "MERGE_MANIFEST")
+ args.add("--")
+ args.add("--manifest", manifest)
+ args.add_all(
+ "--mergeeManifests",
+ [mergee_manifests],
+ map_each = _mergee_manifests_flag,
+ )
+ if manifest_values:
+ args.add(
+ "--manifestValues",
+ ",".join(["%s:%s" % (_escape_mv(k), _escape_mv(v)) for k, v in manifest_values.items()]),
+ )
+ args.add("--mergeType", merge_type)
+ args.add("--customPackage", java_package)
+ args.add("--manifestOutput", out_file)
+ if out_log_file:
+ args.add("--log", out_log_file)
+ outputs.append(out_log_file)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ arguments = [args],
+ inputs = depset(directs, transitive = transitives),
+ outputs = outputs,
+ mnemonic = "MergeManifests",
+ progress_message = "Merging Android Manifests in %s" % out_file.short_path,
+ )
+
+def _process_databinding(
+ ctx,
+ out_databinding_info = None,
+ out_databinding_processed_resources = None,
+ databinding_resources_dirname = None,
+ resource_files = None,
+ java_package = None,
+ busybox = None,
+ host_javabase = None):
+ """Processes databinding for android_binary.
+
+ Processes databinding declarations over resources, populates the databinding layout
+ info file, and generates new resources with databinding expressions stripped out.
+
+ Args:
+ ctx: The context.
+ out_databinding_info: File. The output databinding layout info zip file.
+ out_databinding_processed_resources: List of Files. The generated databinding
+ processed resource files.
+ databinding_resources_dirname: String. The execution path to the directory where
+ the out_databinding_processed_resources are generated.
+ resource_files: List of Files. The resource files to be processed.
+ java_package: String. Java package for which java sources will be
+ generated. By default the package is inferred from the directory where
+ the BUILD file containing the rule is.
+ busybox: FilesToRunProvider. The ResourceBusyBox executable or
+ FilesToRunprovider
+ host_javabase: A Target. The host javabase.
+ """
+ res_dirs = _get_unique_res_dirs(resource_files)
+
+ args = ctx.actions.args()
+ args.add("--tool", "PROCESS_DATABINDING")
+ args.add("--")
+ args.add("--output_resource_directory", databinding_resources_dirname)
+ args.add_all(res_dirs, before_each = "--resource_root")
+ args.add("--dataBindingInfoOut", out_databinding_info)
+ args.add("--appId", java_package)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ arguments = [args],
+ inputs = resource_files,
+ outputs = [out_databinding_info] + out_databinding_processed_resources,
+ mnemonic = "StarlarkProcessDatabinding",
+ progress_message = "Processing data binding",
+ )
+
+def _make_generate_binay_r_flags(resources_node):
+ if not (resources_node.r_txt or resources_node.manifest):
+ return None
+ return ",".join(
+ [
+ resources_node.r_txt.path if resources_node.r_txt else "",
+ resources_node.manifest.path if resources_node.manifest else "",
+ ],
+ )
+
+def _generate_binary_r(
+ ctx,
+ out_class_jar = None,
+ r_txt = None,
+ manifest = None,
+ package_for_r = None,
+ final_fields = None,
+ resources_nodes = depset(),
+ transitive_r_txts = [],
+ transitive_manifests = [],
+ busybox = None,
+ host_javabase = None):
+ """Generate compiled resources class jar.
+
+ Args:
+ ctx: The context.
+ out_class_jar: File. The output class jar file.
+ r_txt: File. The resource IDs outputted by linking resources in text.
+ manifest: File. The primary AndroidManifest.xml.
+ package_for_r: String. The Java package for the generated R class files.
+ final_fields: Bool. Whether fields get declared as final.
+ busybox: FilesToRunProvider. The ResourceBusyBox executable or
+ FilesToRunprovider
+ host_javabase: A Target. The host javabase.
+ """
+ args = ctx.actions.args()
+ args.add("--tool", "GENERATE_BINARY_R")
+ args.add("--")
+ args.add("--primaryRTxt", r_txt)
+ args.add("--primaryManifest", manifest)
+ args.add("--packageForR", package_for_r)
+ args.add_all(
+ resources_nodes,
+ map_each = _make_generate_binay_r_flags,
+ before_each = "--library",
+ )
+ if final_fields:
+ args.add("--finalFields")
+ else:
+ args.add("--nofinalFields")
+
+ # TODO(b/154003916): support transitive "--library transitive_r_txt_path,transitive_manifest_path" flags
+ args.add("--classJarOutput", out_class_jar)
+ args.add("--targetLabel", str(ctx.label))
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ arguments = [args],
+ inputs = depset([r_txt, manifest], transitive = transitive_r_txts + transitive_manifests),
+ outputs = [out_class_jar],
+ mnemonic = "StarlarkRClassGenerator",
+ progress_message = "Generating R classes",
+ )
+
+def _make_aar(
+ ctx,
+ out_aar = None,
+ assets = [],
+ assets_dir = None,
+ resource_files = [],
+ class_jar = None,
+ r_txt = None,
+ manifest = None,
+ proguard_specs = [],
+ should_throw_on_conflict = False,
+ busybox = None,
+ host_javabase = None):
+ """Generate an android archive file.
+
+ Args:
+ ctx: The context.
+ out_aar: File. The output AAR file.
+ assets: sequence of Files. A list of Android assets files to be processed.
+ assets_dir: String. The name of the assets directory.
+ resource_files: A list of Files. The resource files.
+ class_jar: File. The class jar file.
+ r_txt: File. The resource IDs outputted by linking resources in text.
+ manifest: File. The primary AndroidManifest.xml.
+ proguard_specs: List of File. The proguard spec files.
+ busybox: FilesToRunProvider. The ResourceBusyBox executable or
+ FilesToRunprovider
+ host_javabase: A Target. The host javabase.
+ should_throw_on_conflict: A boolean. Determines whether an error should be thrown
+ when a resource conflict occurs.
+ """
+ args = ctx.actions.args()
+ args.add("--tool", "GENERATE_AAR")
+ args.add("--")
+ args.add(
+ "--mainData",
+ _make_resources_flag(
+ manifest = manifest,
+ assets = assets,
+ assets_dir = assets_dir,
+ resource_files = resource_files,
+ ),
+ )
+ args.add("--manifest", manifest)
+ args.add("--rtxt", r_txt)
+ args.add("--classes", class_jar)
+ args.add("--aarOutput", out_aar)
+ args.add_all(proguard_specs, before_each = "--proguardSpec")
+ if should_throw_on_conflict:
+ args.add("--throwOnResourceConflict")
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = busybox,
+ arguments = [args],
+ inputs = (
+ resource_files +
+ assets +
+ proguard_specs +
+ [r_txt, manifest, class_jar]
+ ),
+ outputs = [out_aar],
+ mnemonic = "StarlarkAARGenerator",
+ progress_message = "Generating AAR package for %s" % ctx.label,
+ )
+
+busybox = struct(
+ compile = _compile,
+ merge_compiled = _merge_compiled,
+ validate_and_link = _validate_and_link,
+ merge_manifests = _merge_manifests,
+ package = _package,
+ parse = _parse,
+ merge_assets = _merge_assets,
+ make_resources_flag = _make_resources_flag,
+ process_databinding = _process_databinding,
+ generate_binary_r = _generate_binary_r,
+ make_aar = _make_aar,
+
+ # Exposed for testing
+ mergee_manifests_flag = _mergee_manifests_flag,
+ get_unique_res_dirs = _get_unique_res_dirs,
+ sanitize_assets_dir = _sanitize_assets_dir,
+ extract_filters = _extract_filters,
+)
diff --git a/rules/common.bzl b/rules/common.bzl
new file mode 100644
index 0000000..6e84559
--- /dev/null
+++ b/rules/common.bzl
@@ -0,0 +1,111 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel common library for the Android rules."""
+
+load(":java.bzl", _java = "java")
+load(":utils.bzl", "get_android_sdk", "get_android_toolchain", _log = "log")
+
+# TODO(ostonge): Remove once kotlin/jvm_library.internal.bzl
+# is updated and released to use the java.resolve_package function
+def _java_package(label, custom_package):
+ return _java.resolve_package_from_label(label, custom_package)
+
+# Validates that the packages listed under "deps" all have the given constraint. If a package
+# does not have this attribute, an error is generated.
+def _validate_constraints(targets, constraint):
+ for target in targets:
+ if JavaInfo in target:
+ if constraint not in java_common.get_constraints(target[JavaInfo]):
+ _log.error("%s: does not have constraint '%s'" % (target.label, constraint))
+
+TARGET_DNE = "Target '%s' does not exist or is a file and is not allowed."
+
+def _check_rule(targets):
+ _validate_constraints(targets, "android")
+
+def _get_java_toolchain(ctx):
+ if not hasattr(ctx.attr, "_java_toolchain"):
+ _log.error("Missing _java_toolchain attr")
+ return ctx.attr._java_toolchain
+
+def _get_host_javabase(ctx):
+ if not hasattr(ctx.attr, "_host_javabase"):
+ _log.error("Missing _host_javabase attr")
+ return ctx.attr._host_javabase
+
+def _sign_apk(ctx, unsigned_apk, signed_apk, keystore = None, signing_keys = [], signing_lineage = None):
+ """Signs an apk. Usage of keystore is deprecated. Prefer using signing_keys."""
+ inputs = [unsigned_apk]
+ signer_args = ctx.actions.args()
+ signer_args.add("sign")
+
+ if signing_keys:
+ inputs.extend(signing_keys)
+ for i, key in enumerate(signing_keys):
+ if i > 0:
+ signer_args.add("--next-signer")
+ signer_args.add("--ks")
+ signer_args.add(key.path)
+ signer_args.add("--ks-pass")
+ signer_args.add("pass:android")
+ if signing_lineage:
+ inputs.append(signing_lineage)
+ signer_args.add("--lineage", signing_lineage.path)
+ elif keystore:
+ inputs.append(keystore)
+ signer_args.add("--ks", keystore.path)
+ signer_args.add("--ks-pass", "pass:android")
+
+ signer_args.add("--v1-signing-enabled", ctx.fragments.android.apk_signing_method_v1)
+ signer_args.add("--v1-signer-name", "CERT")
+ signer_args.add("--v2-signing-enabled", ctx.fragments.android.apk_signing_method_v2)
+ signer_args.add("--out", signed_apk.path)
+ signer_args.add(unsigned_apk.path)
+ ctx.actions.run(
+ executable = get_android_sdk(ctx).apk_signer,
+ inputs = inputs,
+ outputs = [signed_apk],
+ arguments = [signer_args],
+ mnemonic = "ApkSignerTool",
+ progress_message = "Signing APK for %s" % unsigned_apk.path,
+ )
+ return signed_apk
+
+def _filter_zip(ctx, in_zip, out_zip, filters = []):
+ """Creates a copy of a zip file with files that match filters."""
+ args = ctx.actions.args()
+ args.add("-q")
+ args.add(in_zip.path)
+ args.add_all(filters)
+ args.add("--copy")
+ args.add("--out")
+ args.add(out_zip.path)
+ ctx.actions.run(
+ executable = get_android_toolchain(ctx).zip_tool.files_to_run,
+ arguments = [args],
+ inputs = [in_zip],
+ outputs = [out_zip],
+ mnemonic = "FilterZip",
+ progress_message = "Filtering %s" % in_zip.short_path,
+ )
+
+common = struct(
+ check_rule = _check_rule,
+ get_host_javabase = _get_host_javabase,
+ get_java_toolchain = _get_java_toolchain,
+ filter_zip = _filter_zip,
+ java_package = _java_package,
+ sign_apk = _sign_apk,
+)
diff --git a/rules/data_binding.bzl b/rules/data_binding.bzl
new file mode 100644
index 0000000..39923ec
--- /dev/null
+++ b/rules/data_binding.bzl
@@ -0,0 +1,286 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android Data Binding."""
+
+load(":utils.bzl", _utils = "utils")
+
+# Data Binding context attributes.
+_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS = \
+ "java_annotation_processor_additional_inputs"
+_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS = \
+ "java_annotation_processor_additional_outputs"
+_JAVA_PLUGINS = "java_plugins"
+_JAVA_SRCS = "java_srcs"
+_JAVAC_OPTS = "javac_opts"
+_PROVIDERS = "providers"
+
+DataBindingContextInfo = provider(
+ doc = "Contains data from processing Android Data Binding.",
+ fields = {
+ _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS: (
+ "Additional inputs required by the Java annotation processor."
+ ),
+ _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS: (
+ "Additional outputs produced by the Java annotation processor."
+ ),
+ _JAVA_PLUGINS: "Data Binding Java annotation processor",
+ _JAVA_SRCS: "Java sources required by the Java annotation processor.",
+ _JAVAC_OPTS: (
+ "Additional Javac opts required by the Java annotation processor."
+ ),
+ _PROVIDERS: "The list of all providers to propagate.",
+ },
+)
+
+# Path used when resources have not been defined.
+_NO_RESOURCES_PATH = "/tmp/no_resources"
+
+def _copy_annotation_file(ctx, output_dir, annotation_template):
+ annotation_out = ctx.actions.declare_file(
+ output_dir + "/android/databinding/layouts/DataBindingInfo.java",
+ )
+ _utils.copy_file(ctx, annotation_template, annotation_out)
+ return annotation_out
+
+def _gen_sources(ctx, output_dir, java_package, deps, data_binding_exec):
+ layout_info = ctx.actions.declare_file(output_dir + "layout-info.zip")
+ class_info = ctx.actions.declare_file(output_dir + "class-info.zip")
+ srcjar = ctx.actions.declare_file(output_dir + "baseClassSrc.srcjar")
+
+ args = ctx.actions.args()
+ args.add("-layoutInfoFiles", layout_info)
+ args.add("-package", java_package)
+ args.add("-classInfoOut", class_info)
+ args.add("-sourceOut", srcjar)
+ args.add("-zipSourceOutput", "true")
+ args.add("-useAndroidX", "false")
+
+ class_infos = []
+ for info in deps:
+ class_infos.extend(info.class_infos)
+ args.add_all(class_infos, before_each = "-dependencyClassInfoList")
+
+ ctx.actions.run(
+ executable = data_binding_exec,
+ arguments = ["GEN_BASE_CLASSES", args],
+ inputs = class_infos + [layout_info],
+ outputs = [class_info, srcjar],
+ mnemonic = "GenerateDataBindingBaseClasses",
+ progress_message = (
+ "GenerateDataBindingBaseClasses %s" % class_info.short_path
+ ),
+ )
+ return srcjar, class_info, layout_info
+
+def _setup_dependent_lib_artifacts(ctx, output_dir, deps):
+ # DataBinding requires files in very specific locations.
+ # The following expand_template (copy actions) are moving the files
+ # to the correct locations.
+ dep_lib_artifacts = []
+ for info in deps:
+ # Yes, DataBinding requires depsets iterations.
+ for artifact in (info.transitive_br_files.to_list() +
+ info.setter_stores +
+ info.class_infos):
+ # short_path might contain a parent directory reference if the
+ # databinding artifact is from an external repository (e.g. an aar
+ # from Maven). If that's the case, just remove the parent directory
+ # reference, otherwise the "dependent-lib-artifacts" directory will
+ # get removed by the "..".
+ path = artifact.short_path
+ if path.startswith("../"):
+ path = path[3:]
+ dep_lib_artifact = ctx.actions.declare_file(
+ output_dir + "dependent-lib-artifacts/" + path,
+ )
+
+ # Copy file to a location required by the DataBinding annotation
+ # processor.
+ # TODO(djwhang): Look into SymlinkAction.
+ if artifact.is_directory:
+ _utils.copy_dir(ctx, artifact, dep_lib_artifact)
+ else:
+ _utils.copy_file(ctx, artifact, dep_lib_artifact)
+ dep_lib_artifacts.append(dep_lib_artifact)
+ return dep_lib_artifacts
+
+def _get_javac_opts(
+ ctx,
+ java_package,
+ dependency_artifacts_dir,
+ aar_out_dir,
+ class_info_path,
+ layout_info_path,
+ deps):
+ java_packages = []
+ for info in deps:
+ for label_and_java_package in info.label_and_java_packages:
+ java_packages.append(label_and_java_package.java_package)
+
+ javac_opts = []
+ javac_opts.append("-Aandroid.databinding.dependencyArtifactsDir=" +
+ dependency_artifacts_dir)
+ javac_opts.append("-Aandroid.databinding.aarOutDir=" + aar_out_dir)
+ javac_opts.append("-Aandroid.databinding.sdkDir=/not/used")
+ javac_opts.append("-Aandroid.databinding.artifactType=LIBRARY")
+ javac_opts.append("-Aandroid.databinding.exportClassListOutFile=" +
+ "/tmp/exported_classes")
+ javac_opts.append("-Aandroid.databinding.modulePackage=" + java_package)
+ javac_opts.append("-Aandroid.databinding.directDependencyPkgs=[%s]" %
+ ",".join(java_packages))
+
+ # The minimum Android SDK compatible with this rule.
+ # TODO(djwhang): This probably should be based on the actual min-sdk from
+ # the manifest, or an appropriate rule attribute.
+ javac_opts.append("-Aandroid.databinding.minApi=14")
+ javac_opts.append("-Aandroid.databinding.enableV2=1")
+
+ javac_opts.append("-Aandroid.databinding.classLogDir=" + class_info_path)
+ javac_opts.append("-Aandroid.databinding.layoutInfoDir=" + layout_info_path)
+ return javac_opts
+
+def _process(
+ ctx,
+ resources_ctx = None,
+ defines_resources = False,
+ enable_data_binding = False,
+ java_package = None,
+ deps = [],
+ exports = [],
+ data_binding_exec = None,
+ data_binding_annotation_processor = None,
+ data_binding_annotation_template = None):
+ """Processes Android Data Binding.
+
+ Args:
+ ctx: The context.
+ resources_ctx: The Android Resources context.
+ defines_resources: boolean. Determines whether resources were defined.
+ enable_data_binding: boolean. Determines whether Data Binding should be
+ enabled.
+ java_package: String. The Java package.
+ deps: sequence of DataBindingV2Info providers. A list of deps. Optional.
+ exports: sequence of DataBindingV2Info providers. A list of exports.
+ Optional.
+ data_binding_exec: The DataBinding executable.
+ data_binding_annotation_processor: JavaInfo. The JavaInfo for the
+ annotation processor.
+ data_binding_annotation_template: A file. Used to generate data binding
+ classes.
+
+ Returns:
+ A DataBindingContextInfo provider.
+ """
+
+ # TODO(b/154513292): Clean up bad usages of context objects.
+ if resources_ctx:
+ defines_resources = resources_ctx.defines_resources
+
+ # The Android Data Binding context object.
+ db_info = {
+ _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS: [],
+ _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS: [],
+ _JAVA_PLUGINS: [],
+ _JAVA_SRCS: [],
+ _JAVAC_OPTS: [],
+ _PROVIDERS: [],
+ }
+
+ if not enable_data_binding:
+ db_info[_PROVIDERS] = [
+ DataBindingV2Info(
+ databinding_v2_providers_in_deps = deps,
+ databinding_v2_providers_in_exports = exports,
+ ),
+ ]
+ return struct(**db_info)
+
+ output_dir = "_migrated/databinding/%s/" % ctx.label.name
+
+ db_info[_JAVA_SRCS].append(_copy_annotation_file(
+ ctx,
+ output_dir,
+ data_binding_annotation_template,
+ ))
+ db_info[_JAVA_PLUGINS].append(data_binding_annotation_processor)
+
+ br_out = None
+ setter_store_out = None
+ class_info = None
+ layout_info = None
+ if defines_resources:
+ # Outputs of the Data Binding annotation processor.
+ br_out = ctx.actions.declare_file(
+ output_dir + "bin-files/%s-br.bin" % java_package,
+ )
+ db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append(br_out)
+ setter_store_out = ctx.actions.declare_file(
+ output_dir + "bin-files/%s-setter_store.json" % java_package,
+ )
+ db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append(
+ setter_store_out,
+ )
+
+ srcjar, class_info, layout_info = _gen_sources(
+ ctx,
+ output_dir,
+ java_package,
+ deps,
+ data_binding_exec,
+ )
+ db_info[_JAVA_SRCS].append(srcjar)
+ db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].append(class_info)
+ db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].append(
+ layout_info,
+ )
+
+ dep_lib_artifacts = _setup_dependent_lib_artifacts(ctx, output_dir, deps)
+ db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].extend(
+ dep_lib_artifacts,
+ )
+
+ db_info[_JAVAC_OPTS] = _get_javac_opts(
+ ctx,
+ java_package,
+ (
+ br_out.path.rpartition(br_out.short_path)[0] +
+ ctx.label.package +
+ "/" +
+ output_dir +
+ "dependent-lib-artifacts"
+ ),
+ br_out.dirname,
+ class_info.path if class_info else _NO_RESOURCES_PATH,
+ layout_info.path if layout_info else _NO_RESOURCES_PATH,
+ deps,
+ )
+
+ db_info[_PROVIDERS] = [
+ DataBindingV2Info(
+ setter_store_file = setter_store_out,
+ class_info_file = class_info,
+ br_file = br_out,
+ label = str(ctx.label),
+ java_package = java_package,
+ databinding_v2_providers_in_deps = deps,
+ databinding_v2_providers_in_exports = exports,
+ ),
+ ]
+
+ return DataBindingContextInfo(**db_info)
+
+data_binding = struct(
+ process = _process,
+)
diff --git a/rules/data_binding_annotation_template.txt b/rules/data_binding_annotation_template.txt
new file mode 100644
index 0000000..295397e
--- /dev/null
+++ b/rules/data_binding_annotation_template.txt
@@ -0,0 +1,15 @@
+package android.databinding.layouts;
+
+import android.databinding.BindingBuildInfo;
+
+/**
+ * Template for the file that feeds data binding's annotation processor. The
+ * processor reads the values set here to generate .java files that link XML
+ * data binding declarations (from layoutInfoDir) to app code.
+ */
+@BindingBuildInfo(
+ buildId="not_used_here" // Adds incrementality, which Bazel already supports
+)
+public class DataBindingInfo {
+ /* This only exists for annotation processing. */
+}
diff --git a/rules/flags/BUILD b/rules/flags/BUILD
new file mode 100644
index 0000000..4895b09
--- /dev/null
+++ b/rules/flags/BUILD
@@ -0,0 +1,22 @@
+# Flags for Android rules and mobile-install
+
+load("@rules_android//rules/flags:flags.bzl", "flags")
+load("@rules_android//rules/flags:flag_defs.bzl", "define_flags")
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+
+licenses(["notice"])
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+)
+
+bzl_library(
+ name = "bzl",
+ srcs = glob(["*.bzl"]),
+)
+
+define_flags()
+
+flags.FLAGS()
diff --git a/rules/flags/flag_defs.bzl b/rules/flags/flag_defs.bzl
new file mode 100644
index 0000000..cecb40a
--- /dev/null
+++ b/rules/flags/flag_defs.bzl
@@ -0,0 +1,92 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Flag definitions."""
+
+load("@rules_android//rules/flags:flags.bzl", "flags")
+
+def define_flags():
+ flags.DEFINE_bool(
+ name = "android_enable_res_v3",
+ default = False,
+ description = "Enable Resource Processing Pipeline v3.",
+ )
+
+ flags.DEFINE_bool(
+ name = "use_direct_deploy",
+ default = False,
+ description = "Enable direct deployment.",
+ )
+
+ flags.DEFINE_int(
+ name = "num_dex_shards",
+ default = 16,
+ description = "Number of dex shards to use for mobile-install.",
+ )
+
+ flags.DEFINE_bool(
+ name = "use_custom_dex_shards",
+ default = False,
+ description = "Whether to use custom dex shard value for mobile-install.",
+ )
+
+ flags.DEFINE_bool_group(
+ name = "mi_v3",
+ default = True,
+ description = "Enable mobile-install v3.",
+ flags = [
+ # TODO(b/160897244): resv3 temporarily disabled while Starlark
+ # resource processing is implemented and rolled out
+ # ":android_enable_res_v3",
+ ":use_custom_dex_shards",
+ ":use_direct_deploy",
+ ],
+ )
+
+ flags.DEFINE_bool_group(
+ name = "mi_dogfood",
+ default = False,
+ description = "Opt-in to mobile-install dogfood track.",
+ flags = [
+ ],
+ )
+
+ flags.DEFINE_bool(
+ name = "enable_splits",
+ default = False,
+ description = "Build and install split apks if the device supports them.",
+ )
+
+ flags.DEFINE_bool(
+ name = "use_adb_root",
+ default = True,
+ description = "Restart adb with root permissions.",
+ )
+
+ flags.DEFINE_bool(
+ name = "mi_desugar_java8_libs",
+ default = False,
+ description = "Set True with --config=android_java8_libs",
+ )
+
+ flags.DEFINE_bool(
+ name = "debug",
+ default = False,
+ description = "",
+ )
+
+ flags.EXPOSE_native_bool(
+ name = "stamp",
+ description = "Accesses the native --stamp CLI flag",
+ )
diff --git a/rules/flags/flags.bzl b/rules/flags/flags.bzl
new file mode 100644
index 0000000..e6e25a6
--- /dev/null
+++ b/rules/flags/flags.bzl
@@ -0,0 +1,255 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Flags."""
+
+load("@rules_android//rules:utils.bzl", "utils")
+
+_BoolFlagInfo = provider(
+ doc = "Provides information about a boolean flag",
+ fields = dict(
+ name = "flag name",
+ value = "flag value",
+ explicit = "whether value was set explicitly",
+ ),
+)
+_BoolFlagGroupInfo = provider(
+ doc = "Provides information about a boolean flag group",
+ fields = dict(
+ name = "group name",
+ value = "group value",
+ flags = "flag names that belong to this group",
+ ),
+)
+_IntFlagInfo = provider(
+ doc = "Provides information about an integer flag",
+ fields = dict(
+ name = "flag name",
+ value = "flag value",
+ ),
+)
+_NativeBoolFlagInfo = provider(
+ doc = "Provides information about a native boolean flag",
+ fields = dict(
+ name = "flag name, the name of the native flag being accessed.",
+ value = "flag value, derived from config_setting targets that access the value",
+ ),
+)
+FlagsInfo = provider(
+ doc = "Provides all flags",
+)
+
+def _native_bool_impl(ctx):
+ return _NativeBoolFlagInfo(
+ name = ctx.label.name,
+ value = ctx.attr.value,
+ )
+
+native_bool_flag = rule(
+ implementation = _native_bool_impl,
+ attrs = dict(
+ value = attr.bool(mandatory = True),
+ ),
+ provides = [_NativeBoolFlagInfo],
+)
+
+def native_bool_flag_macro(name, description):
+ """Provides access to a native boolean flag from Starlark.
+
+ Args:
+ name: The name of the native flag to access.
+ description: The description of the flag.
+ """
+ native.config_setting(
+ name = name + "_on",
+ values = {name: "True"},
+ )
+ native.config_setting(
+ name = name + "_off",
+ values = {name: "False"},
+ )
+ native_bool_flag(
+ name = name,
+ value = select({
+ (":" + name + "_on"): True,
+ (":" + name + "_off"): False,
+ }),
+ )
+
+def _get_bool(v):
+ v = v.lower()
+ if v == "true":
+ return True
+ if v == "false":
+ return False
+ fail("Unknown bool: " + v)
+
+def _bool_impl(ctx):
+ if ctx.label.name in ctx.var:
+ value = _get_bool(ctx.var[ctx.label.name])
+ return _BoolFlagInfo(
+ name = ctx.label.name,
+ value = value,
+ explicit = True,
+ )
+ return _BoolFlagInfo(
+ name = ctx.label.name,
+ value = ctx.attr.default,
+ explicit = False,
+ )
+
+bool_flag = rule(
+ implementation = _bool_impl,
+ attrs = dict(
+ default = attr.bool(
+ mandatory = True,
+ ),
+ description = attr.string(
+ mandatory = True,
+ ),
+ ),
+ provides = [_BoolFlagInfo],
+)
+
+def _bool_group_impl(ctx):
+ if ctx.label.name in ctx.var:
+ value = _get_bool(ctx.var[ctx.label.name])
+ return _BoolFlagGroupInfo(
+ name = ctx.label.name,
+ value = value,
+ flags = [f[_BoolFlagInfo].name for f in ctx.attr.flags],
+ )
+ return _BoolFlagGroupInfo(
+ name = ctx.label.name,
+ value = ctx.attr.default,
+ flags = [f[_BoolFlagInfo].name for f in ctx.attr.flags],
+ )
+
+bool_flag_group = rule(
+ implementation = _bool_group_impl,
+ attrs = dict(
+ default = attr.bool(
+ mandatory = True,
+ ),
+ description = attr.string(
+ mandatory = True,
+ ),
+ flags = attr.label_list(
+ mandatory = True,
+ providers = [_BoolFlagInfo],
+ ),
+ ),
+ provides = [_BoolFlagGroupInfo],
+)
+
+def _int_impl(ctx):
+ if ctx.label.name in ctx.var:
+ value = int(ctx.var[ctx.label.name])
+ else:
+ value = ctx.attr.default
+ return _IntFlagInfo(
+ name = ctx.label.name,
+ value = value,
+ )
+
+int_flag = rule(
+ implementation = _int_impl,
+ attrs = dict(
+ default = attr.int(
+ mandatory = True,
+ ),
+ description = attr.string(
+ mandatory = True,
+ ),
+ ),
+ provides = [_IntFlagInfo],
+)
+
+def _flags_impl_internal(bool_flags, bool_flag_groups, int_flags, native_bool_flags):
+ flags = dict()
+
+ # For each group, set all flags to the group value
+ for fg in bool_flag_groups:
+ for f in fg.flags:
+ if f in flags:
+ fail("Flag '%s' referenced in multiple flag groups" % f)
+ flags[f] = fg.value
+
+ # Set booleans
+ for b in bool_flags:
+ # Always set explicitly specified flags
+ if b.explicit:
+ flags[b.name] = b.value
+ # If not explicit, only set when not set by a group
+
+ elif b.name not in flags:
+ flags[b.name] = b.value
+
+ # Set ints
+ for i in int_flags:
+ flags[i.name] = i.value
+
+ # Set native bool flags
+ for n in native_bool_flags:
+ if n.name in flags:
+ fail("Flag '%s' defined as both native and non-native flag type" % n.name)
+ flags[n.name] = n.value
+
+ return FlagsInfo(**flags)
+
+def _flags_impl(ctx):
+ return _flags_impl_internal(
+ utils.collect_providers(_BoolFlagInfo, ctx.attr.targets),
+ utils.collect_providers(_BoolFlagGroupInfo, ctx.attr.targets),
+ utils.collect_providers(_IntFlagInfo, ctx.attr.targets),
+ utils.collect_providers(_NativeBoolFlagInfo, ctx.attr.targets),
+ )
+
+flags_rule = rule(
+ implementation = _flags_impl,
+ attrs = dict(
+ targets = attr.label_list(),
+ ),
+)
+
+def _flags_macro():
+ flags_rule(
+ name = "flags",
+ targets = native.existing_rules().keys(),
+ visibility = ["//visibility:public"],
+ )
+
+def _get_flags(ctx):
+ return ctx.attr._flags[FlagsInfo]
+
+flags = struct(
+ DEFINE_bool = bool_flag,
+ DEFINE_bool_group = bool_flag_group,
+ DEFINE_int = int_flag,
+ EXPOSE_native_bool = native_bool_flag_macro,
+ FLAGS = _flags_macro,
+ FlagsInfo = FlagsInfo,
+ get = _get_flags,
+)
+
+exported_for_test = struct(
+ BoolFlagGroupInfo = _BoolFlagGroupInfo,
+ BoolFlagInfo = _BoolFlagInfo,
+ IntFlagInfo = _IntFlagInfo,
+ NativeBoolFlagInfo = _NativeBoolFlagInfo,
+ bool_impl = _bool_impl,
+ flags_impl_internal = _flags_impl_internal,
+ int_impl = _int_impl,
+ native_bool_flag_macro = native_bool_flag_macro,
+)
diff --git a/rules/idl.bzl b/rules/idl.bzl
new file mode 100644
index 0000000..8dc52d3
--- /dev/null
+++ b/rules/idl.bzl
@@ -0,0 +1,264 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android IDL library for the Android rules."""
+
+load(":java.bzl", _java = "java")
+load(":path.bzl", _path = "path")
+load(":utils.bzl", _log = "log")
+
+_AIDL_TOOLCHAIN_MISSING_ERROR = (
+ "IDL sources provided without the Android IDL toolchain."
+)
+
+_AIDL_JAVA_ROOT_UNDETERMINABLE_ERROR = (
+ "Cannot determine java/javatests root for import %s."
+)
+
+IDLContextInfo = provider(
+ doc = "Contains data from processing Android IDL.",
+ fields = dict(
+ idl_srcs = "List of IDL sources",
+ idl_import_root = "IDL import root",
+ idl_java_srcs = "List of IDL Java sources",
+ idl_deps =
+ "List of IDL targets required for Java compilation, Proguard, etc.",
+ providers = "The list of all providers to propagate.",
+ ),
+)
+
+def _gen_java_from_idl(
+ ctx,
+ out_idl_java_src = None,
+ idl_src = None,
+ transitive_idl_import_roots = [],
+ transitive_idl_imports = [],
+ transitive_idl_preprocessed = [],
+ aidl = None,
+ aidl_lib = None,
+ aidl_framework = None):
+ args = ctx.actions.args()
+ args.add("-b")
+ args.add_all(transitive_idl_import_roots, format_each = "-I%s")
+ args.add(aidl_framework, format = "-p%s")
+ args.add_all(transitive_idl_preprocessed, format_each = "-p%s")
+ args.add(idl_src)
+ args.add(out_idl_java_src)
+
+ ctx.actions.run(
+ executable = aidl,
+ arguments = [args],
+ inputs = depset(
+ [aidl_framework],
+ transitive = [
+ aidl_lib.files,
+ transitive_idl_imports,
+ transitive_idl_preprocessed,
+ ],
+ ),
+ outputs = [out_idl_java_src],
+ mnemonic = "AndroidIDLGenerate",
+ progress_message = "Android IDL generation %s" % idl_src.path,
+ )
+
+def _get_idl_import_root_path(
+ package,
+ idl_import_root,
+ idl_file_root_path):
+ package_path = _path.relative(
+ idl_file_root_path,
+ package,
+ )
+ return _path.relative(
+ package_path,
+ idl_import_root,
+ )
+
+def _collect_unique_idl_import_root_paths(
+ package,
+ idl_import_root,
+ idl_imports):
+ idl_import_roots = dict()
+ for idl_import in idl_imports:
+ idl_import_roots[_get_idl_import_root_path(
+ package,
+ idl_import_root,
+ idl_import.root.path,
+ )] = True
+ return sorted(idl_import_roots.keys())
+
+def _collect_unique_java_roots(idl_imports):
+ idl_import_roots = dict()
+ for idl_import in idl_imports:
+ java_root = _java.root(idl_import.path)
+ if not java_root:
+ _log.error(_AIDL_JAVA_ROOT_UNDETERMINABLE_ERROR % idl_import.path)
+ idl_import_roots[java_root] = True
+ return sorted(idl_import_roots.keys())
+
+def _determine_idl_import_roots(
+ package,
+ idl_import_root = None,
+ idl_imports = []):
+ if idl_import_root == None:
+ return _collect_unique_java_roots(idl_imports)
+ return _collect_unique_idl_import_root_paths(
+ package,
+ idl_import_root,
+ idl_imports,
+ )
+
+def _process(
+ ctx,
+ idl_srcs = [],
+ idl_parcelables = [],
+ idl_import_root = None,
+ idl_preprocessed = [],
+ deps = [],
+ exports = [],
+ aidl = None,
+ aidl_lib = None,
+ aidl_framework = None):
+ """Processes Android IDL.
+
+ Args:
+ ctx: The context.
+ idl_srcs: sequence of Files. A list of the aidl source files to be
+ processed into Java source files and then compiled. Optional.
+ idl_parcelables: sequence of Files. A list of Android IDL definitions to
+ supply as imports. These files will be made available as imports for any
+ android_library target that depends on this library, directly or via its
+ transitive closure, but will not be translated to Java or compiled.
+
+ Only .aidl files that correspond directly to .java sources in this library
+ should be included (e.g. custom implementations of Parcelable), otherwise
+ idl_srcs should be used.
+
+ These files must be placed appropriately for the aidl compiler to find
+ them. See the description of idl_import_root for information about what
+ this means. Optional.
+ idl_import_root: string. Package-relative path to the root of the java
+ package tree containing idl sources included in this library. This path
+ will be used as the import root when processing idl sources that depend on
+ this library.
+
+ When idl_import_root is specified, both idl_parcelables and idl_srcs must
+ be at the path specified by the java package of the object they represent
+ under idl_import_root. When idl_import_root is not specified, both
+ idl_parcelables and idl_srcs must be at the path specified by their
+ package under a Java root. Optional.
+ idl_preprocessed: sequence of Files. A list of preprocessed Android IDL
+ definitions to supply as imports. These files will be made available as
+ imports for any android_library target that depends on this library,
+ directly or via its transitive closure, but will not be translated to
+ Java or compiled.
+
+ Only preprocessed .aidl files that correspond directly to .java sources
+ in this library should be included (e.g. custom implementations of
+ Parcelable), otherwise use idl_srcs for Android IDL definitions that
+ need to be translated to Java interfaces and use idl_parcelable for
+ non-preprcessed AIDL files. Optional.
+ deps: sequence of Targets. A list of dependencies. Optional.
+ exports: sequence of Targets. A list of exports. Optional.
+ aidl: Target. A target pointing to the aidl executable to be used for
+ Java code generation from *.idl source files. Optional, unless idl_srcs
+ are supplied.
+ aidl_lib: Target. A target pointing to the aidl_lib library required
+ during Java compilation when Java code is generated from idl sources.
+ Optional, unless idl_srcs are supplied.
+ aidl_framework: Target. A target pointing to the aidl framework. Optional,
+ unless idl_srcs are supplied.
+
+ Returns:
+ A IDLContextInfo provider.
+ """
+ if idl_srcs and not (aidl and aidl_lib and aidl_framework):
+ _log.error(_AIDL_TOOLCHAIN_MISSING_ERROR)
+
+ transitive_idl_import_roots = []
+ transitive_idl_imports = []
+ transitive_idl_preprocessed = []
+ for dep in deps + exports:
+ transitive_idl_import_roots.append(dep.transitive_idl_import_roots)
+ transitive_idl_imports.append(dep.transitive_idl_imports)
+ transitive_idl_preprocessed.append(dep.transitive_idl_preprocessed)
+
+ idl_java_srcs = []
+ for idl_src in idl_srcs:
+ idl_java_src = ctx.actions.declare_file(
+ ctx.label.name + "_aidl/" + idl_src.path.replace(".aidl", ".java"),
+ )
+ idl_java_srcs.append(idl_java_src)
+ _gen_java_from_idl(
+ ctx,
+ out_idl_java_src = idl_java_src,
+ idl_src = idl_src,
+ transitive_idl_import_roots = depset(
+ _determine_idl_import_roots(
+ ctx.label.package,
+ idl_import_root,
+ idl_parcelables + idl_srcs,
+ ),
+ transitive = transitive_idl_import_roots,
+ order = "preorder",
+ ),
+ transitive_idl_imports = depset(
+ idl_parcelables + idl_srcs,
+ transitive = transitive_idl_imports,
+ order = "preorder",
+ ),
+ transitive_idl_preprocessed = depset(
+ transitive = transitive_idl_preprocessed,
+ ),
+ aidl = aidl,
+ aidl_lib = aidl_lib,
+ aidl_framework = aidl_framework,
+ )
+
+ return IDLContextInfo(
+ idl_srcs = idl_srcs,
+ idl_import_root = idl_import_root,
+ idl_java_srcs = idl_java_srcs,
+ idl_deps = [aidl_lib] if idl_java_srcs else [],
+ providers = [
+ # TODO(b/146216105): Make this a Starlark provider.
+ AndroidIdlInfo(
+ depset(
+ _determine_idl_import_roots(
+ ctx.label.package,
+ idl_import_root,
+ idl_parcelables + idl_srcs + idl_preprocessed,
+ ),
+ transitive = transitive_idl_import_roots,
+ order = "preorder",
+ ),
+ depset(
+ idl_parcelables + idl_srcs + idl_preprocessed,
+ transitive = transitive_idl_imports,
+ order = "preorder",
+ ),
+ depset(), # TODO(b/146216105): Delete this field once in Starlark.
+ depset(idl_preprocessed, transitive = transitive_idl_preprocessed),
+ ),
+ ],
+ )
+
+idl = struct(
+ process = _process,
+)
+
+# Visible for testing.
+testing = struct(
+ get_idl_import_root_path = _get_idl_import_root_path,
+)
diff --git a/rules/intellij.bzl b/rules/intellij.bzl
new file mode 100644
index 0000000..c870b1b
--- /dev/null
+++ b/rules/intellij.bzl
@@ -0,0 +1,165 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Common methods for use by the IntelliJ Aspect."""
+
+load(":java.bzl", _java = "java")
+load(":utils.bzl", _utils = "utils")
+
+def _extract_idl_jars(
+ ctx,
+ idl_java_srcs = [],
+ jar = None,
+ manifest_proto = None,
+ out_srcjar = None,
+ out_jar = None,
+ idlclass = None,
+ host_javabase = None):
+ """Extracts the idl class and src jars."""
+ args = ctx.actions.args()
+ args.add("--class_jar", jar)
+ args.add("--manifest_proto", manifest_proto)
+ args.add("--output_class_jar", out_jar)
+ args.add("--output_source_jar", out_srcjar)
+ args.add("--temp_dir", out_jar.dirname)
+ args.add_all(idl_java_srcs)
+
+ _java.run(
+ ctx = ctx,
+ host_javabase = host_javabase,
+ executable = idlclass,
+ arguments = [args],
+ inputs = idl_java_srcs + [jar, manifest_proto],
+ outputs = [out_srcjar, out_jar],
+ mnemonic = "AndroidIdlJars",
+ progress_message = "Building idl jars %s" % out_jar.path,
+ )
+
+def _make_android_ide_info(
+ ctx,
+ idl_ctx = None,
+ resources_ctx = None,
+ defines_resources = False,
+ java_package = None,
+ manifest = None,
+ merged_manifest = None,
+ resources_apk = None,
+ idl_import_root = None,
+ idl_srcs = [],
+ idl_java_srcs = [],
+ java_info = None,
+ r_jar = None,
+ signed_apk = None,
+ aar = None,
+ apks_under_test = [],
+ native_libs = dict(),
+ idlclass = None,
+ host_javabase = None):
+ # TODO(b/154513292): Clean up bad usages of context objects.
+ if idl_ctx:
+ idl_import_root = idl_ctx.idl_import_root
+ idl_srcs = idl_ctx.idl_srcs
+ idl_java_srcs = idl_ctx.idl_java_srcs
+ if resources_ctx:
+ defines_resources = resources_ctx.defines_resources
+ merged_manifest = resources_ctx.merged_manifest
+ resources_apk = resources_ctx.resources_apk
+
+ if not defines_resources:
+ java_package = None
+ merged_manifest = None
+
+ # Extracts idl related classes from the jar and creates a src jar
+ # for the idl generated java.
+ idl_jar = None
+ idl_srcjar = None
+
+ # TODO(djwhang): JavaInfo.outputs.jar.manifest_proto is not created by
+ # Kotlin compile. Determine if this is the same manifest_proto produced
+ # by turbine, this could be pulled during annotation processing.
+ jar = _utils.only(java_info.outputs.jars)
+ if idl_java_srcs and jar.manifest_proto:
+ idl_jar = ctx.actions.declare_file("lib%s-idl.jar" % ctx.label.name)
+ idl_srcjar = \
+ ctx.actions.declare_file("lib%s-idl.srcjar" % ctx.label.name)
+
+ jar = _utils.only(java_info.outputs.jars)
+ _extract_idl_jars(
+ ctx,
+ idl_java_srcs = idl_java_srcs,
+ jar = jar.class_jar,
+ manifest_proto = jar.manifest_proto,
+ out_jar = idl_jar,
+ out_srcjar = idl_srcjar,
+ idlclass = idlclass,
+ host_javabase = host_javabase,
+ )
+
+ return AndroidIdeInfo(
+ java_package,
+ manifest,
+ merged_manifest,
+ idl_import_root,
+ idl_srcs,
+ idl_java_srcs,
+ idl_srcjar,
+ idl_jar,
+ defines_resources,
+ r_jar,
+ resources_apk,
+ signed_apk,
+ aar,
+ apks_under_test,
+ native_libs,
+ )
+
+def _make_legacy_android_provider(android_ide_info):
+ # Create the ClassJar "object" for the target.android.idl.output field.
+ if android_ide_info.idl_class_jar:
+ idl_class_jar = struct(
+ class_jar = android_ide_info.idl_class_jar,
+ ijar = None,
+ source_jar = android_ide_info.idl_source_jar,
+ )
+ else:
+ idl_class_jar = None
+
+ return struct(
+ aar = android_ide_info.aar,
+ apk = android_ide_info.signed_apk,
+ apks_under_test = android_ide_info.apks_under_test,
+ defines_resources = android_ide_info.defines_android_resources,
+ idl = struct(
+ import_root = android_ide_info.idl_import_root,
+ sources = android_ide_info.idl_srcs,
+ generated_java_files = android_ide_info.idl_generated_java_files,
+ output = idl_class_jar,
+ ),
+ java_package = android_ide_info.java_package,
+ manifest = android_ide_info.manifest,
+ merged_manifest = android_ide_info.generated_manifest,
+ native_libs = android_ide_info.native_libs,
+ resource_apk = android_ide_info.resource_apk,
+ resource_jar = android_ide_info.resource_jar,
+ )
+
+intellij = struct(
+ make_android_ide_info = _make_android_ide_info,
+ make_legacy_android_provider = _make_legacy_android_provider,
+)
+
+# Only visible for testing.
+testing = struct(
+ extract_idl_jars = _extract_idl_jars,
+)
diff --git a/rules/java.bzl b/rules/java.bzl
new file mode 100644
index 0000000..7b23b35
--- /dev/null
+++ b/rules/java.bzl
@@ -0,0 +1,447 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Java APIs for the Android rules."""
+
+load(":path.bzl", _path = "path")
+load(":utils.bzl", "log")
+
+_ANDROID_CONSTRAINT_MISSING_ERROR = (
+ "A list of constraints provided without the 'android' constraint."
+)
+
+def _segment_idx(path_segments):
+ """Finds the index of the segment in the path that preceeds the source root.
+
+ Args:
+ path_segments: A list of strings, where each string is the segment of a
+ filesystem path.
+
+ Returns:
+ An index to the path segment that represents the Java segment or -1 if
+ none found.
+ """
+ if _path.is_absolute(path_segments[0]):
+ log.error("path must not be absolute: %s" % _path.join(path_segments))
+
+ root_idx = -1
+ for idx, segment in enumerate(path_segments):
+ if segment in ["java", "javatests", "src", "testsrc"]:
+ root_idx = idx
+ break
+ if root_idx < 0:
+ return root_idx
+
+ is_src = path_segments[root_idx] == "src"
+ check_maven_idx = root_idx if is_src else -1
+ if root_idx == 0 or is_src:
+ # Check for a nested root directory.
+ for idx in range(root_idx + 1, len(path_segments) - 2):
+ segment = path_segments[idx]
+ if segment == "src" or (is_src and segment in ["java", "javatests"]):
+ next_segment = path_segments[idx + 1]
+ if next_segment in ["com", "org", "net"]:
+ root_idx = idx
+ elif segment == "src":
+ check_maven_idx = idx
+ break
+
+ if check_maven_idx >= 0 and check_maven_idx + 2 < len(path_segments):
+ next_segment = path_segments[check_maven_idx + 1]
+ if next_segment in ["main", "test"]:
+ next_segment = path_segments[check_maven_idx + 2]
+ if next_segment in ["java", "resources"]:
+ root_idx = check_maven_idx + 2
+ return root_idx
+
+def _resolve_package(path):
+ """Determines the Java package name from the given path.
+
+ Examples:
+ "{workspace}/java/foo/bar/wiz" -> "foo.bar.wiz"
+ "{workspace}/javatests/foo/bar/wiz" -> "foo.bar.wiz"
+
+ Args:
+ path: A string, representing a file path.
+
+ Returns:
+ A string representing a Java package name or None if could not be
+ determined.
+ """
+ path_segments = _path.split(path.partition(":")[0])
+ java_idx = _segment_idx(path_segments)
+ if java_idx < 0:
+ return None
+ else:
+ return ".".join(path_segments[java_idx + 1:])
+
+def _resolve_package_from_label(
+ label,
+ custom_package = None,
+ fallback = True):
+ """Resolves the Java package from a Label.
+
+ When no legal Java package can be resolved from the label, None will be
+ returned unless fallback is specified.
+
+ When a fallback is requested, a not safe for Java compilation package will
+ be returned. The fallback value will be derrived by taking the label.package
+ and replacing all path separators with ".".
+ """
+ if custom_package:
+ return custom_package
+
+ # For backwards compatibility, also include directories
+ # from the label's name
+ # Ex: "//foo/bar:java/com/google/baz" is a legal one and
+ # results in "com.google"
+ label_path = _path.join(
+ [label.package] +
+ _path.split(label.name)[:-1],
+ )
+ java_package = _resolve_package(label_path)
+
+ if java_package != None: # "" is a valid result.
+ return java_package
+
+ if fallback:
+ return label.package.replace("/", ".")
+
+ return None
+
+def _root(path):
+ """Determines the Java root from the given path.
+
+ Examples:
+ "{workspace}/java/foo/bar/wiz" -> "{workspace}/java"
+ "{workspace}/javatests/foo/bar/wiz" -> "{workspace}/javatests"
+ "java/foo/bar/wiz" -> "java"
+ "javatests/foo/bar/wiz" -> "javatests"
+
+ Args:
+ path: A string, representing a file path.
+
+ Returns:
+ A string representing the Java root path or None if could not be
+ determined.
+ """
+ path_segments = _path.split(path.partition(":")[0])
+ java_idx = _segment_idx(path_segments)
+ if java_idx < 0:
+ return None
+ else:
+ return _path.join(path_segments[0:java_idx + 1])
+
+def _check_for_invalid_java_package(java_package):
+ return "-" in java_package or len(java_package.split(".")) < 2
+
+def _invalid_java_package(custom_package, java_package):
+ """Checks if the given java package is invalid.
+
+ Only checks if either custom_package or java_package contains the
+ illegal character "-" or if they are composed of only one word.
+ Only checks java_package if custom_package is an empty string or None.
+
+ Args:
+ custom_package: string. Java package given as an attribute to a rule to override
+ the java_package.
+ java_package: string. Java package inferred from the directory where the BUILD
+ containing the rule is.
+
+ Returns:
+ A boolean. True if custom_package or java_package contains "-" or is only one word.
+ Only checks java_package if custom_package is an empty string or None.
+ """
+ return (
+ (custom_package and _check_for_invalid_java_package(custom_package)) or
+ (not custom_package and _check_for_invalid_java_package(java_package))
+ )
+
+# The Android specific Java compile.
+def _compile_android(
+ ctx,
+ output_jar,
+ output_srcjar = None,
+ srcs = [],
+ resources = [],
+ javac_opts = [],
+ r_java = None,
+ deps = [],
+ exports = [],
+ plugins = [],
+ exported_plugins = [],
+ annotation_processor_additional_outputs = [],
+ annotation_processor_additional_inputs = [],
+ enable_deps_without_srcs = False,
+ neverlink = False,
+ constraints = ["android"],
+ strict_deps = "Error",
+ java_toolchain = None):
+ """Compiles the Java and IDL sources for Android.
+
+ Args:
+ ctx: The context.
+ output_jar: File. The artifact to place the compilation unit.
+ output_srcjar: File. The artifact to place the sources of the compilation
+ unit. Optional.
+ srcs: sequence of Files. A list of files and jars to be compiled.
+ resources: sequence of Files. Will be added to the output jar - see
+ java_library.resources. Optional.
+ javac_opts: sequence of strings. A list of the desired javac options.
+ Optional.
+ r_java: JavaInfo. The R.jar dependency. Optional.
+ deps: sequence of JavaInfo providers. A list of dependencies. Optional.
+ exports: sequence of JavaInfo providers. A list of exports. Optional.
+ plugins: sequence of JavaInfo providers. A list of plugins. Optional.
+ exported_plugins: sequence of JavaInfo providers. A list of exported
+ plugins. Optional.
+ annotation_processor_additional_outputs: sequence of Files. A list of
+ files produced by an annotation processor.
+ annotation_processor_additional_inputs: sequence of Files. A list of
+ files consumed by an annotation processor.
+ enable_deps_without_srcs: Enables the behavior from b/14473160.
+ neverlink: Bool. Makes the compiled unit a compile-time only dependency.
+ constraints: sequence of Strings. A list of constraints, to constrain the
+ target. Optional. By default [].
+ strict_deps: string. A string that specifies how to handle strict deps.
+ Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
+ see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
+ By default 'ERROR'.
+ java_toolchain: The java_toolchain Target.
+ host_javabase: The host_javabase Target.
+
+ Returns:
+ A JavaInfo provider representing the Java compilation.
+ """
+ if "android" not in constraints:
+ log.error(_ANDROID_CONSTRAINT_MISSING_ERROR)
+
+ if not srcs:
+ if deps and enable_deps_without_srcs:
+ # TODO(b/122039567): Produces a JavaInfo that exports the deps, but
+ # not the plugins. To reproduce the "deps without srcs" bug,
+ # b/14473160, behavior in Starlark.
+ exports = exports + [
+ android_common.enable_implicit_sourceless_deps_exports_compatibility(dep)
+ for dep in deps
+ ]
+ if not exports:
+ # Add a "no-op JavaInfo" to propagate the exported_plugins when
+ # deps or exports have not been specified by the target and
+ # additionally forces java_common.compile method to create the
+ # empty output jar and srcjar when srcs have not been specified.
+ noop_java_info = java_common.merge([])
+ exports = exports + [noop_java_info]
+
+ r_java_info = [r_java] if r_java else []
+
+ java_info = _compile(
+ ctx,
+ output_jar,
+ output_srcjar = output_srcjar,
+ srcs = srcs,
+ resources = resources,
+ javac_opts = javac_opts,
+ deps = r_java_info + deps,
+ # In native, the JavaInfo exposes two Jars as compile-time deps, the
+ # compiled sources and the Android R.java jars. To simulate this
+ # behavior, the JavaInfo of the R.jar is also exported.
+ exports = r_java_info + exports,
+ plugins = plugins,
+ exported_plugins = exported_plugins,
+ annotation_processor_additional_outputs = (
+ annotation_processor_additional_outputs
+ ),
+ annotation_processor_additional_inputs = (
+ annotation_processor_additional_inputs
+ ),
+ neverlink = neverlink,
+ constraints = constraints,
+ strict_deps = strict_deps,
+ java_toolchain = java_toolchain,
+ )
+ return java_info
+
+def _compile(
+ ctx,
+ output_jar,
+ output_srcjar = None,
+ srcs = [],
+ resources = [],
+ javac_opts = [],
+ deps = [],
+ exports = [],
+ plugins = [],
+ exported_plugins = [],
+ annotation_processor_additional_outputs = [],
+ annotation_processor_additional_inputs = [],
+ neverlink = False,
+ constraints = [],
+ strict_deps = "Error",
+ java_toolchain = None):
+ """Compiles the Java and IDL sources for Android.
+
+ Args:
+ ctx: The context.
+ output_jar: File. The artifact to place the compilation unit.
+ output_srcjar: File. The artifact to place the sources of the compilation
+ unit. Optional.
+ srcs: sequence of Files. A list of files and jars to be compiled.
+ resources: sequence of Files. Will be added to the output jar - see
+ java_library.resources. Optional.
+ javac_opts: sequence of strings. A list of the desired javac options.
+ Optional.
+ deps: sequence of JavaInfo providers. A list of dependencies. Optional.
+ exports: sequence of JavaInfo providers. A list of exports. Optional.
+ plugins: sequence of JavaInfo providers. A list of plugins. Optional.
+ exported_plugins: sequence of JavaInfo providers. A list of exported
+ plugins. Optional.
+ annotation_processor_additional_outputs: sequence of Files. A list of
+ files produced by an annotation processor.
+ annotation_processor_additional_inputs: sequence of Files. A list of
+ files consumed by an annotation processor.
+ resources: sequence of Files. Will be added to the output jar - see
+ java_library.resources. Optional.
+ neverlink: Bool. Makes the compiled unit a compile-time only dependency.
+ constraints: sequence of Strings. A list of constraints, to constrain the
+ target. Optional. By default [].
+ strict_deps: string. A string that specifies how to handle strict deps.
+ Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
+ see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
+ By default 'ERROR'.
+ java_toolchain: The java_toolchain Target.
+ host_javabase: The host_javabase Target.
+
+ Returns:
+ A JavaInfo provider representing the Java compilation.
+ """
+
+ # Split javac opts.
+ opts = []
+ for opt in javac_opts:
+ opts.extend(opt.split(" "))
+
+ # Separate the sources *.java from *.srcjar.
+ source_files = []
+ source_jars = []
+ for src in srcs:
+ if src.path.endswith(".srcjar"):
+ source_jars.append(src)
+ else:
+ source_files.append(src)
+
+ return java_common.compile(
+ ctx,
+ output = output_jar,
+ output_source_jar = output_srcjar,
+ source_files = source_files,
+ source_jars = source_jars,
+ resources = resources,
+ javac_opts = opts,
+ deps = deps,
+ exports = exports,
+ plugins = plugins,
+ exported_plugins = exported_plugins,
+ annotation_processor_additional_outputs = (
+ annotation_processor_additional_outputs
+ ),
+ annotation_processor_additional_inputs = (
+ annotation_processor_additional_inputs
+ ),
+ neverlink = neverlink,
+ strict_deps = strict_deps,
+ java_toolchain = java_toolchain[java_common.JavaToolchainInfo],
+ )
+
+def _singlejar(
+ ctx,
+ inputs,
+ output,
+ mnemonic = "SingleJar",
+ progress_message = "Merge into a single jar.",
+ exclude_build_data = False,
+ java_toolchain = None):
+ args = ctx.actions.args()
+ args.add("--output")
+ args.add(output)
+ args.add("--compression")
+ args.add("--normalize")
+ if exclude_build_data:
+ args.add("--exclude_build_data")
+ args.add("--warn_duplicate_resources")
+ if inputs:
+ args.add("--sources")
+ args.add_all(inputs)
+
+ ctx.actions.run(
+ executable = java_toolchain.java_toolchain.single_jar,
+ arguments = [args],
+ inputs = inputs,
+ outputs = [output],
+ mnemonic = mnemonic,
+ progress_message = progress_message,
+ )
+
+def _run(
+ ctx,
+ host_javabase,
+ **args):
+ """Run a java binary
+
+ Args:
+ ctx: The context.
+ host_javabase: Target. The host_javabase.
+ **args: Additional arguments to pass to ctx.actions.run(). Some will get modified.
+ """
+
+ if type(ctx) != "ctx":
+ fail("Expected type ctx for argument ctx, got %s" % type(ctx))
+
+ if type(host_javabase) != "Target":
+ fail("Expected type Target for argument host_javabase, got %s" % type(host_javabase))
+
+ # executable should be a File or a FilesToRunProvider
+ jar = args.get("executable")
+ if type(jar) == "FilesToRunProvider":
+ jar = jar.executable
+ elif type(jar) != "File":
+ fail("Expected type File or FilesToRunProvider for argument executable, got %s" % type(jar))
+
+ java_runtime = host_javabase[java_common.JavaRuntimeInfo]
+ args["executable"] = java_runtime.java_executable_exec_path
+
+ # inputs can be a list or a depset of File
+ inputs = args.get("inputs", default = [])
+ if type(inputs) == type([]):
+ args["inputs"] = depset(direct = inputs + [jar], transitive = [java_runtime.files])
+ else: # inputs is a depset
+ args["inputs"] = depset(direct = [jar], transitive = [inputs, java_runtime.files])
+
+ jar_args = ctx.actions.args()
+ jar_args.add("-jar", jar)
+
+ args["arguments"] = [jar_args] + args.get("arguments", default = [])
+
+ ctx.actions.run(**args)
+
+java = struct(
+ compile = _compile,
+ compile_android = _compile_android,
+ resolve_package = _resolve_package,
+ resolve_package_from_label = _resolve_package_from_label,
+ root = _root,
+ invalid_java_package = _invalid_java_package,
+ run = _run,
+ singlejar = _singlejar,
+)
diff --git a/rules/migration_tag_DONOTUSE.bzl b/rules/migration_tag_DONOTUSE.bzl
new file mode 100644
index 0000000..539aca9
--- /dev/null
+++ b/rules/migration_tag_DONOTUSE.bzl
@@ -0,0 +1,25 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel component for the Android Skylark Migration."""
+
+_MIGRATION_TAG = "__ANDROID_RULES_MIGRATION__"
+_TAG_ATTR = "tags"
+
+def add_migration_tag(attrs):
+ if _TAG_ATTR in attrs and attrs[_TAG_ATTR] != None:
+ attrs[_TAG_ATTR] = attrs[_TAG_ATTR] + [_MIGRATION_TAG]
+ else:
+ attrs[_TAG_ATTR] = [_MIGRATION_TAG]
+ return attrs
diff --git a/rules/path.bzl b/rules/path.bzl
new file mode 100644
index 0000000..28d18f1
--- /dev/null
+++ b/rules/path.bzl
@@ -0,0 +1,102 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Path APIs for the Android rules."""
+
+# TODO(djwhang): Get the path separator in a platform agnostic manner.
+_PATH_SEP = "/"
+_TEST_SRCDIR = "${TEST_SRCDIR}"
+
+def _is_absolute(path):
+ # TODO(djwhang): This is not cross platform safe. Windows absolute paths
+ # do not start with "//", rather "C:\".
+ return path.startswith(_PATH_SEP)
+
+def _split(path):
+ return path.split(_PATH_SEP)
+
+def _join(path_segments):
+ return _PATH_SEP.join(path_segments)
+
+def _normalize_path(path, posix = False):
+ return _PATH_SEP.join(
+ _normalize_path_fragments(
+ path.split(_PATH_SEP),
+ posix = posix,
+ ),
+ )
+
+def _normalize_path_fragments(path_fragments, posix = False):
+ normalized_path_fragments = []
+ for idx, fragment in enumerate(path_fragments):
+ if not fragment and idx > 0:
+ continue
+ if fragment == ".":
+ continue
+ if fragment == ".." and not posix:
+ if normalized_path_fragments:
+ last = normalized_path_fragments.pop()
+ if last == ".." or last == "":
+ normalized_path_fragments.append(last)
+ else:
+ continue
+ normalized_path_fragments.append(fragment)
+ if len(normalized_path_fragments) == 1 and not normalized_path_fragments[0]:
+ normalized_path_fragments.append("")
+ return normalized_path_fragments
+
+def _relative_path(path1, path2):
+ if not path1 or _is_absolute(path2):
+ return path2
+
+ path1_fragments = _normalize_path_fragments(_split(path1))
+ path2_fragments = _normalize_path_fragments(_split(path2))
+ path1_idx = len(path1_fragments) # index move backwards
+ path2_idx = -1
+ for idx, fragment in enumerate(path2_fragments):
+ if fragment == "..":
+ path1_idx -= 1
+ else:
+ path2_idx = idx
+ break
+
+ relative_path_fragments = []
+ if path1_idx >= 0:
+ relative_path_fragments.extend(path1_fragments[:path1_idx])
+ if path2_idx >= 0:
+ relative_path_fragments.extend(path2_fragments[path2_idx:])
+ return _join(_normalize_path_fragments(relative_path_fragments))
+
+def _make_test_srcdir_path(ctx, *path_fragments):
+ """Creates a filepath relative to TEST_SRCDIR.
+
+ Args:
+ ctx: Starlark context.
+ *path_fragments: Directories/file to join into a single path.
+ Returns:
+ A filepath that's spearated by the host's filepath separator.
+ """
+ fragments = [_TEST_SRCDIR, ctx.workspace_name]
+ for path_fragment in path_fragments:
+ fragments += _normalize_path_fragments(_split(path_fragment))
+ return _join(fragments)
+
+path = struct(
+ is_absolute = _is_absolute,
+ join = _join,
+ normalize = _normalize_path,
+ relative = _relative_path,
+ split = _split,
+ make_test_srcdir_path = _make_test_srcdir_path,
+)
diff --git a/rules/platforms/BUILD b/rules/platforms/BUILD
new file mode 100644
index 0000000..778c849
--- /dev/null
+++ b/rules/platforms/BUILD
@@ -0,0 +1,33 @@
+package(default_visibility = ["//visibility:public"])
+
+platform(
+ name = "armeabi_v7a",
+ constraint_values = [
+ "@platforms//cpu:armv7",
+ "@platforms//os:android",
+ ],
+)
+
+platform(
+ name = "arm64-v8a",
+ constraint_values = [
+ "@platforms//cpu:arm64",
+ "@platforms//os:android",
+ ],
+)
+
+platform(
+ name = "x86",
+ constraint_values = [
+ "@platforms//cpu:x86_32",
+ "@platforms//os:android",
+ ],
+)
+
+platform(
+ name = "x86_64",
+ constraint_values = [
+ "@platforms//cpu:x86_64",
+ "@platforms//os:android",
+ ],
+)
diff --git a/rules/processing_pipeline.bzl b/rules/processing_pipeline.bzl
new file mode 100644
index 0000000..6ba2ae7
--- /dev/null
+++ b/rules/processing_pipeline.bzl
@@ -0,0 +1,161 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Common implementation for processing pipelines."""
+
+PROVIDERS = "providers"
+VALIDATION_OUTPUTS = "validation_outputs"
+
+# TODO(djwhang): When a provider type can be retrieved from a Starlark provider
+# ProviderInfo is necessary. Once this is possible, processor methods can have a
+# uniform method signature foo(ctx, target_ctx) where we can pull the provider
+# off the target_ctx using the provider type.
+#
+# Yes, this effectively leads to producing a build rule like system within a
+# build rule, rather than resorting to rule based composition.
+ProviderInfo = provider(
+ "Stores metadata about the actual Starlark provider returned.",
+ fields = dict(
+ name = "The type of the provider",
+ value = "The actual provider",
+ runfiles = "Runfiles to pass to the DefaultInfo provider",
+ ),
+)
+
+_ProcessingPipelineInfo = provider(
+ "Stores functions that forms a rule's implementation.",
+ fields = dict(
+ processors = "Ordered dictionary of processing functions.",
+ finalize = "Function to form the final providers to propagate.",
+ ),
+)
+
+def _make_processing_pipeline(processors = dict(), finalize = None):
+ """Creates the combined processing pipeline.
+
+ Args:
+ processors: Ordered dictionary of processing functions.
+ finalize: Function to form the final providers to propagate.
+
+ Returns:
+ A _ProcessingPipelineInfo provider.
+ """
+ return _ProcessingPipelineInfo(
+ processors = processors,
+ finalize = finalize,
+ )
+
+def _run(ctx, java_package, processing_pipeline):
+ """Runs the processing pipeline and populates the target context.
+
+ Args:
+ ctx: The context.
+ java_package: The java package resolved from the target's path
+ or the custom_package attr.
+ processing_pipeline: The _ProcessingPipelineInfo provider for this target.
+
+ Returns:
+ The output of the _ProcessingPipelineInfo.finalize function.
+ """
+ target_ctx = dict(
+ java_package = java_package,
+ providers = [],
+ validation_outputs = [],
+ runfiles = ctx.runfiles(),
+ )
+
+ for execute in processing_pipeline.processors.values():
+ info = execute(ctx, **target_ctx)
+ if info:
+ if info.name in target_ctx:
+ fail("%s provider already registered in target context" % info.name)
+ target_ctx[info.name] = info.value
+ target_ctx[PROVIDERS].extend(getattr(info.value, PROVIDERS, []))
+ target_ctx[VALIDATION_OUTPUTS].extend(getattr(info.value, VALIDATION_OUTPUTS, []))
+ if hasattr(info, "runfiles") and info.runfiles:
+ target_ctx["runfiles"] = target_ctx["runfiles"].merge(info.runfiles)
+
+ return processing_pipeline.finalize(ctx, **target_ctx)
+
+def _prepend(processors, **new_processors):
+ """Prepends processors in a given processing pipeline.
+
+ Args:
+ processors: The dictionary representing the processing pipeline.
+ **new_processors: The processors to add where the key represents the
+ name of the processor and value is the function pointer to the new
+ processor.
+
+ Returns:
+ A dictionary which represents the new processing pipeline.
+ """
+ updated_processors = dict()
+ for name, processor in new_processors.items():
+ updated_processors[name] = processor
+
+ for key in processors.keys():
+ updated_processors[key] = processors[key]
+
+ return updated_processors
+
+def _append(processors, **new_processors):
+ """Appends processors in a given processing pipeline.
+
+ Args:
+ processors: The dictionary representing the processing pipeline.
+ **new_processors: The processors to append where the key represents the
+ name of the processor and value is the function pointer to the new
+ processor.
+
+ Returns:
+ A dictionary which represents the new processing pipeline.
+ """
+ updated_processors = dict(processors)
+ for name, processor in new_processors.items():
+ updated_processors[name] = processor
+
+ return updated_processors
+
+def _replace(processors, **new_processors):
+ """Replace processors in a given processing pipeline.
+
+ Args:
+ processors: The dictionary representing the processing pipeline.
+ **new_processors: The processors to override where the key represents the
+ name of the processor and value is the function pointer to the new
+ processor.
+
+ Returns:
+ A dictionary which represents the new processing pipeline.
+ """
+ updated_processors = dict(processors)
+ for name, processor in new_processors.items():
+ if name not in processors:
+ fail("Error, %s not found, unable to override." % name)
+
+ # NOTE: Overwriting an existing value does not break iteration order.
+ # However, if a new processor is being added that needs to be injected
+ # between other processors, the processing pipeline dictionary will need
+ # to be recreated.
+ updated_processors[name] = processor
+
+ return updated_processors
+
+processing_pipeline = struct(
+ make_processing_pipeline = _make_processing_pipeline,
+ run = _run,
+ prepend = _prepend,
+ append = _append,
+ replace = _replace,
+)
diff --git a/rules/proguard.bzl b/rules/proguard.bzl
new file mode 100644
index 0000000..837d622
--- /dev/null
+++ b/rules/proguard.bzl
@@ -0,0 +1,110 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android Proguard library for the Android rules."""
+
+_ProguardContextInfo = provider(
+ doc = "Contains data from processing Proguard specs.",
+ fields = dict(
+ proguard_configs = "The direct proguard configs",
+ transitive_proguard_configs =
+ "The proguard configs within the transitive closure of the target",
+ providers = "The list of all providers to propagate.",
+ ),
+)
+
+def _validate_proguard_spec(
+ ctx,
+ out_validated_proguard_spec,
+ proguard_spec,
+ proguard_allowlister):
+ args = ctx.actions.args()
+ args.add("--path", proguard_spec)
+ args.add("--output", out_validated_proguard_spec)
+
+ ctx.actions.run(
+ executable = proguard_allowlister,
+ arguments = [args],
+ inputs = [proguard_spec],
+ outputs = [out_validated_proguard_spec],
+ mnemonic = "ValidateProguard",
+ progress_message = (
+ "Validating proguard configuration %s" % proguard_spec.short_path
+ ),
+ )
+
+def _process(
+ ctx,
+ proguard_configs = [],
+ proguard_spec_providers = [],
+ proguard_allowlister = None):
+ """Processes Proguard Specs
+
+ Args:
+ ctx: The context.
+ proguard_configs: sequence of Files. A list of proguard config files to be
+ processed. Optional.
+ proguard_spec_providers: sequence of ProguardSpecProvider providers. A
+ list of providers from the dependencies, exports, plugins,
+ exported_plugins, etc. Optional.
+ proguard_allowlister: The proguard_allowlister exeutable provider.
+
+ Returns:
+ A _ProguardContextInfo provider.
+ """
+
+ # TODO(djwhang): Look to see if this can be just a validation action and the
+ # proguard_spec provided by the rule can be propagated.
+ validated_proguard_configs = []
+ for proguard_spec in proguard_configs:
+ validated_proguard_spec = ctx.actions.declare_file(
+ "validated_proguard/%s/%s_valid" %
+ (ctx.label.name, proguard_spec.path),
+ )
+ _validate_proguard_spec(
+ ctx,
+ validated_proguard_spec,
+ proguard_spec,
+ proguard_allowlister,
+ )
+ validated_proguard_configs.append(validated_proguard_spec)
+
+ transitive_validated_proguard_configs = []
+ for info in proguard_spec_providers:
+ transitive_validated_proguard_configs.append(info.specs)
+
+ transitive_proguard_configs = depset(
+ validated_proguard_configs,
+ transitive = transitive_validated_proguard_configs,
+ order = "preorder",
+ )
+ return _ProguardContextInfo(
+ proguard_configs = proguard_configs,
+ transitive_proguard_configs = transitive_proguard_configs,
+ providers = [
+ ProguardSpecProvider(transitive_proguard_configs),
+ # TODO(b/152659272): Remove this once the android_archive rule is
+ # able to process a transitive closure of deps to produce an aar.
+ AndroidProguardInfo(proguard_configs),
+ ],
+ )
+
+proguard = struct(
+ process = _process,
+)
+
+testing = struct(
+ validate_proguard_spec = _validate_proguard_spec,
+ ProguardContextInfo = _ProguardContextInfo,
+)
diff --git a/rules/providers.bzl b/rules/providers.bzl
new file mode 100644
index 0000000..fd92708
--- /dev/null
+++ b/rules/providers.bzl
@@ -0,0 +1,118 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel providers for Android rules."""
+
+
+
+AndroidAppsInfo = provider(
+ doc = "Provides information about app to install.",
+ fields = dict(
+ apps = "List of app provider artifacts.",
+ ),
+)
+
+
+
+
+
+
+
+
+AndroidJavaInfo = provider(
+ doc = "Provides outputs for the Android Java Compilation",
+ fields = dict(
+ aidl = "AndroidIdlInfo",
+ aide = "AndroidIdeInfo",
+ java = "JavaInfo",
+ ),
+)
+
+AndroidFilteredJdepsInfo = provider(
+ doc = "Provides a filtered jdeps proto.",
+ fields = dict(
+ jdeps = "Filtered jdeps",
+ ),
+)
+
+
+StarlarkApkInfo = provider(
+ doc = "Provides APK outputs of a rule.",
+ fields = dict(
+ keystore = "Keystore used to sign the APK. Deprecated, prefer signing_keys.",
+ signing_keys = "List of keys used to sign the APK",
+ signing_lineage = "Optional sigining lineage file",
+ signed_apk = "Signed APK",
+ unsigned_apk = "Unsigned APK",
+ ),
+)
+
+ResourcesNodeInfo = provider(
+ doc = "Provides information for building ResourceProcessorBusyBox flags",
+ fields = dict(
+ label = "A label, the target's label",
+
+ # Assets related fields
+ assets = "A depset of files, assets files of the target",
+ assets_dir = "A string, the name of the assets directory",
+ assets_symbols = "A file, the merged assets",
+ compiled_assets = "A file, the compiled assets",
+
+ # Resource related fields
+ resource_files = "A depset of files, resource files of the target",
+ compiled_resources = "A file, the compiled resources",
+ r_txt = "A file, the R.txt file",
+ manifest = "A file, the AndroidManifest.xml",
+ # TODO(ostonge): Add the manifest if it's exported, otherwise leave empty
+ exports_manifest = "Boolean, whether the manifest is exported",
+ ),
+)
+
+StarlarkAndroidResourcesInfo = provider(
+ doc = "Provides information about direct and transitive resources",
+ fields = dict(
+ direct_resources_nodes = "Depset of ResourcesNodeInfo providers, can contain multiple providers due to exports",
+ transitive_resources_nodes = "Depset of transitive ResourcesNodeInfo providers, not including directs",
+ transitive_assets = "Depset of transitive assets files",
+ transitive_assets_symbols = "Depset of transitive merged assets",
+ transitive_compiled_assets = "Depset of transitive compiled assets",
+ direct_compiled_resources = "Depset of direct compiled_resources, can contain multiple files due to exports",
+ transitive_compiled_resources = "Depset of transitive compiled resources",
+ transitive_manifests = "Depset of transitive manifests",
+ transitive_r_txts = "Depset of transitive R.txt files",
+ transitive_resource_files = "Depset of transitive resource files",
+ ),
+)
+
+AndroidLintRulesInfo = provider(
+ doc = "Provides extra lint rules to use with AndroidLint.",
+ fields = dict(
+ lint_jar = "A file, a lint jar found in an aar.",
+ ),
+)
+
+
+
+FailureInfo = provider(
+ fields = dict(
+ error = "Error message",
+ ),
+)
+
+AndroidBundleInfo = provider(
+ doc = "Provides .aab outputs from a rule.",
+ fields = dict(
+ unsigned_aab = "File, the unsigned .aab",
+ ),
+)
diff --git a/rules/res_v3_dummy_AndroidManifest.xml b/rules/res_v3_dummy_AndroidManifest.xml
new file mode 100644
index 0000000..8072ee0
--- /dev/null
+++ b/rules/res_v3_dummy_AndroidManifest.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest />
diff --git a/rules/res_v3_dummy_R.txt b/rules/res_v3_dummy_R.txt
new file mode 100644
index 0000000..2b3d8b7
--- /dev/null
+++ b/rules/res_v3_dummy_R.txt
@@ -0,0 +1 @@
+int string fake 0x00000000
diff --git a/rules/resources.bzl b/rules/resources.bzl
new file mode 100644
index 0000000..386196d
--- /dev/null
+++ b/rules/resources.bzl
@@ -0,0 +1,1638 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android Resources."""
+
+load(":attrs.bzl", _attrs = "attrs")
+load(":busybox.bzl", _busybox = "busybox")
+load(":common.bzl", _common = "common")
+load(":java.bzl", _java = "java")
+load(":path.bzl", _path = "path")
+load(
+ ":providers.bzl",
+ "ResourcesNodeInfo",
+ "StarlarkAndroidResourcesInfo",
+)
+load(
+ ":utils.bzl",
+ "utils",
+ _compilation_mode = "compilation_mode",
+ _log = "log",
+)
+
+_RESOURCE_FOLDER_TYPES = [
+ "anim",
+ "animator",
+ "color",
+ "drawable",
+ "font",
+ "interpolator",
+ "layout",
+ "menu",
+ "mipmap",
+ "navigation",
+ "values",
+ "xml",
+ "raw",
+ "transition",
+]
+
+_RESOURCE_QUALIFIER_SEP = "-"
+
+_MANIFEST_MISSING_ERROR = (
+ "In target %s, manifest attribute is required when resource_files or " +
+ "assets are defined."
+)
+
+_ASSET_DEFINITION_ERROR = (
+ "In target %s, the assets and assets_dir attributes should be either " +
+ "both empty or non-empty."
+)
+
+_JAVA_PACKAGE_MISSING_ERROR = (
+ "In target %s, a java package is required when stamping " +
+ "the manifest."
+)
+
+_INCORRECT_RESOURCE_LAYOUT_ERROR = (
+ "'%s' is not in the expected resource directory structure of " +
+ "<resource directory>/{%s}/<file>" % (",").join(_RESOURCE_FOLDER_TYPES)
+)
+
+# Keys for manifest_values
+_VERSION_NAME = "versionName"
+_VERSION_CODE = "versionCode"
+
+# Resources context attributes.
+_ASSETS_PROVIDER = "assets_provider"
+_DEFINES_RESOURCES = "defines_resources"
+_DIRECT_ANDROID_RESOURCES = "direct_android_resources"
+_MERGED_MANIFEST = "merged_manifest"
+_PROVIDERS = "providers"
+_R_JAVA = "r_java"
+_RESOURCES_APK = "resources_apk"
+_VALIDATION_RESULTS = "validation_results"
+_VALIDATION_OUTPUTS = "validation_outputs"
+_RESOURCES_PROVIDER = "resources_provider"
+_STARLARK_PROCESSED_MANIFEST = "starlark_processed_manifest"
+_STARLARK_R_TXT = "starlark_r_txt"
+_STARLARK_PROCESSED_RESOURCES = "starlark_processed_resources"
+
+_ResourcesProcessContextInfo = provider(
+ "Resources context object",
+ fields = {
+ _DEFINES_RESOURCES: "If local resources were defined.",
+ _DIRECT_ANDROID_RESOURCES: "Direct android resources.",
+ _MERGED_MANIFEST: "Merged manifest.",
+ _PROVIDERS: "The list of all providers to propagate.",
+ _R_JAVA: "JavaInfo for R.jar.",
+ _RESOURCES_APK: "ResourcesApk.",
+ _VALIDATION_RESULTS: "List of validation results.",
+ _VALIDATION_OUTPUTS: "List of outputs given to OutputGroupInfo _validation group",
+
+ # TODO(djwhang): The android_library aar generation requires direct
+ # access to providers. Remove once aar is its own rule.
+ _ASSETS_PROVIDER: "AndroidAssetsInfo provider.",
+ _RESOURCES_PROVIDER: "AndroidResourcesInfo provider.",
+ _STARLARK_PROCESSED_MANIFEST: "The processed manifest from the starlark resource processing pipeline.",
+ _STARLARK_R_TXT: "The R.txt from the starlark resource processing pipeline.",
+ _STARLARK_PROCESSED_RESOURCES: "The processed resources from the starlark processing pipeline.",
+ },
+)
+
+# Packaged resources context attributes.
+_PACKAGED_FINAL_MANIFEST = "processed_manifest"
+_PACKAGED_RESOURCE_APK = "resources_apk"
+_PACKAGED_CLASS_JAR = "class_jar"
+_PACKAGED_VALIDATION_RESULT = "validation_result"
+
+_ResourcesPackageContextInfo = provider(
+ "Packaged resources context object",
+ fields = {
+ _PACKAGED_FINAL_MANIFEST: "Final processed manifest.",
+ _PACKAGED_RESOURCE_APK: "ResourceApk.",
+ _PACKAGED_CLASS_JAR: "R class jar.",
+ _PACKAGED_VALIDATION_RESULT: "Validation result.",
+ _R_JAVA: "JavaInfo for R.jar",
+ _PROVIDERS: "The list of all providers to propagate.",
+ },
+)
+
+def _generate_dummy_manifest(
+ ctx,
+ out_manifest = None,
+ java_package = None,
+ min_sdk_version = None):
+ content = """<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="%s">""" % java_package
+
+ if min_sdk_version:
+ content = content + """
+ <uses-sdk android:minSdkVersion="%s" />""" % min_sdk_version
+
+ content = content + """
+ <application>
+ </application>
+</manifest>"""
+
+ ctx.actions.write(
+ output = out_manifest,
+ content = content,
+ )
+
+def _add_g3itr(
+ ctx,
+ manifest = None,
+ out_manifest = None,
+ xsltproc = None,
+ instrument_xslt = None):
+ """Adds Google3InstrumentationTestRunner instrumentation element to the manifest.
+
+ Element is only added if the manifest contains an instrumentation element with
+ name "android.test.InstrumentationTestRunner". The added element's name attr is
+ "com.google.android.apps.common.testing.testrunner.Google3InstrumentationTestRunner".
+
+ Args:
+ ctx: The context.
+ manifest: File. The AndroidManifest.xml file.
+ out_manifest: File. The transformed AndroidManifest.xml.
+ xsltproc: FilesToRunProvider. The xsltproc executable or
+ FilesToRunProvider.
+ instrument_xslt: File. The add_g3itr.xslt file describing the xslt
+ transformation to apply.
+ """
+ args = ctx.actions.args()
+ args.add("--nonet")
+ args.add("--novalid")
+ args.add("-o", out_manifest)
+ args.add(instrument_xslt)
+ args.add(manifest)
+
+ ctx.actions.run(
+ executable = xsltproc,
+ arguments = [args],
+ inputs = [manifest, instrument_xslt],
+ outputs = [out_manifest],
+ mnemonic = "AddG3ITRStarlark",
+ progress_message = "Adding G3ITR to test manifest for %s" % ctx.label,
+ )
+
+def _get_legacy_mergee_manifests(resources_infos):
+ all_dependencies = depset(
+ transitive = [
+ ri.direct_android_resources
+ for ri in resources_infos
+ ] + [
+ ri.transitive_android_resources
+ for ri in resources_infos
+ ],
+ )
+
+ mergee_manifests = []
+ for dep in all_dependencies.to_list():
+ if dep.to_provider.manifest.exports_manifest:
+ mergee_manifests.append(dep.to_provider.manifest.manifest)
+
+ return depset(mergee_manifests)
+
+def _legacy_mergee_manifest(manifest):
+ sort_key = manifest.short_path + "#"
+ return sort_key + "--mergee=" + manifest.path
+
+def _legacy_merge_manifests(
+ ctx,
+ out_merged_manifest = None,
+ manifest = None,
+ mergee_manifests = None,
+ legacy_merger = None):
+ """Merges manifests with the legacy manifest merger."
+
+ This should not be called with empty mergee_manifests.
+
+ Args:
+ ctx: The context.
+ out_merged_manifest: File. The merged AndroidManifest.xml.
+ manifest: File. The AndroidManifest.xml.
+ mergee_manifests: A sequence of Files. All transitive manifests to be merged.
+ legacy_merger: A FilesToRunProvider. The legacy manifest merger executable.
+ """
+ args = ctx.actions.args()
+ args.use_param_file("%s", use_always = True)
+ args.set_param_file_format("multiline")
+ args.add("--merger=%s" % manifest.path)
+ args.add("--exclude_permission=all")
+ args.add("--output=%s" % out_merged_manifest.path)
+
+ manifest_params = ctx.actions.declare_file(ctx.label.name + "/legacy_merger.params")
+ manifest_args = ctx.actions.args()
+ manifest_args.use_param_file("%s", use_always = True)
+ manifest_args.set_param_file_format("multiline")
+ manifest_args.add_joined(mergee_manifests, map_each = _legacy_mergee_manifest, join_with = "\n")
+ ctx.actions.run_shell(
+ command = """
+# Sorts the mergee manifests by path and combines with other busybox args.
+set -e
+SORTED=`sort $1 | sed 's/^.*#//'`
+cat $2 > $3
+echo "$SORTED" >> $3
+""",
+ arguments = [manifest_args, args, manifest_params.path],
+ outputs = [manifest_params],
+ )
+ args = ctx.actions.args()
+ args.add(manifest_params, format = "--flagfile=%s")
+
+ ctx.actions.run(
+ executable = legacy_merger,
+ arguments = [args],
+ inputs = depset([manifest, manifest_params], transitive = [mergee_manifests]),
+ outputs = [out_merged_manifest],
+ mnemonic = "StarlarkLegacyAndroidManifestMerger",
+ progress_message = "Merging Android Manifests",
+ )
+
+def _make_databinding_outputs(
+ ctx,
+ resource_files):
+ """Helper method to create arguments for the process_databinding busybox tool.
+
+ Declares databinding-processed resource files that are generated by the
+ PROCESS_DATABINDING busybox tool, which must be declared underneath an output
+ resources directory and namespaced by their paths. The busybox takes the
+ output directory exec path and generates the underlying resource files.
+
+ Args:
+ ctx: The context.
+ resource_files: List of Files. The android resource files to be processed by
+ _process_databinding.
+
+ Returns:
+ A tuple containing the list of declared databinding processed resource files and the
+ output resource directory path expected by the busybox. The path is a full path.
+ """
+
+ # TODO(b/160907203): Clean up databinding_rel_path. We capitalize "Databinding" here to avoid
+ # conflicting with native artifact file names. This is changed back to "databinding" during
+ # process_starlark so that compiled resources exactly match those of the native resource
+ # processing pipeline. Even a single character mismatch in the file names causes selected
+ # resources to differ in the final APK.
+ databinding_rel_path = _path.join(["Databinding-processed-resources", ctx.label.name])
+ databinding_processed_resources = [
+ ctx.actions.declare_file(_path.join([databinding_rel_path, f.path]))
+ for f in resource_files
+ ]
+ databinding_resources_dirname = _path.join([
+ ctx.bin_dir.path,
+ ctx.label.package,
+ databinding_rel_path,
+ ])
+ return databinding_processed_resources, databinding_resources_dirname
+
+def _fix_databinding_compiled_resources(
+ ctx,
+ out_compiled_resources = None,
+ compiled_resources = None,
+ zip_tool = None):
+ """Fix compiled resources to match those produced by the native pipeline.
+
+ Changes "Databinding" to "databinding" in each compiled resource .flat file name and header.
+
+ Args:
+ ctx: The context.
+ out_compiled_resources: File. The modified compiled_resources output.
+ compiled_resources: File. The compiled_resources zip.
+ """
+ ctx.actions.run_shell(
+ outputs = [out_compiled_resources],
+ inputs = [compiled_resources],
+ tools = [zip_tool],
+ arguments = [compiled_resources.path, out_compiled_resources.path, zip_tool.executable.path],
+ command = """#!/bin/bash
+set -e
+
+IN_DIR=$(mktemp -d)
+OUT_DIR=$(mktemp -d)
+CUR_PWD=$(pwd)
+
+if zipinfo -t "$1"; then
+ ORDERED_LIST=`(unzip -l "$1" | sed -e '1,3d' | head -n -2 | tr -s " " | cut -d " " -f5)`
+
+ unzip -q "$1" -d "$IN_DIR"
+
+ # Iterate through the ordered list, change "Databinding" to "databinding" in the file header
+ # and file name and zip the files with the right comment
+ for FILE in $ORDERED_LIST; do
+ cd "$IN_DIR"
+ if [ -f "$FILE" ]; then
+ sed -i 's/Databinding\\-processed\\-resources/databinding\\-processed\\-resources/g' "$FILE"
+ NEW_NAME=`echo "$FILE" | sed 's/Databinding\\-processed\\-resources/databinding\\-processed\\-resources/g' | sed 's#'"$IN_DIR"'/##g'`
+ mkdir -p `dirname "$OUT_DIR/$NEW_NAME"` && touch "$OUT_DIR/$NEW_NAME"
+ cp -p "$FILE" "$OUT_DIR/$NEW_NAME"
+
+ PATH_SEGMENTS=(`echo ${FILE} | tr '/' ' '`)
+ BASE_PATH_SEGMENT="${PATH_SEGMENTS[0]}"
+ COMMENT=
+ if [ "${BASE_PATH_SEGMENT}" == "generated" ]; then
+ COMMENT="generated"
+ elif [ "${BASE_PATH_SEGMENT}" == "default" ]; then
+ COMMENT="default"
+ fi
+
+ cd "$OUT_DIR"
+ "$CUR_PWD/$3" -jt -X -0 -q -r -c "$CUR_PWD/$2" $NEW_NAME <<EOM
+${COMMENT}
+EOM
+ fi
+ done
+
+ cd "$CUR_PWD"
+ touch -r "$1" "$2"
+else
+ cp -p "$1" "$2"
+fi
+ """,
+ )
+
+def _is_resource_shrinking_enabled(
+ shrink_resources,
+ use_android_resource_shrinking):
+ if shrink_resources == _attrs.tristate.auto:
+ return use_android_resource_shrinking
+ return shrink_resources == _attrs.tristate.yes
+
+def _should_shrink_resource_cycles(
+ use_android_resource_cycle_shrinking,
+ resource_shrinking_enabled):
+ if use_android_resource_cycle_shrinking and not resource_shrinking_enabled:
+ fail("resource cycle shrinking can only be enabled when resource shrinking is enabled")
+ return use_android_resource_cycle_shrinking
+
+def _filter_multi_cpu_configuration_targets(
+ targets):
+ """Filter out duplicate split-configured targets.
+
+ This method simulates logic in the native rule where if a label_list attribute has
+ split-configuration but is requested in target mode, only targets from the first architecture
+ are returned. Without this filtering there are duplicate targets if multiple CPU configurations
+ are specified on the command line. This is the case with deps in the packaging step of
+ android_binary.
+
+ Args:
+ targets: A list of Target objects.
+
+ Returns:
+ A list of Target objects with duplicates removed.
+ """
+ seen_labels = {}
+ filtered_targets = []
+ for t in targets:
+ if t.label in seen_labels:
+ continue
+ seen_labels[t.label] = True
+ filtered_targets.append(t)
+ return filtered_targets
+
+def _package(
+ ctx,
+ assets = [],
+ assets_dir = None,
+ deps = [],
+ manifest = None,
+ manifest_values = None,
+ instruments = None,
+ resource_configs = None,
+ densities = [],
+ resource_files = [],
+ nocompress_extensions = [],
+ java_package = None,
+ compilation_mode = _compilation_mode.FASTBUILD,
+ shrink_resources = None,
+ use_android_resource_shrinking = None,
+ use_android_resource_cycle_shrinking = None,
+ use_legacy_manifest_merger = False,
+ should_throw_on_conflict = True,
+ enable_data_binding = False,
+ enable_manifest_merging = True,
+ aapt = None,
+ android_jar = None,
+ legacy_merger = None,
+ xsltproc = None,
+ instrument_xslt = None,
+ busybox = None,
+ host_javabase = None):
+ """Package resources for top-level rules.
+
+ Args:
+ ctx: The context.
+ assets: sequence of Files. A list of assets to be packaged. All files be
+ under the assets_dir directory in the corresponding package.
+ assets_dir: String. A string giving the path to the files in assets. The
+ pair assets and assets_dir describe packaged assets and either both
+ parameters should be provided or none of them.
+ deps: sequence of Targets. The list of other libraries targets to link
+ against.
+ manifest: File. The input top-level AndroidManifest.xml.
+ manifest_values: String dictionary. Manifest values to substitute.
+ instruments: Optional target. The value of the "instruments" attr if set.
+ resource_configs: sequence of Strings. A list of resource_configuration_filters
+ to apply.
+ densities: sequence of Strings. A list of densities to filter for when building
+ the apk.
+ resource_files: sequence of Files. A list of Android resource files
+ to be processed.
+ nocompress_extensions: sequence of Strings. File extension to leave uncompressed
+ in the apk.
+ java_package: String. Java package for which java sources will be
+ generated. By default the package is inferred from the directory where
+ the BUILD file containing the rule is.
+ compilation_mode: String. A string that represents compilation mode. The
+ list of expected values are as follows: dbg, fastbuild, opt.
+ shrink_resources: Tristate. Whether resource shrinking is enabled by the rule.
+ use_android_resource_shrinking: Bool. Flag that controls the default value for
+ shrink_resources if the tristate value is auto (-1).
+ use_android_resource_cycle_shrinking: Bool. Flag that enables more shrinking of
+ code and resources by instructing AAPT2 to emit conditional Proguard keep rules.
+ use_legacy_manifest_merger: A boolean. Whether to use the legacy manifest merger
+ instead of the android manifest merger.
+ should_throw_on_conflict: A boolean. Determines whether an error should be thrown
+ when a resource conflict occurs.
+ enable_data_binding: boolean. If true, processesing the data binding
+ expressions in layout resources included through the resource_files
+ parameter is enabled. Without this setting, data binding expressions
+ produce build failures.
+ enable_manifest_merging: boolean. If true, manifest merging will be performed.
+ aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider.
+ android_jar: File. The Android jar.
+ legacy_merger: FilesToRunProvider. The legacy manifest merger executable.
+ xsltproc: FilesToRunProvider. The xsltproc executable or
+ FilesToRunProvider.
+ instrument_xslt: File. The add_g3itr.xslt file describing the xslt
+ transformation to apply.
+ busybox: FilesToRunProvider. The ResourceBusyBox executable or
+ FilesToRunprovider
+ host_javabase: A Target. The host javabase.
+
+ Returns:
+ A ResourcesPackageContextInfo containing packaged resource artifacts and
+ providers.
+ """
+ _validate_resources(resource_files)
+
+ # Filtering is necessary if a build is requested with multiple CPU configurations.
+ deps = _filter_multi_cpu_configuration_targets(deps)
+
+ packaged_resources_ctx = {
+ _PROVIDERS: [],
+ }
+
+ g3itr_manifest = manifest
+
+ if xsltproc or instrument_xslt:
+ g3itr_manifest = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "add_g3itr/AndroidManifest.xml",
+ )
+ _add_g3itr(
+ ctx,
+ out_manifest = g3itr_manifest,
+ manifest = manifest,
+ xsltproc = xsltproc,
+ instrument_xslt = instrument_xslt,
+ )
+
+ direct_resources_nodes = []
+ transitive_resources_nodes = []
+ transitive_assets = []
+ transitive_assets_symbols = []
+ transitive_compiled_assets = []
+ transitive_resource_files = []
+ transitive_compiled_resources = []
+ transitive_manifests = []
+ transitive_r_txts = []
+ for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, deps):
+ direct_resources_nodes.append(dep.direct_resources_nodes)
+ transitive_resources_nodes.append(dep.transitive_resources_nodes)
+ transitive_assets.append(dep.transitive_assets)
+ transitive_assets_symbols.append(dep.transitive_assets_symbols)
+ transitive_compiled_assets.append(dep.transitive_compiled_assets)
+ transitive_resource_files.append(dep.transitive_resource_files)
+ transitive_compiled_resources.append(dep.transitive_compiled_resources)
+ transitive_manifests.append(dep.transitive_manifests)
+ transitive_r_txts.append(dep.transitive_r_txts)
+
+ mergee_manifests = depset([
+ node_info.manifest
+ for node_info in depset(transitive = transitive_resources_nodes + direct_resources_nodes).to_list()
+ if node_info.exports_manifest
+ ])
+
+ # TODO(b/156763506): Add analysis tests to verify logic around when manifest merging is configured.
+ # TODO(b/154153771): Run the android merger if mergee_manifests or manifest values are present.
+ merged_manifest = g3itr_manifest
+ if enable_manifest_merging and (manifest_values or mergee_manifests):
+ if use_legacy_manifest_merger:
+ # Legacy manifest merger only runs if mergee manifests are present
+ if mergee_manifests:
+ merged_manifest = ctx.actions.declare_file(
+ "_migrated/_merged/" + ctx.label.name + "/AndroidManifest.xml",
+ )
+ _legacy_merge_manifests(
+ ctx,
+ out_merged_manifest = merged_manifest,
+ manifest = g3itr_manifest,
+ mergee_manifests = mergee_manifests,
+ legacy_merger = legacy_merger,
+ )
+ else:
+ merged_manifest = ctx.actions.declare_file(
+ "_migrated/_merged/" + ctx.label.name + "/AndroidManifest.xml",
+ )
+ _busybox.merge_manifests(
+ ctx,
+ out_file = merged_manifest,
+ out_log_file = ctx.actions.declare_file(
+ "_migrated/_merged/" + ctx.label.name + "/manifest_merger_log.txt",
+ ),
+ manifest = g3itr_manifest,
+ mergee_manifests = mergee_manifests,
+ manifest_values = manifest_values,
+ merge_type = "APPLICATION",
+ java_package = java_package,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+
+ processed_resources = resource_files
+ databinding_info = None
+ if enable_data_binding:
+ databinding_info = ctx.actions.declare_file("_migrated/databinding/" + ctx.label.name + "/layout-info.zip")
+ processed_resources, resources_dirname = _make_databinding_outputs(
+ ctx,
+ resource_files,
+ )
+ _busybox.process_databinding(
+ ctx,
+ out_databinding_info = databinding_info,
+ out_databinding_processed_resources = processed_resources,
+ databinding_resources_dirname = resources_dirname,
+ resource_files = resource_files,
+ java_package = java_package,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+
+ resource_apk = ctx.actions.declare_file(ctx.label.name + "_migrated/.ap_")
+ r_java = ctx.actions.declare_file("_migrated/" + ctx.label.name + ".srcjar")
+ r_txt = ctx.actions.declare_file(ctx.label.name + "_migrated/_symbols/R.txt")
+ processed_manifest = ctx.actions.declare_file(ctx.label.name + "_migrated/_processed_manifest/AndroidManifest.xml")
+ proguard_cfg = ctx.actions.declare_file(
+ "_migrated/proguard/%s/_%s_proguard.cfg" % (ctx.label.name, ctx.label.name),
+ )
+ main_dex_proguard_cfg = ctx.actions.declare_file(
+ "_migrated/proguard/%s/main_dex_%s_proguard.cfg" %
+ (ctx.label.name, ctx.label.name),
+ )
+ resource_files_zip = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_files/resource_files.zip",
+ )
+ _busybox.package(
+ ctx,
+ out_file = resource_apk,
+ out_r_src_jar = r_java,
+ out_r_txt = r_txt,
+ out_symbols = ctx.actions.declare_file("_migrated/" + ctx.label.name + "_symbols/merged.bin"),
+ out_manifest = processed_manifest,
+ out_proguard_cfg = proguard_cfg,
+ out_main_dex_proguard_cfg = main_dex_proguard_cfg,
+ out_resource_files_zip = resource_files_zip,
+ application_id = manifest_values.get("applicationId", None),
+ manifest = merged_manifest,
+ assets = assets,
+ assets_dir = assets_dir,
+ resource_files = processed_resources,
+ direct_resources_nodes =
+ depset(transitive = direct_resources_nodes, order = "preorder"),
+ transitive_resources_nodes =
+ depset(transitive = transitive_resources_nodes, order = "preorder"),
+ transitive_assets = transitive_assets,
+ transitive_compiled_assets = transitive_compiled_assets,
+ transitive_resource_files = transitive_resource_files,
+ transitive_compiled_resources = transitive_compiled_resources,
+ transitive_manifests = transitive_manifests,
+ transitive_r_txts = transitive_r_txts,
+ resource_configs = resource_configs,
+ densities = densities,
+ nocompress_extensions = nocompress_extensions,
+ java_package = java_package,
+ version_name = manifest_values[_VERSION_NAME] if _VERSION_NAME in manifest_values else None,
+ version_code = manifest_values[_VERSION_CODE] if _VERSION_CODE in manifest_values else None,
+ android_jar = android_jar,
+ aapt = aapt,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ debug = compilation_mode != _compilation_mode.OPT,
+ should_throw_on_conflict = should_throw_on_conflict,
+ )
+ packaged_resources_ctx[_PACKAGED_FINAL_MANIFEST] = processed_manifest
+ packaged_resources_ctx[_PACKAGED_RESOURCE_APK] = resource_apk
+ packaged_resources_ctx[_PACKAGED_VALIDATION_RESULT] = resource_files_zip
+
+ resource_shrinking_enabled = _is_resource_shrinking_enabled(
+ shrink_resources,
+ use_android_resource_shrinking,
+ )
+ shrink_resource_cycles = _should_shrink_resource_cycles(
+ use_android_resource_cycle_shrinking,
+ resource_shrinking_enabled,
+ )
+
+ # Fix class jar name because some tests depend on {label_name}_resources.jar being the suffix of
+ # the path, with _RESOURCES_DO_NOT_USE removed from the label name.
+ _RESOURCES_SUFFIX = "_RESOURCES_DO_NOT_USE"
+ class_jar_name = ctx.label.name + "_migrated/_resources.jar"
+ if ctx.label.name.endswith(_RESOURCES_SUFFIX):
+ label_name = ctx.label.name[:-len(_RESOURCES_SUFFIX)]
+ class_jar_name = ctx.label.name + "_migrated/" + label_name + "_resources.jar"
+
+ class_jar = ctx.actions.declare_file(class_jar_name)
+ _busybox.generate_binary_r(
+ ctx,
+ out_class_jar = class_jar,
+ r_txt = r_txt,
+ manifest = processed_manifest,
+ package_for_r = java_package,
+ final_fields = not shrink_resource_cycles and not instruments,
+ resources_nodes = depset(transitive = direct_resources_nodes + transitive_resources_nodes),
+ transitive_r_txts = transitive_r_txts,
+ transitive_manifests = transitive_manifests,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+ packaged_resources_ctx[_PACKAGED_CLASS_JAR] = class_jar
+
+ java_info = JavaInfo(
+ output_jar = class_jar,
+ compile_jar = class_jar,
+ source_jar = r_java,
+ )
+
+ packaged_resources_ctx[_R_JAVA] = java_info
+
+ packaged_resources_ctx[_PROVIDERS].append(AndroidApplicationResourceInfo(
+ resource_apk = resource_apk,
+ resource_java_src_jar = r_java,
+ resource_java_class_jar = class_jar,
+ manifest = processed_manifest,
+ resource_proguard_config = proguard_cfg,
+ main_dex_proguard_config = main_dex_proguard_cfg,
+ r_txt = r_txt,
+ resources_zip = resource_files_zip,
+ databinding_info = databinding_info,
+ ))
+ return _ResourcesPackageContextInfo(**packaged_resources_ctx)
+
+def _liteparse(ctx, out_r_pb, resource_files, android_kit):
+ """Creates an R.pb which contains the resource ids gotten from a light parse.
+
+ Args:
+ ctx: The context.
+ out_r_pb: File. The R.pb output file.
+ resource_files: List of Files. The list of resource files.
+ android_kit: FilesToRunProvider. The Android Kit executable or
+ FilesToRunProvider.
+ """
+ args = ctx.actions.args()
+ args.use_param_file(param_file_arg = "--flagfile=%s", use_always = True)
+ args.set_param_file_format("multiline")
+ args.add_joined("--res_files", resource_files, join_with = ",")
+ args.add("--out", out_r_pb)
+
+ ctx.actions.run(
+ executable = android_kit,
+ arguments = ["liteparse", args],
+ inputs = resource_files,
+ outputs = [out_r_pb],
+ mnemonic = "ResLiteParse",
+ progress_message = "Lite parse Android Resources %s" % ctx.label,
+ )
+
+def _fastr(ctx, r_pbs, package, manifest, android_kit):
+ """Create R.srcjar from the given R.pb files in the transitive closure.
+
+ Args:
+ ctx: The context.
+ r_pbs: Transitive set of resource pbs.
+ package: The package name of the compile-time R.java.
+ manifest: File. The AndroidManifest.xml file.
+ android_kit: FilesToRunProvider. The Android Kit executable or
+ FilesToRunProvider.
+
+ Returns:
+ The output R source jar artifact.
+ """
+ inputs = r_pbs
+ r_srcjar = ctx.actions.declare_file(ctx.label.name + "/resources/R-fastr.srcjar")
+ args = ctx.actions.args()
+ args.use_param_file(param_file_arg = "--flagfile=%s", use_always = True)
+ args.set_param_file_format("multiline")
+ args.add("-rJavaOutput", r_srcjar)
+ if package:
+ args.add("-packageForR", package)
+ else:
+ args.add("-manifest", manifest)
+ inputs = depset([manifest], transitive = [inputs])
+ args.add_joined("-resourcePbs", r_pbs, join_with = ",")
+
+ ctx.actions.run(
+ executable = android_kit,
+ arguments = ["rstub", args],
+ inputs = inputs,
+ outputs = [r_srcjar],
+ mnemonic = "CompileTimeR",
+ progress_message = "Generating compile-time R %s" % r_srcjar.short_path,
+ )
+ return r_srcjar
+
+def _compile(
+ ctx,
+ out_compiled_resources = None,
+ out_r_pb = None,
+ resource_files = [],
+ aapt = None,
+ android_kit = None,
+ busybox = None,
+ host_javabase = None):
+ """Compile Android Resources processing pipeline.
+
+ Args:
+ ctx: The context.
+ out_compiled_resources: File. The compiled resources output file.
+ out_r_pb: File. The R.pb output file.
+ resource_files: A list of Files. The resource files can be directories.
+ aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider.
+ android_kit: FilesToRunProvider. The android_kit executable or
+ FilesToRunProvider.
+ busybox: FilesToRunProvider. The ResourceBusyBox executable or
+ FilesToRunprovider
+ host_javabase: A Target. The host javabase.
+ """
+ _liteparse(ctx, out_r_pb, resource_files, android_kit)
+ _busybox.compile(
+ ctx,
+ out_file = out_compiled_resources,
+ resource_files = resource_files,
+ aapt = aapt,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+
+def _make_aar(
+ ctx,
+ assets = [],
+ assets_dir = None,
+ resource_files = [],
+ class_jar = None,
+ r_txt = None,
+ manifest = None,
+ proguard_specs = [],
+ busybox = None,
+ host_javabase = None):
+ """Generate an android archive file.
+
+ Args:
+ ctx: The context.
+ assets: sequence of Files. A list of Android assets files to be processed.
+ assets_dir: String. The name of the assets directory.
+ resource_files: A list of Files. The resource files.
+ class_jar: File. The class jar file.
+ r_txt: File. The resource IDs outputted by linking resources in text.
+ manifest: File. The primary AndroidManifest.xml.
+ proguard_specs: List of File. The proguard spec files.
+ busybox: FilesToRunProvider. The ResourceBusyBox executable or
+ FilesToRunprovider
+ host_javabase: A Target. The host javabase.
+
+ Returns:
+ The output aar artifact.
+ """
+ aar = ctx.actions.declare_file(ctx.label.name + ".aar")
+ _busybox.make_aar(
+ ctx,
+ out_aar = aar,
+ assets = assets,
+ assets_dir = assets_dir,
+ resource_files = resource_files,
+ class_jar = class_jar,
+ r_txt = r_txt,
+ manifest = manifest,
+ proguard_specs = proguard_specs,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+ return aar
+
+def _validate(ctx, manifest, defined_assets, defined_assets_dir):
+ if ((defined_assets and not defined_assets_dir) or
+ (not defined_assets and defined_assets_dir)):
+ _log.error(_ASSET_DEFINITION_ERROR % ctx.label)
+
+ if not manifest:
+ _log.error(_MANIFEST_MISSING_ERROR % ctx.label)
+
+def _make_direct_assets_transitive(assets_info):
+ return AndroidAssetsInfo(
+ assets_info.label,
+ assets_info.validation_result,
+ depset([]), # direct_parsed_assets
+ depset(
+ transitive = [
+ assets_info.direct_parsed_assets,
+ assets_info.transitive_parsed_assets,
+ ],
+ order = "preorder",
+ ),
+ assets_info.assets,
+ assets_info.symbols,
+ assets_info.compiled_symbols,
+ )
+
+def _make_direct_resources_transitive(resources_info):
+ return AndroidResourcesInfo(
+ resources_info.label,
+ resources_info.manifest,
+ resources_info.compiletime_r_txt,
+ # NB: the ordering of "direct" and "transitive" is inconsistent with that used for
+ # AndroidAssetsInfo.
+ depset(
+ transitive = [
+ # Ordering is inconsistent here too:
+ # https://github.com/bazelbuild/bazel/blob/82c7f48b4628ebbec18123afdbed701bbaa605e2/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java#L158
+ resources_info.transitive_android_resources,
+ resources_info.direct_android_resources,
+ ],
+ order = "preorder",
+ ),
+ depset([]), # direct_android_resources
+ resources_info.transitive_resources,
+ resources_info.transitive_manifests,
+ resources_info.transitive_aapt2_r_txt,
+ resources_info.transitive_symbols_bin,
+ resources_info.transitive_compiled_symbols,
+ resources_info.transitive_static_lib,
+ resources_info.transitive_r_txt,
+ validation_artifacts = resources_info.validation_artifacts,
+ )
+
+def _export_assets(assets_info, exports):
+ all_providers = [assets_info] + utils.collect_providers(AndroidAssetsInfo, exports)
+ return AndroidAssetsInfo(
+ assets_info.label,
+ assets_info.validation_result,
+ direct_parsed_assets = utils.join_depsets(all_providers, "direct_parsed_assets", order = "preorder"),
+ transitive_parsed_assets = utils.join_depsets(all_providers, "transitive_parsed_assets", order = "preorder"),
+ transitive_assets = utils.join_depsets(all_providers, "assets", order = "preorder"),
+ transitive_symbols = utils.join_depsets(all_providers, "symbols", order = "preorder"),
+ transitive_compiled_symbols = utils.join_depsets(all_providers, "compiled_symbols", order = "preorder"),
+ )
+
+def _export_resources(resources_info, exports):
+ all_providers = [resources_info] + utils.collect_providers(AndroidResourcesInfo, exports)
+ return AndroidResourcesInfo(
+ resources_info.label,
+ resources_info.manifest,
+ resources_info.compiletime_r_txt,
+ **{attr: utils.join_depsets(all_providers, attr, order = "preorder") for attr in [
+ "transitive_android_resources",
+ "direct_android_resources",
+ "transitive_resources",
+ "transitive_manifests",
+ "transitive_aapt2_r_txt",
+ "transitive_symbols_bin",
+ "transitive_compiled_symbols",
+ "transitive_static_lib",
+ "transitive_r_txt",
+ "validation_artifacts",
+ ]}
+ )
+
+def _validate_resources(resource_files = None):
+ for resource_file in resource_files:
+ path_segments = resource_file.path.split("/")
+ if len(path_segments) < 3:
+ fail(_INCORRECT_RESOURCE_LAYOUT_ERROR % resource_file)
+
+ # Check the resource directory type if the resource file is not a Fileset.
+ if not resource_file.is_directory:
+ # The resource directory is presumed to be the second directory from the end.
+ # Resource directories can have multiple qualifiers, each one separated with a dash.
+ res_type = path_segments[-2].partition(_RESOURCE_QUALIFIER_SEP)[0]
+ if res_type not in _RESOURCE_FOLDER_TYPES:
+ fail(_INCORRECT_RESOURCE_LAYOUT_ERROR % resource_file)
+
+def _process_starlark(
+ ctx,
+ java_package = None,
+ manifest = None,
+ defined_assets = False,
+ assets = None,
+ defined_assets_dir = False,
+ assets_dir = None,
+ exports_manifest = False,
+ stamp_manifest = True,
+ deps = [],
+ exports = [],
+ resource_files = None,
+ neverlink = False,
+ enable_data_binding = False,
+ android_test_migration = False,
+ fix_resource_transitivity = False,
+ aapt = None,
+ android_jar = None,
+ android_kit = None,
+ busybox = None,
+ java_toolchain = None,
+ host_javabase = None,
+ instrument_xslt = None,
+ xsltproc = None,
+ zip_tool = None):
+ """Processes Android Resources.
+
+ Args:
+ ctx: The rules context.
+ java_package: string. Java package for which java sources will be
+ generated. By default the package is inferred from the directory where
+ the BUILD file containing the rule is.
+ manifest: File. The AndroidManifest.xml file.
+ defined_assets: Bool. Signifies that the assets attribute was set, even
+ if the value is an empty list.
+ assets: sequence of Files. A list of Android assets files to be processed.
+ defined_assets_dir: Bool. Signifies that the assets dir attribute was set,
+ even if the value is an empty string.
+ assets_dir: String. The name of the assets directory.
+ exports_manifest: boolean. Whether to export manifest entries to the
+ android_binary targets that depend on this target.
+ NOTE: "uses-permissions" attributes are never exported.
+ stamp_manifest: boolean. Whether to stamp the manifest with the java
+ package of the target. If True, java_package needs to be passed to
+ the function.
+ deps: sequence of Targets. The list of other libraries targets to link
+ against.
+ exports: sequence of Targets. The closure of all rules reached via exports
+ attributes are considered direct dependencies of any rule that directly
+ depends on the target with exports. The exports are not direct deps of
+ the rule they belong to (TODO(b/144134042): make this so).
+ resource_files: sequence of Files. A list of Android resource files to be
+ processed.
+ neverlink: boolean. Only use this library for compilation and not runtime.
+ The outputs of a rule marked as neverlink will not be used in .apk
+ creation. Useful if the library will be provided by the runtime
+ environment during execution.
+ enable_data_binding: boolean. If true, processesing the data binding
+ expressions in layout resources included through the resource_files
+ parameter is enabled. Without this setting, data binding expressions
+ produce build failures.
+ android_test_migration: boolean. If true, the target is part of the android
+ test to android instrumentation test migration and should not propagate
+ any Android Resource providers.
+ fix_resource_transitivity: Whether to ensure that transitive resources are
+ correctly marked as transitive.
+ aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider.
+ android_jar: File. The android Jar.
+ android_kit: FilesToRunProvider. The android_kit executable or
+ FilesToRunProvider.
+ busybox: FilesToRunProvider. The ResourceBusyBox executable or
+ FilesToRunprovider
+ java_toolchain: The java_toolchain Target.
+ host_javabase: Target. The host javabase.
+ instrument_xslt: File. The xslt transform to apply g3itr.
+ xsltproc: FilesToRunProvider. The xsltproc executable or FilesToRunProvider.
+ zip_tool: FilesToRunProvider. The zip tool executable or FilesToRunProvider.
+
+ Returns:
+ A dict containing _ResourcesProcessContextInfo provider fields.
+ """
+ if (xsltproc and not instrument_xslt) or (not xsltproc and instrument_xslt):
+ fail(
+ "Error, both instrument_xslt and xsltproc need to be " +
+ "specified or not, got:\nxlstproc = %s\ninstrument_xslt = %s" %
+ (xsltproc, instrument_xslt),
+ )
+
+ _validate_resources(resource_files)
+
+ defines_resources = bool(
+ manifest or
+ resource_files or
+ defined_assets or
+ defined_assets_dir or
+ exports_manifest,
+ )
+
+ # TODO(djwhang): Clean up the difference between neverlink the attribute used
+ # by Java compilation and resources neverlink.
+ resources_neverlink = (
+ neverlink and (
+ defines_resources or
+ ctx.fragments.android.fixed_resource_neverlinking
+ )
+ )
+
+ resources_ctx = {
+ _RESOURCES_APK: None,
+ _PROVIDERS: [],
+ # TODO(b/156530953): Move the validation result to the validation_outputs list when we are
+ # done rolling out Starlark resources processing
+ _VALIDATION_RESULTS: [],
+ _DEFINES_RESOURCES: defines_resources,
+ _R_JAVA: None,
+ _MERGED_MANIFEST: None,
+ _STARLARK_PROCESSED_MANIFEST: None,
+ _STARLARK_R_TXT: None,
+ _STARLARK_PROCESSED_RESOURCES: [],
+ }
+
+ if resource_files and not manifest:
+ _log.error(_MANIFEST_MISSING_ERROR % ctx.label)
+
+ if stamp_manifest and not java_package:
+ _log.error(_JAVA_PACKAGE_MISSING_ERROR % ctx.label)
+
+ direct_resources_nodes = []
+ transitive_resources_nodes = []
+ transitive_assets = []
+ transitive_assets_symbols = []
+ transitive_compiled_assets = []
+ direct_compiled_resources = []
+ transitive_compiled_resources = []
+ transitive_resources_files = []
+ transitive_manifests = []
+ transitive_r_txts = []
+
+ for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, deps):
+ direct_resources_nodes.append(dep.direct_resources_nodes)
+ transitive_resources_nodes.append(dep.transitive_resources_nodes)
+ transitive_assets.append(dep.transitive_assets)
+ transitive_assets_symbols.append(dep.transitive_assets_symbols)
+ transitive_compiled_assets.append(dep.transitive_compiled_assets)
+ direct_compiled_resources.append(dep.direct_compiled_resources)
+ transitive_compiled_resources.append(dep.transitive_compiled_resources)
+ transitive_resources_files.append(dep.transitive_resource_files)
+ transitive_manifests.append(dep.transitive_manifests)
+ transitive_r_txts.append(dep.transitive_r_txts)
+
+ exports_direct_resources_nodes = []
+ exports_transitive_resources_nodes = []
+ exports_transitive_assets = []
+ exports_transitive_assets_symbols = []
+ exports_transitive_compiled_assets = []
+ exports_direct_compiled_resources = []
+ exports_transitive_compiled_resources = []
+ exports_transitive_resources_files = []
+ exports_transitive_manifests = []
+ exports_transitive_r_txts = []
+ for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, exports):
+ exports_direct_resources_nodes.append(dep.direct_resources_nodes)
+ exports_transitive_resources_nodes.append(dep.transitive_resources_nodes)
+ exports_transitive_assets.append(dep.transitive_assets)
+ exports_transitive_assets_symbols.append(dep.transitive_assets_symbols)
+ exports_transitive_compiled_assets.append(dep.transitive_compiled_assets)
+ exports_direct_compiled_resources.append(dep.direct_compiled_resources)
+ exports_transitive_compiled_resources.append(dep.transitive_compiled_resources)
+ exports_transitive_resources_files.append(dep.transitive_resource_files)
+ exports_transitive_manifests.append(dep.transitive_manifests)
+ exports_transitive_r_txts.append(dep.transitive_r_txts)
+
+ # TODO(b/144134042): Don't merge exports; exports are not deps.
+ direct_resources_nodes.extend(exports_direct_resources_nodes)
+ transitive_resources_nodes.extend(exports_transitive_resources_nodes)
+ transitive_assets.extend(exports_transitive_assets)
+ transitive_assets_symbols.extend(exports_transitive_assets_symbols)
+ transitive_compiled_assets.extend(exports_transitive_compiled_assets)
+ direct_compiled_resources.extend(exports_direct_compiled_resources)
+ transitive_compiled_resources.extend(exports_transitive_compiled_resources)
+ transitive_resources_files.extend(exports_transitive_resources_files)
+ transitive_manifests.extend(exports_transitive_manifests)
+ transitive_r_txts.extend(exports_transitive_r_txts)
+
+ compiled_assets = None
+ parsed_assets = None
+ compiled_resources = None
+ out_aapt2_r_txt = None
+ r_txt = None
+ processed_resources = resource_files
+ processed_manifest = None
+ if not defines_resources:
+ if aapt:
+ # Generate an empty manifest with the right package
+ generated_manifest = ctx.actions.declare_file(
+ "_migrated/_generated/" + ctx.label.name + "/AndroidManifest.xml",
+ )
+ _generate_dummy_manifest(
+ ctx,
+ generated_manifest,
+ java_package if java_package else ctx.label.package.replace("/", "."),
+ )
+ r_txt = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_symbols/R.txt",
+ )
+ out_manifest = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_processed_manifest/AndroidManifest.xml",
+ )
+ _busybox.package(
+ ctx,
+ out_r_src_jar = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + ".srcjar",
+ ),
+ out_r_txt = r_txt,
+ out_manifest = out_manifest,
+ manifest = generated_manifest,
+ assets = assets,
+ assets_dir = assets_dir,
+ resource_files = resource_files,
+ direct_resources_nodes =
+ depset(transitive = direct_resources_nodes, order = "preorder"),
+ transitive_resources_nodes =
+ depset(transitive = transitive_resources_nodes, order = "preorder"),
+ transitive_assets = transitive_assets,
+ transitive_compiled_assets = transitive_compiled_assets,
+ transitive_resource_files = transitive_resources_files,
+ transitive_compiled_resources = transitive_compiled_resources,
+ transitive_manifests = transitive_manifests,
+ transitive_r_txts = transitive_r_txts,
+ package_type = "LIBRARY",
+ java_package = java_package,
+ android_jar = android_jar,
+ aapt = aapt,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ should_throw_on_conflict = False,
+ )
+ resources_ctx[_STARLARK_PROCESSED_MANIFEST] = out_manifest
+ resources_ctx[_STARLARK_R_TXT] = r_txt
+ resources_ctx[_STARLARK_PROCESSED_RESOURCES] = resource_files
+
+ else:
+ if stamp_manifest:
+ stamped_manifest = ctx.actions.declare_file(
+ "_migrated/_renamed/" + ctx.label.name + "/AndroidManifest.xml",
+ )
+ _busybox.merge_manifests(
+ ctx,
+ out_file = stamped_manifest,
+ manifest = manifest,
+ merge_type = "LIBRARY",
+ java_package = java_package,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+ manifest = stamped_manifest
+
+ if instrument_xslt:
+ g3itr_manifest = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_g3itr_manifest/AndroidManifest.xml",
+ )
+ _add_g3itr(
+ ctx,
+ out_manifest = g3itr_manifest,
+ manifest = manifest,
+ xsltproc = xsltproc,
+ instrument_xslt = instrument_xslt,
+ )
+ manifest = g3itr_manifest
+
+ parsed_assets = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_symbols/assets.bin",
+ )
+ _busybox.parse(
+ ctx,
+ out_symbols = parsed_assets,
+ assets = assets,
+ assets_dir = assets_dir,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+ merged_assets = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_files/assets.zip",
+ )
+ _busybox.merge_assets(
+ ctx,
+ out_assets_zip = merged_assets,
+ assets = assets,
+ assets_dir = assets_dir,
+ symbols = parsed_assets,
+ direct_resources_nodes = depset(
+ transitive = direct_resources_nodes,
+ order = "preorder",
+ ),
+ transitive_resources_nodes = depset(
+ transitive = transitive_resources_nodes,
+ order = "preorder",
+ ),
+ transitive_assets = transitive_assets,
+ transitive_assets_symbols = transitive_assets_symbols,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+ resources_ctx[_VALIDATION_RESULTS].append(merged_assets)
+
+ if assets:
+ compiled_assets = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_symbols/assets.zip",
+ )
+ _busybox.compile(
+ ctx,
+ out_file = compiled_assets,
+ assets = assets,
+ assets_dir = assets_dir,
+ aapt = aapt,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+
+ if enable_data_binding:
+ out_databinding_info = ctx.actions.declare_file(
+ "_migrated/databinding/" + ctx.label.name + "/layout-info.zip",
+ )
+ processed_resources, resources_dirname = _make_databinding_outputs(
+ ctx,
+ resource_files,
+ )
+ _busybox.process_databinding(
+ ctx,
+ out_databinding_info = out_databinding_info,
+ out_databinding_processed_resources = processed_resources,
+ databinding_resources_dirname = resources_dirname,
+ resource_files = resource_files,
+ java_package = java_package,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+
+ compiled_resources = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_symbols/symbols.zip",
+ )
+ _busybox.compile(
+ ctx,
+ out_file = compiled_resources,
+ resource_files = processed_resources,
+ aapt = aapt,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+
+ # TODO(b/160907203): Remove this fix once the native resource processing pipeline is turned off.
+ if enable_data_binding:
+ fixed_compiled_resources = ctx.actions.declare_file(
+ "_migrated/fixed/" + ctx.label.name + "_symbols/symbols.zip",
+ )
+ _fix_databinding_compiled_resources(
+ ctx,
+ out_compiled_resources = fixed_compiled_resources,
+ compiled_resources = compiled_resources,
+ zip_tool = zip_tool,
+ )
+ compiled_resources = fixed_compiled_resources
+
+ out_class_jar = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_resources.jar",
+ )
+ processed_manifest = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_processed_manifest/AndroidManifest.xml",
+ )
+ out_aapt2_r_txt = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_symbols/R.aapt2.txt",
+ )
+ _busybox.merge_compiled(
+ ctx,
+ out_class_jar = out_class_jar,
+ out_manifest = processed_manifest,
+ out_aapt2_r_txt = out_aapt2_r_txt,
+ java_package = java_package,
+ manifest = manifest,
+ compiled_resources = compiled_resources,
+ direct_resources_nodes =
+ depset(transitive = direct_resources_nodes, order = "preorder"),
+ transitive_resources_nodes = depset(
+ transitive = transitive_resources_nodes,
+ order = "preorder",
+ ),
+ direct_compiled_resources = depset(
+ transitive = direct_compiled_resources,
+ order = "preorder",
+ ),
+ transitive_compiled_resources = depset(
+ transitive = transitive_compiled_resources,
+ order = "preorder",
+ ),
+ android_jar = android_jar,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+ resources_ctx[_MERGED_MANIFEST] = processed_manifest
+
+ apk = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_files/library.ap_",
+ )
+ r_java = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + ".srcjar",
+ )
+ r_txt = ctx.actions.declare_file(
+ "_migrated/" + ctx.label.name + "_symbols/R.txt",
+ )
+ _busybox.validate_and_link(
+ ctx,
+ out_r_src_jar = r_java,
+ out_r_txt = r_txt,
+ out_file = apk,
+ compiled_resources = compiled_resources,
+ transitive_compiled_resources = depset(
+ transitive = transitive_compiled_resources,
+ order = "preorder",
+ ),
+ java_package = java_package,
+ manifest = processed_manifest,
+ android_jar = android_jar,
+ aapt = aapt,
+ busybox = busybox,
+ host_javabase = host_javabase,
+ )
+ resources_ctx[_RESOURCES_APK] = apk
+
+ java_info = JavaInfo(
+ output_jar = out_class_jar,
+ compile_jar = out_class_jar,
+ source_jar = r_java,
+ )
+
+ resources_ctx[_R_JAVA] = java_info
+
+ # In a normal build, the outputs of _busybox.validate_and_link are unused. However we need
+ # this action to run to support resource visibility checks.
+ resources_ctx[_VALIDATION_RESULTS].append(r_txt)
+
+ # Needed for AAR generation. The Starlark resource processing pipeline uses the aapt2_r_txt file,
+ # which is why we can't use the StarlarkAndroidResourcesInfo provider when generating the aar.
+ resources_ctx[_STARLARK_PROCESSED_MANIFEST] = processed_manifest
+ resources_ctx[_STARLARK_R_TXT] = r_txt
+ resources_ctx[_STARLARK_PROCESSED_RESOURCES] = processed_resources
+
+ # TODO(b/117338320): Transitive lists defined here are incorrect; direct should come
+ # before transitive, and the order should be topological order instead of preorder.
+ # However, some applications may depend on this incorrect order.
+ if defines_resources:
+ transitive_resources_nodes = transitive_resources_nodes + direct_resources_nodes
+ direct_resources_nodes = []
+ transitive_compiled_resources = transitive_compiled_resources + direct_compiled_resources
+ direct_compiled_resources = []
+ else:
+ if fix_resource_transitivity:
+ transitive_resources_nodes = transitive_resources_nodes + direct_resources_nodes
+ direct_resources_nodes = []
+ transitive_compiled_resources = transitive_compiled_resources + direct_compiled_resources
+ direct_compiled_resources = []
+
+ # TODO(b/144163743): If the resource transitivity fix is disabled and resources-related
+ # inputs are missing, we implicitly export deps here. This legacy behavior must exist in the
+ # Starlark resource processing pipeline until we can clean up the depot.
+
+ # TODO(b/159916013): Audit neverlink behavior. Some processing can likely be skipped if the target is neverlink.
+ # TODO(b/69668042): Don't propagate exported providers/artifacts. Exports should respect neverlink.
+ if resources_neverlink:
+ resources_ctx[_PROVIDERS].append(StarlarkAndroidResourcesInfo(
+ direct_resources_nodes = depset(
+ transitive = exports_direct_resources_nodes,
+ order = "preorder",
+ ),
+ transitive_resources_nodes = depset(
+ transitive = exports_transitive_resources_nodes,
+ order = "preorder",
+ ),
+ transitive_assets = depset(
+ transitive = exports_transitive_assets,
+ order = "preorder",
+ ),
+ transitive_assets_symbols = depset(
+ transitive = exports_transitive_assets_symbols,
+ order = "preorder",
+ ),
+ transitive_compiled_assets = depset(
+ transitive = exports_transitive_compiled_assets,
+ order = "preorder",
+ ),
+ transitive_resource_files = depset(
+ transitive = exports_transitive_resources_files,
+ order = "preorder",
+ ),
+ direct_compiled_resources = depset(
+ transitive = exports_direct_compiled_resources,
+ order = "preorder",
+ ),
+ transitive_compiled_resources = depset(
+ transitive = exports_transitive_compiled_resources,
+ order = "preorder",
+ ),
+ transitive_manifests = depset(
+ [processed_manifest] if processed_manifest else [],
+ transitive = exports_transitive_manifests,
+ order = "preorder",
+ ),
+ transitive_r_txts = depset(
+ [out_aapt2_r_txt] if out_aapt2_r_txt else [],
+ transitive = exports_transitive_r_txts,
+ order = "preorder",
+ ),
+ ))
+ else:
+ # Depsets are ordered below to match the order in the legacy native rules.
+ resources_ctx[_PROVIDERS].append(StarlarkAndroidResourcesInfo(
+ direct_resources_nodes = depset(
+ [ResourcesNodeInfo(
+ label = ctx.label,
+ assets = depset(assets),
+ assets_dir = assets_dir,
+ assets_symbols = parsed_assets,
+ compiled_assets = compiled_assets,
+ resource_files = depset(processed_resources),
+ compiled_resources = compiled_resources,
+ r_txt = out_aapt2_r_txt,
+ manifest = processed_manifest,
+ exports_manifest = exports_manifest,
+ )] if defines_resources else [],
+ transitive = direct_resources_nodes + exports_direct_resources_nodes,
+ order = "preorder",
+ ),
+ transitive_resources_nodes = depset(
+ transitive = transitive_resources_nodes + exports_transitive_resources_nodes,
+ order = "preorder",
+ ),
+ transitive_assets = depset(
+ assets,
+ transitive = transitive_assets + exports_transitive_assets,
+ order = "preorder",
+ ),
+ transitive_assets_symbols = depset(
+ [parsed_assets] if parsed_assets else [],
+ transitive = transitive_assets_symbols + exports_transitive_assets_symbols,
+ order = "preorder",
+ ),
+ transitive_compiled_assets = depset(
+ [compiled_assets] if compiled_assets else [],
+ transitive = transitive_compiled_assets + exports_transitive_compiled_assets,
+ order = "preorder",
+ ),
+ transitive_resource_files = depset(
+ processed_resources,
+ transitive = transitive_resources_files + exports_transitive_resources_files,
+ order = "preorder",
+ ),
+ direct_compiled_resources = depset(
+ [compiled_resources] if compiled_resources else [],
+ transitive = direct_compiled_resources + exports_direct_compiled_resources,
+ order = "preorder",
+ ),
+ transitive_compiled_resources = depset(
+ [compiled_resources] if compiled_resources else [],
+ transitive = transitive_compiled_resources + exports_transitive_compiled_resources,
+ order = "preorder",
+ ),
+ transitive_manifests = depset(
+ [processed_manifest] if processed_manifest else [],
+ transitive = transitive_manifests + exports_transitive_manifests,
+ order = "preorder",
+ ),
+ transitive_r_txts = depset(
+ [out_aapt2_r_txt] if out_aapt2_r_txt else [],
+ transitive = transitive_r_txts + exports_transitive_r_txts,
+ order = "preorder",
+ ),
+ ))
+
+ # Do not collect resources and R.java for test apk
+ if android_test_migration:
+ resources_ctx[_R_JAVA] = None
+ resources_ctx[_PROVIDERS] = []
+
+ # TODO(b/69552500): In the Starlark Android Rules, the R compile time
+ # JavaInfo is added as a runtime dependency to the JavaInfo. Stop
+ # adding the R.jar as a runtime dependency.
+ resources_ctx[_PROVIDERS].append(
+ AndroidLibraryResourceClassJarProvider(
+ depset(
+ (resources_ctx[_R_JAVA].runtime_output_jars if resources_ctx[_R_JAVA] else []),
+ transitive = [
+ p.jars
+ for p in utils.collect_providers(
+ AndroidLibraryResourceClassJarProvider,
+ deps,
+ exports,
+ )
+ ],
+ order = "preorder",
+ ),
+ ),
+ )
+
+ return resources_ctx
+
+
+def _process(
+ ctx,
+ manifest = None,
+ resource_files = None,
+ defined_assets = False,
+ assets = None,
+ defined_assets_dir = False,
+ assets_dir = None,
+ exports_manifest = False,
+ java_package = None,
+ custom_package = None,
+ neverlink = False,
+ enable_data_binding = False,
+ deps = [],
+ exports = [],
+ android_jar = None,
+ android_kit = None,
+ aapt = None,
+ busybox = None,
+ xsltproc = None,
+ instrument_xslt = None,
+ java_toolchain = None,
+ host_javabase = None,
+ enable_res_v3 = False,
+ res_v3_dummy_manifest = None,
+ res_v3_dummy_r_txt = None,
+ fix_resource_transitivity = False,
+ fix_export_exporting = False,
+ android_test_migration = False,
+ zip_tool = None):
+ out_ctx = _process_starlark(
+ ctx,
+ java_package = java_package,
+ manifest = manifest,
+ defined_assets = defined_assets,
+ # TODO(b/159937795): When the Starlark Resources Processing pipeline is
+ # default and the native version is no longer used, remove the depset
+ # creation and directly pass through ctx.files.assets to this method.
+ assets =
+ depset(transitive = [target.files for target in assets]).to_list(),
+ defined_assets_dir = defined_assets_dir,
+ assets_dir = assets_dir,
+ exports_manifest = exports_manifest,
+ stamp_manifest = True if java_package else False,
+ deps = deps,
+ exports = exports,
+ resource_files = depset(transitive = [target.files for target in resource_files]).to_list(),
+ enable_data_binding = enable_data_binding,
+ fix_resource_transitivity = fix_resource_transitivity,
+ neverlink = neverlink,
+ android_test_migration = android_test_migration,
+ android_jar = android_jar,
+ aapt = aapt,
+ android_kit = android_kit,
+ busybox = busybox,
+ instrument_xslt = instrument_xslt,
+ xsltproc = xsltproc,
+ java_toolchain = java_toolchain,
+ host_javabase = host_javabase,
+ zip_tool = zip_tool,
+ )
+
+
+ if _VALIDATION_OUTPUTS not in out_ctx:
+ out_ctx[_VALIDATION_OUTPUTS] = []
+
+ return _ResourcesProcessContextInfo(**out_ctx)
+
+resources = struct(
+ process = _process,
+ process_starlark = _process_starlark,
+ package = _package,
+ make_aar = _make_aar,
+
+ # Exposed for mobile-install
+ compile = _compile,
+ legacy_merge_manifests = _legacy_merge_manifests,
+
+ # Exposed for android_local_test and android_library
+ generate_dummy_manifest = _generate_dummy_manifest,
+)
+
+testing = struct(
+ add_g3itr = _add_g3itr,
+ filter_multi_cpu_configuration_targets = _filter_multi_cpu_configuration_targets,
+ get_legacy_mergee_manifests = _get_legacy_mergee_manifests,
+ make_databinding_outputs = _make_databinding_outputs,
+ ResourcesPackageContextInfo = _ResourcesPackageContextInfo,
+ ResourcesProcessContextInfo = _ResourcesProcessContextInfo,
+)
diff --git a/rules/robolectric_properties_template.txt b/rules/robolectric_properties_template.txt
new file mode 100644
index 0000000..d05a28c
--- /dev/null
+++ b/rules/robolectric_properties_template.txt
@@ -0,0 +1,5 @@
+android_merged_manifest=%android_merged_manifest%
+android_merged_resources=%android_merged_resources%
+android_merged_assets=%android_merged_assets%
+android_custom_package=%android_custom_package%
+android_resource_apk=%android_resource_apk%
diff --git a/rules/rules.bzl b/rules/rules.bzl
new file mode 100644
index 0000000..e849d72
--- /dev/null
+++ b/rules/rules.bzl
@@ -0,0 +1,129 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Skylark rules for building Android apps."""
+
+load(
+ "//rules/aar_import:rule.bzl",
+ _aar_import = "aar_import",
+)
+
+#load(
+# ":apk_import.bzl",
+# _apk_import = "apk_import",
+#)
+
+load(
+ ":android_binary.bzl",
+ _android_binary = "android_binary",
+)
+
+# load(
+# ":android_device.bzl",
+# _android_device = "android_device",
+# )
+# load(
+# ":android_device_script_fixture.bzl",
+# _android_device_script_fixture = "android_device_script_fixture",
+# )
+# load(
+# ":android_host_service_fixture.bzl",
+# _android_host_service_fixture = "android_host_service_fixture",
+# )
+# load(
+# ":android_instrumentation_test.bzl",
+# _android_instrumentation_test = "android_instrumentation_test",
+# )
+
+load(
+ "//rules/android_library:rule.bzl",
+ _android_library = "android_library_macro",
+)
+
+# load(
+# ":android_local_test.bzl",
+# _android_local_test = "android_local_test",
+# )
+
+load(
+ ":android_ndk_repository.bzl",
+ _android_ndk_repository = "android_ndk_repository",
+)
+load(
+ ":android_sdk.bzl",
+ _android_sdk = "android_sdk",
+)
+load(
+ ":android_sdk_repository.bzl",
+ _android_sdk_repository = "android_sdk_repository",
+)
+load(
+ ":android_tools_defaults_jar.bzl",
+ _android_tools_defaults_jar = "android_tools_defaults_jar",
+)
+
+# Current version. Tools may check this to determine compatibility.
+RULES_ANDROID_VERSION = "0.1.0"
+
+aar_import = _aar_import
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_apk_to_bundle"""
+
+android_binary = _android_binary
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_binary"""
+
+#android_device = _android_device
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_device"""
+
+#android_device_script_fixture = _android_device_script_fixture
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_host_service_fixture"""
+
+#android_host_service_fixture = _android_host_service_fixture
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_device_script_fixture"""
+
+#android_instrumentation_test = _android_instrumentation_test
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_instrumentation_test"""
+
+android_library = _android_library
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_library"""
+
+#android_local_test = _android_local_test
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_local_test"""
+
+android_ndk_repository = _android_ndk_repository
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_ndk_repository"""
+
+android_sdk = _android_sdk
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_sdk"""
+
+android_sdk_repository = _android_sdk_repository
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_sdk_repository"""
+
+android_tools_defaults_jar = _android_tools_defaults_jar
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_tools_defaults_jar"""
+
+#apk_import = _apk_import
+#
+#"""https://docs.bazel.build/versions/master/be/android.html#apk_import"""
diff --git a/rules/toolchains/emulator/BUILD b/rules/toolchains/emulator/BUILD
new file mode 100644
index 0000000..a02375a
--- /dev/null
+++ b/rules/toolchains/emulator/BUILD
@@ -0,0 +1,27 @@
+# Description:
+# Defines an emulator toolchain so that the emulator used for android_device
+# can be configured at build-time.
+
+load(":toolchain.bzl", "emulator_toolchain")
+
+package(default_visibility = ["//visibility:public"])
+
+# By convention, toolchain_type targets are named "toolchain_type"
+# and distinguished by their package path.
+toolchain_type(
+ name = "toolchain_type",
+)
+
+emulator_toolchain(
+ name = "emulator_default",
+ emulator = "@androidsdk//:emulator",
+ emulator_deps = [
+ "@androidsdk//:emulator_shared_libs",
+ ],
+)
+
+toolchain(
+ name = "emulator_default_toolchain",
+ toolchain = ":emulator_default",
+ toolchain_type = ":toolchain_type",
+)
diff --git a/rules/toolchains/emulator/toolchain.bzl b/rules/toolchains/emulator/toolchain.bzl
new file mode 100644
index 0000000..61bfb77
--- /dev/null
+++ b/rules/toolchains/emulator/toolchain.bzl
@@ -0,0 +1,59 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Defines the emulator_toolchain rule to allow configuring emulator binaries to use."""
+
+EmulatorInfo = provider(
+ doc = "Information used to launch a specific version of the emulator.",
+ fields = {
+ "emulator": "A label for the emulator launcher executable at stable version.",
+ "emulator_deps": "Additional files required to launch the stable version of emulator.",
+ "emulator_suffix": "An optional path suffix used to find emulator binary under the emulator label path",
+ },
+)
+
+def _emulator_toolchain_impl(ctx):
+ toolchain_info = platform_common.ToolchainInfo(
+ info = EmulatorInfo(
+ emulator = ctx.attr.emulator,
+ emulator_deps = ctx.attr.emulator_deps,
+ emulator_suffix = ctx.attr.emulator_suffix,
+ ),
+ )
+ return [toolchain_info]
+
+emulator_toolchain = rule(
+ implementation = _emulator_toolchain_impl,
+ attrs = {
+ "emulator": attr.label(
+ allow_files = True,
+ cfg = "host",
+ mandatory = True,
+ ),
+ "emulator_deps": attr.label_list(
+ allow_files = True,
+ cfg = "host",
+ ),
+ "emulator_head": attr.label(
+ allow_files = True,
+ cfg = "host",
+ ),
+ "emulator_head_deps": attr.label_list(
+ allow_files = True,
+ cfg = "host",
+ ),
+ "emulator_suffix": attr.string(default = ""),
+ "emulator_head_suffix": attr.string(default = ""),
+ },
+)
diff --git a/rules/utils.bzl b/rules/utils.bzl
new file mode 100644
index 0000000..76a0fd2
--- /dev/null
+++ b/rules/utils.bzl
@@ -0,0 +1,451 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Utilities for the Android rules."""
+
+load(":providers.bzl", "FailureInfo")
+
+_CUU = "\033[A"
+_EL = "\033[K"
+_DEFAULT = "\033[0m"
+_BOLD = "\033[1m"
+_RED = "\033[31m"
+_GREEN = "\033[32m"
+_MAGENTA = "\033[35m"
+_ERASE_PREV_LINE = "\n" + _CUU + _EL
+
+_INFO = _ERASE_PREV_LINE + _GREEN + "INFO: " + _DEFAULT + "%s"
+_WARNING = _ERASE_PREV_LINE + _MAGENTA + "WARNING: " + _DEFAULT + "%s"
+_ERROR = _ERASE_PREV_LINE + _BOLD + _RED + "ERROR: " + _DEFAULT + "%s"
+
+_WORD_CHARS = {
+ "A": True,
+ "B": True,
+ "C": True,
+ "D": True,
+ "E": True,
+ "F": True,
+ "G": True,
+ "H": True,
+ "I": True,
+ "J": True,
+ "K": True,
+ "L": True,
+ "M": True,
+ "N": True,
+ "O": True,
+ "P": True,
+ "Q": True,
+ "R": True,
+ "S": True,
+ "T": True,
+ "U": True,
+ "V": True,
+ "W": True,
+ "X": True,
+ "Y": True,
+ "Z": True,
+ "a": True,
+ "b": True,
+ "c": True,
+ "d": True,
+ "e": True,
+ "f": True,
+ "g": True,
+ "h": True,
+ "i": True,
+ "j": True,
+ "k": True,
+ "l": True,
+ "m": True,
+ "n": True,
+ "o": True,
+ "p": True,
+ "q": True,
+ "r": True,
+ "s": True,
+ "t": True,
+ "u": True,
+ "v": True,
+ "w": True,
+ "x": True,
+ "y": True,
+ "z": True,
+ "0": True,
+ "1": True,
+ "2": True,
+ "3": True,
+ "4": True,
+ "5": True,
+ "6": True,
+ "7": True,
+ "8": True,
+ "9": True,
+ "_": True,
+}
+
+_HEX_CHAR = {
+ 0x0: "0",
+ 0x1: "1",
+ 0x2: "2",
+ 0x3: "3",
+ 0x4: "4",
+ 0x5: "5",
+ 0x6: "6",
+ 0x7: "7",
+ 0x8: "8",
+ 0x9: "9",
+ 0xA: "A",
+ 0xB: "B",
+ 0xC: "C",
+ 0xD: "D",
+ 0xE: "E",
+ 0xF: "F",
+}
+
+_JAVA_RESERVED = {
+ "abstract": True,
+ "assert": True,
+ "boolean": True,
+ "break": True,
+ "byte": True,
+ "case": True,
+ "catch": True,
+ "char": True,
+ "class": True,
+ "const": True,
+ "continue": True,
+ "default": True,
+ "do": True,
+ "double": True,
+ "else": True,
+ "enum": True,
+ "extends": True,
+ "final": True,
+ "finally": True,
+ "float": True,
+ "for": True,
+ "goto": True,
+ "if": True,
+ "implements": True,
+ "import": True,
+ "instanceof": True,
+ "int": True,
+ "interface": True,
+ "long": True,
+ "native": True,
+ "new": True,
+ "package": True,
+ "private": True,
+ "protected": True,
+ "public": True,
+ "return": True,
+ "short": True,
+ "static": True,
+ "strictfp": True,
+ "super": True,
+ "switch": True,
+ "synchronized": True,
+ "this": True,
+ "throw": True,
+ "throws": True,
+ "transient": True,
+ "try": True,
+ "void": True,
+ "volatile": True,
+ "while": True,
+ "true": True,
+ "false": True,
+ "null": True,
+}
+
+def _collect_providers(provider, *all_deps):
+ """Collects the requested providers from the given list of deps."""
+ providers = []
+ for deps in all_deps:
+ for dep in deps:
+ if provider in dep:
+ providers.append(dep[provider])
+ return providers
+
+def _join_depsets(providers, attr, order = "default"):
+ """Returns a merged depset using 'attr' from each provider in 'providers'."""
+ return depset(transitive = [getattr(p, attr) for p in providers], order = order)
+
+def _first(collection):
+ """Returns the first item in the collection."""
+ for i in collection:
+ return i
+ return _error("The collection is empty.")
+
+def _only(collection):
+ """Returns the only item in the collection."""
+ if len(collection) != 1:
+ _error("Expected one element, has %s." % len(collection))
+ return _first(collection)
+
+def _copy_file(ctx, src, dest):
+ if src.is_directory or dest.is_directory:
+ fail("Cannot use copy_file with directories")
+ ctx.actions.run_shell(
+ command = "cp --reflink=auto $1 $2",
+ arguments = [src.path, dest.path],
+ inputs = [src],
+ outputs = [dest],
+ mnemonic = "CopyFile",
+ progress_message = "Copy %s to %s" % (src.short_path, dest.short_path),
+ )
+
+def _copy_dir(ctx, src, dest):
+ if not src.is_directory:
+ fail("copy_dir src must be a directory")
+ ctx.actions.run_shell(
+ command = "cp -r --reflink=auto $1 $2",
+ arguments = [src.path, dest.path],
+ inputs = [src],
+ outputs = [dest],
+ mnemonic = "CopyDir",
+ progress_message = "Copy %s to %s" % (src.short_path, dest.short_path),
+ )
+
+def _info(msg):
+ """Print info."""
+ print(_INFO % msg)
+
+def _warn(msg):
+ """Print warning."""
+ print(_WARNING % msg)
+
+def _debug(msg):
+ """Print debug."""
+ print("\n%s" % msg)
+
+def _error(msg):
+ """Print error and fail."""
+ fail(_ERASE_PREV_LINE + _CUU + _ERASE_PREV_LINE + _CUU + _ERROR % msg)
+
+def _expand_var(config_vars, value):
+ """Expands make variables of the form $(SOME_VAR_NAME) for a single value.
+
+ "$$(SOME_VAR_NAME)" is escaped to a literal value of "$(SOME_VAR_NAME)" instead of being
+ expanded.
+
+ Args:
+ config_vars: String dictionary which maps config variables to their expanded values.
+ value: The string to apply substitutions to.
+
+ Returns:
+ The string value with substitutions applied.
+ """
+ parts = value.split("$(")
+ replacement = parts[0]
+ last_char = replacement[-1] if replacement else ""
+ for part in parts[1:]:
+ var_end = part.find(")")
+ if last_char == "$":
+ # If "$$(..." is found, treat it as "$(..."
+ replacement += "(" + part
+ elif var_end == -1 or part[:var_end] not in config_vars:
+ replacement += "$(" + part
+ else:
+ replacement += config_vars[part[:var_end]] + part[var_end + 1:]
+ last_char = replacement[-1] if replacement else ""
+ return replacement
+
+def _expand_make_vars(ctx, vals):
+ """Expands make variables of the form $(SOME_VAR_NAME).
+
+ Args:
+ ctx: The rules context.
+ vals: Dictionary. Values of the form $(...) will be replaced.
+
+ Returns:
+ A dictionary containing vals.keys() and the expanded values.
+ """
+ res = {}
+ for k, v in vals.items():
+ res[k] = _expand_var(ctx.var, v)
+ return res
+
+def _get_runfiles(ctx, attrs):
+ runfiles = ctx.runfiles()
+ for attr in attrs:
+ executable = attr[DefaultInfo].files_to_run.executable
+ if executable:
+ runfiles = runfiles.merge(ctx.runfiles([executable]))
+ runfiles = runfiles.merge(
+ ctx.runfiles(
+ # Wrap DefaultInfo.files in depset to strip ordering.
+ transitive_files = depset(
+ transitive = [attr[DefaultInfo].files],
+ ),
+ ),
+ )
+ runfiles = runfiles.merge(attr[DefaultInfo].default_runfiles)
+ return runfiles
+
+def _sanitize_string(s, replacement = ""):
+ """Sanitizes a string by replacing all non-word characters.
+
+ This matches the \\w regex character class [A_Za-z0-9_].
+
+ Args:
+ s: String to sanitize.
+ replacement: Replacement for all non-word characters. Optional.
+
+ Returns:
+ The original string with all non-word characters replaced.
+ """
+ return "".join([s[i] if s[i] in _WORD_CHARS else replacement for i in range(len(s))])
+
+def _hex(n, pad = True):
+ """Convert an integer number to an uppercase hexadecimal string.
+
+ Args:
+ n: Integer number.
+ pad: Optional. Pad the result to 8 characters with leading zeroes. Default = True.
+
+ Returns:
+ Return a representation of an integer number as a hexadecimal string.
+ """
+ hex_str = ""
+ for _ in range(8):
+ r = n % 16
+ n = n // 16
+ hex_str = _HEX_CHAR[r] + hex_str
+ if pad:
+ return hex_str
+ else:
+ return hex_str.lstrip("0")
+
+def _sanitize_java_package(pkg):
+ return ".".join(["xxx" if p in _JAVA_RESERVED else p for p in pkg.split(".")])
+
+def _check_for_failures(label, *all_deps):
+ """Collects FailureInfo providers from the given list of deps and fails if there's at least one."""
+ failure_infos = _collect_providers(FailureInfo, *all_deps)
+ if failure_infos:
+ error = "in label '%s':" % label
+ for failure_info in failure_infos:
+ error += "\n\t" + failure_info.error
+ _error(error)
+
+def _run_validation(
+ ctx,
+ validation_out,
+ executable,
+ outputs = [],
+ tools = [],
+ **args):
+ """Creates an action that runs an executable as a validation.
+
+ Note: When the validation executable fails, it should return a non-zero
+ value to signify a validation failure.
+
+ Args:
+ ctx: The context.
+ validation_out: A File. The output of the executable is piped to the
+ file. This artifact should then be propagated to "validations" in the
+ OutputGroupInfo.
+ executable: See ctx.actions.run#executable.
+ outputs: See ctx.actions.run#outputs.
+ tools: See ctx.actions.run#tools.
+ **args: Remaining args are directly propagated to ctx.actions.run_shell.
+ See ctx.actions.run_shell for further documentation.
+ """
+ exec_type = type(executable)
+ exec_bin = None
+ exec_bin_path = None
+ if exec_type == "FilesToRunProvider":
+ exec_bin = executable.executable
+ exec_bin_path = exec_bin.path
+ elif exec_type == "File":
+ exec_bin = executable
+ exec_bin_path = exec_bin.path
+ elif exec_type == type(""):
+ exec_bin_path = executable
+ else:
+ fail(
+ "Error, executable should be a File, FilesToRunProvider or a " +
+ "string that represents a path to a tool, got: %s" % exec_type,
+ )
+
+ ctx.actions.run_shell(
+ command = """#!/bin/bash
+set -eu
+set -o pipefail # Returns the executables failure code, if it fails.
+
+EXECUTABLE={executable}
+VALIDATION_OUT={validation_out}
+
+"${{EXECUTABLE}}" $@ 2>&1 | tee -a "${{VALIDATION_OUT}}"
+""".format(
+ executable = exec_bin_path,
+ validation_out = validation_out.path,
+ ),
+ tools = tools + ([exec_bin] if exec_bin else []),
+ outputs = [validation_out] + outputs,
+ **args
+ )
+
+def get_android_toolchain(ctx):
+ return ctx.toolchains["@rules_android//toolchains/android:toolchain_type"]
+
+def get_android_sdk(ctx):
+ if hasattr(ctx.fragments.android, "incompatible_use_toolchain_resolution") and ctx.fragments.android.incompatible_use_toolchain_resolution:
+ return ctx.toolchains["@rules_android//toolchains/android_sdk:toolchain_type"].android_sdk_info
+ else:
+ return ctx.attr._android_sdk[AndroidSdkInfo]
+
+def _get_compilation_mode(ctx):
+ """Retrieves the compilation mode from the context.
+
+ Returns:
+ A string that represents the compilation mode.
+ """
+ return ctx.var["COMPILATION_MODE"]
+
+compilation_mode = struct(
+ DBG = "dbg",
+ FASTBUILD = "fastbuild",
+ OPT = "opt",
+ get = _get_compilation_mode,
+)
+
+utils = struct(
+ check_for_failures = _check_for_failures,
+ collect_providers = _collect_providers,
+ copy_file = _copy_file,
+ copy_dir = _copy_dir,
+ expand_make_vars = _expand_make_vars,
+ first = _first,
+ get_runfiles = _get_runfiles,
+ join_depsets = _join_depsets,
+ only = _only,
+ run_validation = _run_validation,
+ sanitize_string = _sanitize_string,
+ sanitize_java_package = _sanitize_java_package,
+ hex = _hex,
+)
+
+log = struct(
+ debug = _debug,
+ error = _error,
+ info = _info,
+ warn = _warn,
+)
+
+testing = struct(
+ expand_var = _expand_var,
+)
diff --git a/test/rules/resources/BUILD b/test/rules/resources/BUILD
new file mode 100644
index 0000000..e9ef118
--- /dev/null
+++ b/test/rules/resources/BUILD
@@ -0,0 +1,4 @@
+# Used in android_binary_internal resources diff test
+exports_files(
+ ["test_stub_script.sh"],
+)
diff --git a/toolchains/android/BUILD b/toolchains/android/BUILD
new file mode 100644
index 0000000..6c731a9
--- /dev/null
+++ b/toolchains/android/BUILD
@@ -0,0 +1,52 @@
+# Description:
+# Defines the Android toolchain.
+
+load(":toolchain.bzl", "android_toolchain")
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+licenses(["notice"])
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+)
+
+# Android Toolchain Type
+toolchain_type(name = "toolchain_type")
+
+# Default Android Toolchain
+android_toolchain(
+ name = "android_default",
+ visibility = ["//visibility:public"],
+)
+
+toolchain(
+ name = "android_default_toolchain",
+ toolchain = ":android_default",
+ toolchain_type = ":toolchain_type",
+)
+
+bzl_library(
+ name = "bzl",
+ srcs = glob(["*.bzl"]),
+)
+
+genrule(
+ name = "gen_unzip",
+ outs = ["unzip.sh"],
+ cmd = """cat > $@ <<EOF
+unzip \\$$@
+EOF
+""",
+ executable = True,
+)
+
+sh_binary(
+ name = "zip",
+ srcs = [":zip.sh"],
+)
+
+sh_binary(
+ name = "unzip",
+ srcs = [":unzip.sh"],
+)
diff --git a/toolchains/android/toolchain.bzl b/toolchains/android/toolchain.bzl
new file mode 100644
index 0000000..b356447
--- /dev/null
+++ b/toolchains/android/toolchain.bzl
@@ -0,0 +1,167 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Android toolchain."""
+
+_ATTRS = dict(
+ aapt2 = attr.label(
+ allow_files = True,
+ default = "@androidsdk//:aapt2_binary",
+ ),
+ aar_embedded_jars_extractor = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@bazel_tools//tools/android:aar_embedded_jars_extractor",
+ executable = True,
+ ),
+ aar_native_libs_zip_creator = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@bazel_tools//tools/android:aar_native_libs_zip_creator",
+ executable = True,
+ ),
+ aar_resources_extractor = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@bazel_tools//tools/android:aar_resources_extractor",
+ executable = True,
+ ),
+ adb = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@androidsdk//:platform-tools/adb",
+ executable = True,
+ ),
+ add_g3itr_xslt = attr.label(
+ cfg = "host",
+ default = Label("//tools/android/xslt:add_g3itr.xslt"),
+ allow_files = True,
+ ),
+ android_kit = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@androidsdk//:fail", # TODO: "//src/tools/ak", needs Go
+ executable = True,
+ ),
+ android_resources_busybox = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@bazel_tools//src/tools/android/java/com/google/devtools/build/android:ResourceProcessorBusyBox_deploy.jar",
+ executable = True,
+ ),
+ apk_to_bundle_tool = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@androidsdk//:fail",
+ executable = True,
+ ),
+ bundletool = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@androidsdk//:fail",
+ executable = True,
+ ),
+ data_binding_annotation_processor = attr.label(
+ cfg = "host",
+ default = "@//tools/android:compiler_annotation_processor", # TODO: processor rules should be moved into rules_android
+ ),
+ data_binding_annotation_template = attr.label(
+ default = "//rules:data_binding_annotation_template.txt",
+ allow_files = True,
+ ),
+ data_binding_exec = attr.label(
+ cfg = "host",
+ default = "@bazel_tools//tools/android:databinding_exec",
+ executable = True,
+ ),
+ desugar_java8_extra_bootclasspath = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@bazel_tools//tools/android:desugar_java8_extra_bootclasspath",
+ executable = True,
+ ),
+ idlclass = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@bazel_tools//tools/android:IdlClass", # _deploy.jar?
+ executable = True,
+ ),
+ import_deps_checker = attr.label(
+ allow_files = True,
+ cfg = "host",
+ default = "@android_tools//:ImportDepsChecker_deploy.jar",
+ executable = True,
+ ),
+ jacocorunner = attr.label(
+ default = "@androidsdk//:fail",
+ ),
+ java_stub = attr.label(
+ allow_files = True,
+ # used in android_local_test
+ default = "@androidsdk//:fail", # TODO: java_stub_template.txt gets embedded in bazel's jar, need a copy in @bazel_tools or similar
+ ),
+ jdeps_tool = attr.label(
+ allow_files = True,
+ cfg = "host",
+ # used in android_local_test
+ default = "@androidsdk//:fail", # TODO: "//src/tools/jdeps", needs Go
+ executable = True,
+ ),
+ proguard_allowlister = attr.label(
+ cfg = "host",
+ default = "@bazel_tools//tools/jdk:proguard_whitelister",
+ executable = True,
+ ),
+ res_v3_dummy_manifest = attr.label(
+ allow_files = True,
+ default = "//rules:res_v3_dummy_AndroidManifest.xml",
+ ),
+ res_v3_dummy_r_txt = attr.label(
+ allow_files = True,
+ default = "//rules:res_v3_dummy_R.txt",
+ ),
+ robolectric_template = attr.label(
+ allow_files = True,
+ default = "//rules:robolectric_properties_template.txt",
+ ),
+ testsupport = attr.label(
+ default = "@androidsdk//:fail",
+ ),
+ unzip_tool = attr.label(
+ cfg = "host",
+ default = "//toolchains/android:unzip",
+ executable = True,
+ ),
+ xsltproc_tool = attr.label(
+ cfg = "host",
+ default = Label("//tools/android/xslt:xslt"),
+ allow_files = True,
+ executable = True,
+ ),
+ zip_tool = attr.label(
+ cfg = "host",
+ default = "//toolchains/android:zip",
+ executable = True,
+ ),
+)
+
+def _impl(ctx):
+ return [platform_common.ToolchainInfo(
+ **{name: getattr(ctx.attr, name) for name in _ATTRS.keys()}
+ )]
+
+android_toolchain = rule(
+ implementation = _impl,
+ attrs = _ATTRS,
+)
diff --git a/toolchains/android/zip.sh b/toolchains/android/zip.sh
new file mode 100755
index 0000000..5d0f18b
--- /dev/null
+++ b/toolchains/android/zip.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+args=()
+for arg in "$@"; do
+ if [[ ! "$arg" == "-jt" ]]; then
+ args+=( "$arg" )
+ fi
+done
+
+zip ${args[@]}
diff --git a/toolchains/android_sdk/BUILD b/toolchains/android_sdk/BUILD
new file mode 100644
index 0000000..10e40ca
--- /dev/null
+++ b/toolchains/android_sdk/BUILD
@@ -0,0 +1,27 @@
+# Description:
+# Defines the Android SDK toolchain.
+
+licenses(["notice"])
+
+filegroup(
+ name = "all_files",
+ srcs = glob(["**"]),
+)
+
+# Android SDK Toolchain Type
+toolchain_type(name = "toolchain_type")
+
+toolchain(
+ name = "android_sdk_tools",
+ exec_compatible_with = [
+ "@bazel_tools//platforms:x86_64",
+ "@bazel_tools//platforms:linux",
+ ],
+ # TODO(b/175833893): This causes the toolchain to not be selected, so
+ # disable for now.
+ #target_compatible_with = [
+ # "@bazel_tools//platforms:android",
+ #],
+ toolchain = "@androidsdk//:sdk",
+ toolchain_type = ":toolchain_type",
+)
diff --git a/toolchains/emulator/BUILD b/toolchains/emulator/BUILD
new file mode 100644
index 0000000..a02375a
--- /dev/null
+++ b/toolchains/emulator/BUILD
@@ -0,0 +1,27 @@
+# Description:
+# Defines an emulator toolchain so that the emulator used for android_device
+# can be configured at build-time.
+
+load(":toolchain.bzl", "emulator_toolchain")
+
+package(default_visibility = ["//visibility:public"])
+
+# By convention, toolchain_type targets are named "toolchain_type"
+# and distinguished by their package path.
+toolchain_type(
+ name = "toolchain_type",
+)
+
+emulator_toolchain(
+ name = "emulator_default",
+ emulator = "@androidsdk//:emulator",
+ emulator_deps = [
+ "@androidsdk//:emulator_shared_libs",
+ ],
+)
+
+toolchain(
+ name = "emulator_default_toolchain",
+ toolchain = ":emulator_default",
+ toolchain_type = ":toolchain_type",
+)
diff --git a/tools/android/BUILD b/tools/android/BUILD
new file mode 100644
index 0000000..c0f554c
--- /dev/null
+++ b/tools/android/BUILD
@@ -0,0 +1,13 @@
+load(":defs.bzl", "android_jar")
+
+android_jar(
+ name = "android_jar",
+ visibility = ["//visibility:public"],
+)
+
+# TODO(b/175833857): This is a stub, should remove.
+alias(
+ name = "merge_manifests",
+ actual = "@androidsdk//:fail",
+ visibility = ["//visibility:public"],
+)
diff --git a/tools/android/defs.bzl b/tools/android/defs.bzl
new file mode 100644
index 0000000..6aa1896
--- /dev/null
+++ b/tools/android/defs.bzl
@@ -0,0 +1,27 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A rule that returns android.jar from the current android sdk."""
+
+def _android_jar_impl(ctx):
+ return DefaultInfo(
+ files = depset([ctx.attr._sdk[AndroidSdkInfo].android_jar]),
+ )
+
+android_jar = rule(
+ implementation = _android_jar_impl,
+ attrs = {
+ "_sdk": attr.label(default = "@androidsdk//:sdk"),
+ },
+)
diff --git a/tools/android/xslt/BUILD b/tools/android/xslt/BUILD
new file mode 100644
index 0000000..b9a60b0
--- /dev/null
+++ b/tools/android/xslt/BUILD
@@ -0,0 +1,7 @@
+exports_files(["add_g3itr.xslt"])
+
+sh_binary(
+ name = "xslt",
+ srcs = ["xslt.sh"],
+ visibility = ["//visibility:public"],
+)
diff --git a/tools/android/xslt/add_g3itr.xslt b/tools/android/xslt/add_g3itr.xslt
new file mode 100644
index 0000000..9ce9a1e
--- /dev/null
+++ b/tools/android/xslt/add_g3itr.xslt
@@ -0,0 +1,7 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ <xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+ </xsl:copy>
+ </xsl:template>
+</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/android/xslt/xslt.sh b/tools/android/xslt/xslt.sh
new file mode 100755
index 0000000..fef6235
--- /dev/null
+++ b/tools/android/xslt/xslt.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# noop
+cp $6 $4
diff --git a/tools/jdk/BUILD b/tools/jdk/BUILD
new file mode 100644
index 0000000..c688d1a
--- /dev/null
+++ b/tools/jdk/BUILD
@@ -0,0 +1,11 @@
+load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
+
+default_java_toolchain(
+ name = "toolchain_android_only",
+ bootclasspath = [
+ "//tools/android:android_jar",
+ # TODO(b/175805830): Add this only when desugaring is enabled.
+ "@bazel_tools//tools/android:desugar_java8_extra_bootclasspath",
+ ],
+ visibility = ["//visibility:public"],
+)