diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 06:56:45 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 06:56:45 +0000 |
commit | 2495809a0455cb320b2699d2c04474d4ad696df4 (patch) | |
tree | 852e73e45af48623c78a152bdd5dc38f8a4986ab | |
parent | 21b742bc1da1235309d33fdb4d20980e40eaef34 (diff) | |
parent | 7f7740c9ea674bf465c2afe0496065f7a6a0449e (diff) | |
download | bazelbuild-rules_android-2495809a0455cb320b2699d2c04474d4ad696df4.tar.gz |
Snap for 8564071 from 7f7740c9ea674bf465c2afe0496065f7a6a0449e to mainline-permission-releaseaml_per_331913010aml_per_331812030aml_per_331710050aml_per_331611010aml_per_331512020aml_per_331411000aml_per_331313010aml_per_331115020aml_per_331019040aml_per_330912010aml_per_330811030android13-mainline-permission-release
Change-Id: I0784945d64dd94cc5f81c7f3456be2fef771d0d7
56 files changed, 2094 insertions, 434 deletions
diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 6902cfb..0000000 --- a/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @djwhang @jin @ahumesky @mauriciogg @timpeut @git-str @@ -4,7 +4,7 @@ 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: +A version of Bazel built at or near head and the following flags are necessary to use these rules: ``` --experimental_enable_android_migration_apis --experimental_google_legacy_api @@ -13,15 +13,6 @@ Bazel 4.0.0 or newer and the following flags are necessary to use these rules: --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. @@ -38,10 +29,17 @@ 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", + urls = ["https://github.com/bazelbuild/rules_android/archive/refs/heads/pre-alpha.zip"], + strip_prefix = "rules_android-pre-alpha", ) + load("@build_bazel_rules_android//:defs.bzl", "rules_android_workspace") + rules_android_workspace() + + register_toolchains( + "@build_bazel_rules_android//toolchains/android:android_default_toolchain", + "@build_bazel_rules_android//toolchains/android_sdk:android_sdk_tools", + ) + Then, in your BUILD files, import and use the rules: diff --git a/ROADMAP.md b/ROADMAP.md deleted file mode 100644 index 57e46c3..0000000 --- a/ROADMAP.md +++ /dev/null @@ -1,71 +0,0 @@ - -# 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/defs.bzl b/defs.bzl new file mode 100644 index 0000000..4d08708 --- /dev/null +++ b/defs.bzl @@ -0,0 +1,31 @@ +# 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. + +"""Workspace setup macro for rules_android.""" + +load("@rules_jvm_external//:defs.bzl", "maven_install") + +def rules_android_workspace(): + """ Sets up workspace dependencies for rules_android.""" + + maven_install( + name = "rules_android_maven", + artifacts = [ + "com.android.tools.build:bundletool:1.6.1", + ], + repositories = [ + "https://maven.google.com", + "https://repo1.maven.org/maven2", + ], + ) diff --git a/rules/BUILD b/rules/BUILD index b233605..ac89362 100644 --- a/rules/BUILD +++ b/rules/BUILD @@ -8,11 +8,5 @@ exports_files([ 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/aapt.bzl b/rules/aapt.bzl new file mode 100644 index 0000000..284d89a --- /dev/null +++ b/rules/aapt.bzl @@ -0,0 +1,200 @@ +# 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 AAPT Commands.""" + +def _link( + ctx, + out_r_java, + out_resource_apk, + manifest = None, + java_package = None, + assets = depset([]), + assets_dirs = [], + compiled_resources = depset([]), + config_filters = [], + make_r_java_ids_non_final = False, + compatible_with_resource_shrinking = True, + enable_debug = False, + enable_static_lib = False, + android_jar = None, + aapt = None): + """Links compiled Android Resources with AAPT. + + Args: + ctx: The context. + out_r_java: A File. The R.java outputted by linking resources. + out_resource_apk: A File. The Resource APK outputted by linking resources. + manifest: A File. The AndroidManifest.xml. + java_package: A string. The Java package for the generated R.java. + assets: A list of Files. The list of assets from the transitive closure of + the project. + assets_dirs: A list of strings. The list of asset directories in the + transitive closure of the project. + compiled_resources: List of intermediate compiled android resource files. + config_filters: A list of Strings. The configuration filters. + make_r_java_ids_non_final: A bool. Makes the R.java produced from linkin + have non-final values. + compatible_with_resource_shrinking: A bool. When enabled produces the + output in proto format which is a requirement for resource shrinking. + enable_debug: A bool. Enable debugging + enable_static_lib: A bool. Enable static lib. + android_jar: A File. The Android Jar. + aapt: A FilesToRunProvider. The AAPT executable. + """ + + # Output the list of resources in reverse topological order. + resources_param = ctx.actions.declare_file( + out_r_java.basename + ".params", + sibling = out_r_java, + ) + args = ctx.actions.args() + args.use_param_file("%s", use_always = True) + args.set_param_file_format("multiline") + args.add_all(compiled_resources, expand_directories = True) + ctx.actions.run_shell( + command = """ +# Reverses the set of inputs that have been topologically ordered to utilize the +# overlay/override semantics of aapt2. +set -e + +echo $(tac $1) > $2 +""", + arguments = [args, resources_param.path], + outputs = [resources_param], + inputs = compiled_resources, + ) + + args = ctx.actions.args() + args.add("link") + if enable_static_lib: + args.add("--static-lib") + args.add("--no-version-vectors") + args.add("--no-static-lib-packages") # Turn off namespaced resource + + args.add("--manifest", manifest) + args.add("--auto-add-overlay") # Enables resource redefinition and merging + args.add("--override-styles-instead-of-overlaying") # mimic AAPT1. + if make_r_java_ids_non_final: + args.add("--non-final-ids") + if compatible_with_resource_shrinking: + args.add("--proto-format") + if enable_debug: + args.add("--debug-mode") + args.add("--custom-package", java_package) + args.add("-I", android_jar) + args.add_all(assets_dirs, before_each = "-A") + args.add("-R", resources_param, format = "@%s") + args.add("-0", ".apk") + args.add_joined("-c", config_filters, join_with = ",", omit_if_empty = True) + args.add("--java", out_r_java.path.rpartition(java_package.replace(".", "/"))[0]) + args.add("-o", out_resource_apk) + + ctx.actions.run( + executable = aapt, + arguments = [args], + inputs = depset( + [android_jar, resources_param] + + ([manifest] if manifest else []), + transitive = [assets, compiled_resources], + ), + outputs = [out_resource_apk, out_r_java], + mnemonic = "LinkAndroidResources", + progress_message = "ResV3 Linking Android Resources to %s" % out_resource_apk.short_path, + ) + +def _compile( + ctx, + out_dir, + resource_files, + aapt): + """Compile and store resources in a single archive. + + Args: + ctx: The context. + out_dir: File. A file to store the output. + resource_files: A list of Files. The list of resource files or directories + to process. + aapt: AAPT. Tool for compiling resources. + """ + if not out_dir: + fail("No output directory specified.") + if not out_dir.is_directory: + fail("Output directory is not a directory artifact.") + if not resource_files: + fail("No resource files given.") + + # Retrieves the list of files at runtime when a directory is passed. + args = ctx.actions.args() + args.add_all(resource_files, expand_directories = True) + + ctx.actions.run_shell( + command = """ +set -e + +AAPT=%s +OUT_DIR=%s +RESOURCE_FILES=$@ + +i=0 +declare -A out_dir_map +for f in ${RESOURCE_FILES}; do + res_dir="$(dirname $(dirname ${f}))" + if [ -z "${out_dir_map[${res_dir}]}" ]; then + out_dir="${OUT_DIR}/$((++i))" + mkdir -p ${out_dir} + out_dir_map[${res_dir}]="${out_dir}" + fi + # Outputs from multiple directories can overwrite the outputs. As we do not + # control the outputs for now store each in its own sub directory which will be + # captured by the over_dir. + # TODO(b/139757260): Re-evaluate this one compile per file or multiple and zip + # merge. + "${AAPT}" compile --legacy "${f}" -o "${out_dir_map[${res_dir}]}" +done +""" % (aapt.executable.path, out_dir.path), + tools = [aapt], + arguments = [args], + inputs = resource_files, + outputs = [out_dir], + mnemonic = "CompileAndroidResources", + progress_message = "ResV3 Compiling Android Resources in %s" % out_dir, + ) + +def _convert( + ctx, + out = None, + input = None, + to_proto = False, + aapt = None): + args = ctx.actions.args() + args.add("convert") + args.add("--output-format", ("proto" if to_proto else "binary")) + args.add("-o", out) + args.add(input) + + ctx.actions.run( + executable = aapt, + arguments = [args], + inputs = [input], + outputs = [out], + mnemonic = "AaptConvert", + progress_message = "ResV3 Convert to %s" % out.short_path, + ) + +aapt = struct( + link = _link, + compile = _compile, + convert = _convert, +) diff --git a/rules/aar_import/impl.bzl b/rules/aar_import/impl.bzl index 96baa2b..280060e 100644 --- a/rules/aar_import/impl.bzl +++ b/rules/aar_import/impl.bzl @@ -46,6 +46,10 @@ _UNEXPECTED_LINT_JAR_ERROR = ( "a lint.jar file." ) +# Resources context dict fields. +_PROVIDERS = "providers" +_VALIDATION_RESULTS = "validation_results" + def _create_aar_artifact(ctx, name): return ctx.actions.declare_file("%s/%s/%s" % (RULE_PREFIX, ctx.label.name, name)) @@ -114,6 +118,7 @@ def _extract_native_libs( def _process_resources( ctx, aar, + package, manifest, deps, aar_resources_extractor_tool, @@ -139,6 +144,7 @@ def _process_resources( deps = ctx.attr.deps, exports = ctx.attr.exports, exports_manifest = getattr(ctx.attr, "exports_manifest", True), + propagate_resources = _acls.in_aar_propagate_resources(str(ctx.label)), # Tool and Processing related inputs aapt = _get_android_toolchain(ctx).aapt2.files_to_run, @@ -151,23 +157,15 @@ def _process_resources( 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"] = [] + native_android_manifest = manifest + if not getattr(ctx.attr, "exports_manifest", True): + # Write an empty manifest, for the native pipeline. + native_android_manifest = ctx.actions.declare_file(ctx.label.name + "_aar/AndroidManifest.xml") + ctx.actions.write(native_android_manifest, content = """<?xml version="1.0" encoding="utf-8"?> +<manifest package="%s"> +</manifest> +""" % package) + return struct(**resources_ctx) @@ -250,7 +248,10 @@ def _create_import_deps_check( 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( + depset(order = "preorder", transitive = [declared_deps, 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) @@ -355,19 +356,16 @@ def _process_jars( def _validate_rule( ctx, aar, + package, 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) + args.add("-pkg", package) + args.add("-manifest", manifest) if ctx.attr.has_lint_jar: args.add("-has_lint_jar") args.add("-output", validation_output) @@ -375,7 +373,7 @@ def _validate_rule( ctx.actions.run( executable = checks, arguments = [args], - inputs = inputs, + inputs = [aar, manifest], outputs = [validation_output], mnemonic = "ValidateAAR", progress_message = "Validating aar_import %s" % str(ctx.label), @@ -407,6 +405,27 @@ def _process_lint_rules( )) return providers +def _collect_proguard( + ctx, + out_proguard, + aar, + aar_embedded_proguard_extractor): + args = ctx.actions.args() + args.add("--input_aar", aar) + args.add("--output_proguard_file", out_proguard) + ctx.actions.run( + executable = aar_embedded_proguard_extractor, + arguments = [args], + inputs = [aar], + outputs = [out_proguard], + mnemonic = "AarEmbeddedProguardExtractor", + progress_message = "Extracting proguard spec from %s" % aar.basename, + ) + transitive_proguard_specs = [] + for p in _utils.collect_providers(ProguardSpecProvider, ctx.attr.deps, ctx.attr.exports): + transitive_proguard_specs.append(p.specs) + return ProguardSpecProvider(depset([out_proguard], transitive = transitive_proguard_specs)) + def impl(ctx): """The rule implementation. @@ -421,6 +440,7 @@ def impl(ctx): aar = _utils.only(ctx.files.aar) unzip_tool = _get_android_toolchain(ctx).unzip_tool.files_to_run + package = _java.resolve_package_from_label(ctx.label, ctx.attr.package) # Extract the AndroidManifest.xml from the AAR. android_manifest = _create_aar_artifact(ctx, ANDROID_MANIFEST) @@ -435,6 +455,7 @@ def impl(ctx): resources_ctx = _process_resources( ctx, aar = aar, + package = package, manifest = android_manifest, deps = ctx.attr.deps, aar_resources_extractor_tool = @@ -495,6 +516,15 @@ def impl(ctx): ), ) + # Will be empty if there's no proguard.txt file in the aar + proguard_spec = _create_aar_artifact(ctx, "proguard.txt") + providers.append(_collect_proguard( + ctx, + proguard_spec, + aar, + _get_android_toolchain(ctx).aar_embedded_proguard_extractor.files_to_run, + )) + lint_providers = _process_lint_rules( ctx, aar = aar, @@ -505,6 +535,7 @@ def impl(ctx): validation_outputs.append(_validate_rule( ctx, aar = aar, + package = package, manifest = android_manifest, checks = _get_android_toolchain(ctx).aar_import_checks.files_to_run, )) diff --git a/rules/aar_import/rule.bzl b/rules/aar_import/rule.bzl index fa78a88..02a1d61 100644 --- a/rules/aar_import/rule.bzl +++ b/rules/aar_import/rule.bzl @@ -21,6 +21,11 @@ aar_import = rule( attrs = _ATTRS, fragments = ["android"], implementation = _impl, - provides = [AndroidNativeLibsInfo, JavaInfo], + provides = [ + AndroidIdeInfo, + AndroidLibraryResourceClassJarProvider, + AndroidNativeLibsInfo, + JavaInfo, + ], toolchains = ["@rules_android//toolchains/android:toolchain_type"], ) diff --git a/rules/acls.bzl b/rules/acls.bzl index ade99db..ffa1377 100644 --- a/rules/acls.bzl +++ b/rules/acls.bzl @@ -15,7 +15,7 @@ """Access Control Lists. To create a new list: - 1. Create new .bzl file in this directory with a list of targets. + 1. Create new .bzl file in the acls directory with a list of targets. 2. Create matching method in this file. 3. Add matching method to struct. @@ -30,24 +30,26 @@ To update a list: 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_archive_excluded_deps_denylist.bzl", "ANDROID_ARCHIVE_EXCLUDED_DEPS_DENYLIST") 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_library_starlark_resource_outputs.bzl", "ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_FALLBACK", "ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_ROLLOUT") +load("@rules_android//rules/acls:android_lint_checks_rollout.bzl", "ANDROID_LINT_CHECKS_FALLBACK", "ANDROID_LINT_CHECKS_ROLLOUT") +load("@rules_android//rules/acls:android_lint_rollout.bzl", "ANDROID_LINT_FALLBACK", "ANDROID_LINT_ROLLOUT") +load("@rules_android//rules/acls:lint_registry_rollout.bzl", "LINT_REGISTRY_FALLBACK", "LINT_REGISTRY_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") @@ -55,7 +57,6 @@ load("@rules_android//rules/acls:install_apps_in_data.bzl", "INSTALL_APPS_IN_DAT 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") @@ -65,6 +66,8 @@ load( "PARTIAL_JETIFICATION_TARGETS_ROLLOUT", ) load("@rules_android//rules/acls:kt_android_library_rollout.bzl", "KT_ANDROID_LIBRARY_FALLBACK", "KT_ANDROID_LIBRARY_ROLLOUT") +load("@rules_android//rules/acls:android_instrumentation_test_manifest_check_rollout.bzl", "ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_FALLBACK", "ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_ROLLOUT") +load("@rules_android//rules/acls:android_instrumentation_derived_test_class_rollout.bzl", "ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_FALLBACK", "ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_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) @@ -75,9 +78,6 @@ def _in_aar_import_explicit_exports_manifest(fqn): 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) @@ -87,6 +87,9 @@ def _in_ait_virtual_device(fqn): def _in_android_archive_dogfood(fqn): return _matches(fqn, ANDROID_ARCHIVE_DOGFOOD_DICT) +def _in_android_archive_excluded_deps_denylist(fqn): + return _matches(fqn, ANDROID_ARCHIVE_EXCLUDED_DEPS_DENYLIST_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) @@ -96,14 +99,22 @@ def _in_android_instrumentation_binary_starlark_resources(fqn): def _in_android_feature_splits_dogfood(fqn): return _matches(fqn, ANDROID_FEATURE_SPLITS_DOGFOOD_DICT) +def _in_android_lint_checks_rollout(fqn): + return not _matches(fqn, ANDROID_LINT_CHECKS_FALLBACK_DICT) and _matches(fqn, ANDROID_LINT_CHECKS_ROLLOUT_DICT) + def _in_android_lint_rollout(fqn): - return _matches(fqn, ANDROID_LINT_ROLLOUT_DICT) + return not _matches(fqn, ANDROID_LINT_FALLBACK_DICT) and _matches(fqn, ANDROID_LINT_ROLLOUT_DICT) + +def _in_lint_registry_rollout(fqn): + return not _matches(fqn, LINT_REGISTRY_FALLBACK_DICT) and _matches(fqn, LINT_REGISTRY_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 + if generator == "android_test": + return _matches(fqn, ANDROID_TEST_LOCKDOWN_TARGETS) + return generator in ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS_DICT def _in_b122039567(fqn): return _matches(fqn, B122039567_DICT) @@ -123,15 +134,15 @@ def _in_android_library_resources_without_srcs(fqn): def _in_android_library_resources_without_srcs_generator_functions(gfn): return gfn in ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS_DICT +def _in_android_library_starlark_resource_outputs_rollout(fqn): + return not _matches(fqn, ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_FALLBACK_DICT) and _matches(fqn, ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_ROLLOUT_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) @@ -153,12 +164,6 @@ def _in_local_test_rollout(fqn): 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) @@ -177,6 +182,12 @@ def _in_partial_jetification_targets(fqn): 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 _in_android_instrumentation_test_manifest_check_rollout(fqn): + return not _matches(fqn, ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_FALLBACK_DICT) and _matches(fqn, ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_ROLLOUT_DICT) + +def _in_android_instrumentation_test_derived_test_class_rollout(fqn): + return not _matches(fqn, ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_FALLBACK_DICT) and _matches(fqn, ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_ROLLOUT_DICT) + def _make_dict(lst): """Do not use this method outside of this file.""" return {t: True for t in lst} @@ -185,13 +196,12 @@ AAR_IMPORT_DEPS_CHECKER_FALLBACK_DICT = _make_dict(AAR_IMPORT_DEPS_CHECKER_FALLB 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_ARCHIVE_EXCLUDED_DEPS_DENYLIST_DICT = _make_dict(ANDROID_ARCHIVE_EXCLUDED_DEPS_DENYLIST) 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) @@ -201,7 +211,14 @@ ANDROID_LIBRARY_IMPLICIT_EXPORTS_DICT = _make_dict(ANDROID_LIBRARY_IMPLICIT_EXPO 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_LIBRARY_STARLARK_RESOURCE_OUTPUTS_FALLBACK_DICT = _make_dict(ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_FALLBACK) +ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_ROLLOUT_DICT = _make_dict(ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_ROLLOUT) +ANDROID_LINT_CHECKS_FALLBACK_DICT = _make_dict(ANDROID_LINT_CHECKS_FALLBACK) +ANDROID_LINT_CHECKS_ROLLOUT_DICT = _make_dict(ANDROID_LINT_CHECKS_ROLLOUT) +ANDROID_LINT_FALLBACK_DICT = _make_dict(ANDROID_LINT_FALLBACK) ANDROID_LINT_ROLLOUT_DICT = _make_dict(ANDROID_LINT_ROLLOUT) +LINT_REGISTRY_FALLBACK_DICT = _make_dict(LINT_REGISTRY_FALLBACK) +LINT_REGISTRY_ROLLOUT_DICT = _make_dict(LINT_REGISTRY_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) @@ -211,8 +228,6 @@ APP_INSTALLATION_SNAPSHOT_FALLBACK_DICT = _make_dict(APP_INSTALLATION_SNAPSHOT_F 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) @@ -225,9 +240,6 @@ 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) @@ -239,8 +251,16 @@ PARTIAL_JETIFICATION_TARGETS_ROLLOUT_DICT = _make_dict(PARTIAL_JETIFICATION_TARG 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) +ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_ROLLOUT_DICT = _make_dict(ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_ROLLOUT) +ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_FALLBACK_DICT = _make_dict(ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_FALLBACK) +ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_ROLLOUT_DICT = _make_dict(ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_ROLLOUT) +ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_FALLBACK_DICT = _make_dict(ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_FALLBACK) def _matches(fqn, dct): + # Labels with workspace names ("@workspace//pkg:target") are not supported. + if fqn.startswith("@"): + return False + if not fqn.startswith("//"): fail("Fully qualified target should start with '//', got: " + fqn) @@ -273,7 +293,6 @@ def _matches(fqn, dct): 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, @@ -281,19 +300,22 @@ acls = struct( in_b122039567 = _in_b122039567, in_b123854163 = _in_b123854163, in_android_archive_dogfood = _in_android_archive_dogfood, + in_android_archive_excluded_deps_denylist = _in_android_archive_excluded_deps_denylist, 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_starlark_resource_outputs_rollout = _in_android_library_starlark_resource_outputs_rollout, 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_checks_rollout = _in_android_lint_checks_rollout, in_android_lint_rollout = _in_android_lint_rollout, + in_lint_registry_rollout = _in_lint_registry_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, @@ -301,14 +323,14 @@ acls = struct( 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, + in_android_instrumentation_test_manifest_check_rollout = _in_android_instrumentation_test_manifest_check_rollout, + in_android_instrumentation_test_derived_test_class_rollout = _in_android_instrumentation_test_derived_test_class_rollout, ) # Visible for testing diff --git a/rules/acls/aar_import_exports_r_java.bzl b/rules/acls/aar_import_exports_r_java.bzl index c0a07a4..7d2aff1 100644 --- a/rules/acls/aar_import_exports_r_java.bzl +++ b/rules/acls/aar_import_exports_r_java.bzl @@ -1,4 +1,4 @@ -# Copyright 2020 The Bazel Authors. All rights reserved. +# 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. diff --git a/rules/acls/android_archive_excluded_deps_denylist.bzl b/rules/acls/android_archive_excluded_deps_denylist.bzl new file mode 100644 index 0000000..2a46e68 --- /dev/null +++ b/rules/acls/android_archive_excluded_deps_denylist.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. + +"""Denylist for rules that are not allowed in android_archive excluded_deps.""" + +# keep sorted +ANDROID_ARCHIVE_EXCLUDED_DEPS_DENYLIST = [ + # Failure test support. + "@rules_android//test/rules/android_archive/java/com/testdata/denied:__pkg__", +] diff --git a/rules/acls/android_build_stamping_rollout.bzl b/rules/acls/android_build_stamping_rollout.bzl index 5b1169a..8747db8 100644 --- a/rules/acls/android_build_stamping_rollout.bzl +++ b/rules/acls/android_build_stamping_rollout.bzl @@ -19,4 +19,5 @@ ANDROID_BUILD_STAMPING_ROLLOUT = [ ] # keep sorted -ANDROID_BUILD_STAMPING_FALLBACK = [] +ANDROID_BUILD_STAMPING_FALLBACK = [ +] diff --git a/rules/acls/android_feature_splits_dogfood.bzl b/rules/acls/android_feature_splits_dogfood.bzl index 159ef42..0e7ade0 100644 --- a/rules/acls/android_feature_splits_dogfood.bzl +++ b/rules/acls/android_feature_splits_dogfood.bzl @@ -12,13 +12,8 @@ # 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. -""" +"""Packages able to use deprecated Android feature splits features.""" # keep sorted ANDROID_FEATURE_SPLITS_DOGFOOD = [ - "//:__subpackages__", ] diff --git a/rules/acls/android_instrumentation_derived_test_class_rollout.bzl b/rules/acls/android_instrumentation_derived_test_class_rollout.bzl new file mode 100644 index 0000000..782beb8 --- /dev/null +++ b/rules/acls/android_instrumentation_derived_test_class_rollout.bzl @@ -0,0 +1,23 @@ +# 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. + +"""Rollout list for enabling test class derivation in android_instrumentation_test,""" + +ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_ROLLOUT = [ + "//:__subpackages__", +] + +ANDROID_INSTRUMENTATION_TEST_DERIVED_TEST_CLASS_FALLBACK = [ + "//javatests/notinacl:__subpackages__", +] diff --git a/rules/acls/fix_application_id.bzl b/rules/acls/android_instrumentation_test_manifest_check_rollout.bzl index 41c18b7..154f6bb 100644 --- a/rules/acls/fix_application_id.bzl +++ b/rules/acls/android_instrumentation_test_manifest_check_rollout.bzl @@ -12,16 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Allowlist for fixing the implicit application ID in manifest processing. +"""Rollout list for enabling manifest validation in android_instrumentation_test.""" -See b/111923269 for context. -""" - -# keep sorted -FIX_APPLICATION_ID_ROLLOUT = [ +ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_ROLLOUT = [ "//:__subpackages__", ] -# keep sorted -FIX_APPLICATION_ID_FALLBACK = [ +ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_FALLBACK = [ ] diff --git a/rules/acls/android_library_starlark_resource_outputs.bzl b/rules/acls/android_library_starlark_resource_outputs.bzl new file mode 100644 index 0000000..b798fa3 --- /dev/null +++ b/rules/acls/android_library_starlark_resource_outputs.bzl @@ -0,0 +1,26 @@ +# 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 setting the resource outputs (.srcjar, R.txt, and _resources.jar) of android_library to +those files generated by the Starlark resource processing pipeline and not the native resource +processing pipeline. These resource-related predeclared outputs need to be re-pointed to the corresponding +artifacts in the Starlark pipeline. See b/177261846.""" + +# keep sorted +ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_ROLLOUT = [ + "//:__subpackages__", +] + +ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_FALLBACK = [ +] diff --git a/rules/acls/aar_import_package_check.bzl b/rules/acls/android_lint_checks_rollout.bzl index 54b2b51..ee44280 100644 --- a/rules/acls/aar_import_package_check.bzl +++ b/rules/acls/android_lint_checks_rollout.bzl @@ -12,10 +12,11 @@ # 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__", +"""Allow list for enabling Android Lint checks in the Android Rules.""" + +# keep sorted +ANDROID_LINT_CHECKS_ROLLOUT = [ ] -AAR_IMPORT_PKG_CHECK_FALLBACK = [ +ANDROID_LINT_CHECKS_FALLBACK = [ ] diff --git a/rules/acls/android_lint_rollout.bzl b/rules/acls/android_lint_rollout.bzl index 65f9ff7..aab1d59 100644 --- a/rules/acls/android_lint_rollout.bzl +++ b/rules/acls/android_lint_rollout.bzl @@ -17,3 +17,5 @@ # keep sorted ANDROID_LINT_ROLLOUT = [ ] + +ANDROID_LINT_FALLBACK = [] diff --git a/rules/acls/lint_registry_rollout.bzl b/rules/acls/lint_registry_rollout.bzl new file mode 100644 index 0000000..3138f94 --- /dev/null +++ b/rules/acls/lint_registry_rollout.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 the Android Lint Registry target.""" + +# keep sorted +LINT_REGISTRY_ROLLOUT = [ +] + +LINT_REGISTRY_FALLBACK = [] diff --git a/rules/acls/use_classic_desugar.bzl b/rules/acls/use_classic_desugar.bzl new file mode 100644 index 0000000..37110c4 --- /dev/null +++ b/rules/acls/use_classic_desugar.bzl @@ -0,0 +1,18 @@ +# 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. + +"""List of targets that require classic desugar.""" + +USE_CLASSIC_DESUGAR = [ +] diff --git a/rules/android_application/BUILD b/rules/android_application/BUILD new file mode 100644 index 0000000..31cf119 --- /dev/null +++ b/rules/android_application/BUILD @@ -0,0 +1,27 @@ +# The android_application rule. + +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +licenses(["notice"]) + +exports_files([ + "bundle_deploy.sh_template", + "feature_module_validation.sh", + "gen_android_feature_manifest.sh", + "gen_priority_android_feature_manifest.sh", + "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_application/android_application.bzl b/rules/android_application/android_application.bzl new file mode 100644 index 0000000..f7e1710 --- /dev/null +++ b/rules/android_application/android_application.bzl @@ -0,0 +1,51 @@ +# 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. + +"""android_application rule. + +This file exists to inject the correct version of android_binary. +""" + +load(":android_application_rule.bzl", _android_application_macro = "android_application_macro") +load("@rules_android//rules:android_binary.bzl", _android_binary = "android_binary") + +def android_application(**attrs): + """Rule to build an Android Application (app bundle). + + `android_application` produces an app bundle (.aab) rather than an apk, and treats splits + (both configuration and dynamic feature modules) as first-class constructs. If + `feature_modules`, `bundle_config` or both are supplied this rule will produce an .aab. + Otherwise it will fall back to `android_binary` and produce an apk. + + **Attributes** + + `android_application` accepts all the same attributes as `android_binary`, with the following + key differences. + + Name | Description + --- | --- + `srcs` | `android_application` does not accept sources. + `manifest_values` | Required. Must specify `applicationId` in the `manifest_values` + `feature_modules` | New. List of labels to `android_feature_module`s to include as feature splits. Note: must be fully qualified paths (//some:target), not relative. + `bundle_config_file` | New. String path to .pb.json file containing the bundle config. See the [bundletool docs](https://developer.android.com/studio/build/building-cmdline#bundleconfig) for format and examples. Note: this attribute is subject to changes which may require teams to migrate their configurations to a build target. + `app_integrity_config` | Optional. String path to .binarypb file containing the play integrity config. See https://github.com/google/bundletool/blob/master/src/main/proto/app_integrity_config.proto. + `rotation_config` | Optional. String path to .textproto file containing the V3 rotation config. + + Args: + **attrs: Rule attributes + """ + _android_application_macro( + _android_binary = _android_binary, + **attrs + ) diff --git a/rules/android_application/android_application_rule.bzl b/rules/android_application/android_application_rule.bzl new file mode 100644 index 0000000..ab26456 --- /dev/null +++ b/rules/android_application/android_application_rule.bzl @@ -0,0 +1,385 @@ +# 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. + +"""android_application rule.""" + +load(":android_feature_module_rule.bzl", "get_feature_module_paths") +load(":attrs.bzl", "ANDROID_APPLICATION_ATTRS") +load( + "@rules_android//rules:aapt.bzl", + _aapt = "aapt", +) +load( + "@rules_android//rules:bundletool.bzl", + _bundletool = "bundletool", +) +load( + "@rules_android//rules:busybox.bzl", + _busybox = "busybox", +) +load( + "@rules_android//rules:common.bzl", + _common = "common", +) +load( + "@rules_android//rules:java.bzl", + _java = "java", +) +load( + "@rules_android//rules:providers.bzl", + "AndroidBundleInfo", + "AndroidFeatureModuleInfo", + "StarlarkAndroidResourcesInfo", +) +load( + "@rules_android//rules:utils.bzl", + "get_android_toolchain", + _log = "log", +) + +UNSUPPORTED_ATTRS = [ + "srcs", +] + +def _verify_attrs(attrs, fqn): + for attr in UNSUPPORTED_ATTRS: + if hasattr(attrs, attr): + _log.error("Unsupported attr: %s in android_application" % attr) + + if not attrs.get("manifest_values", default = {}).get("applicationId"): + _log.error("%s missing required applicationId in manifest_values" % fqn) + + for attr in ["deps"]: + if attr not in attrs: + _log.error("%s missing require attribute `%s`" % (fqn, attr)) + +def _process_feature_module( + ctx, + out = None, + base_apk = None, + feature_target = None, + java_package = None, + application_id = None): + manifest = _create_feature_manifest( + ctx, + base_apk, + java_package, + feature_target, + ctx.attr._android_sdk[AndroidSdkInfo].aapt2, + ctx.executable._feature_manifest_script, + ctx.executable._priority_feature_manifest_script, + get_android_toolchain(ctx).android_resources_busybox, + _common.get_host_javabase(ctx), + ) + res = feature_target[AndroidFeatureModuleInfo].library[StarlarkAndroidResourcesInfo] + binary = feature_target[AndroidFeatureModuleInfo].binary[ApkInfo].unsigned_apk + has_native_libs = bool(feature_target[AndroidFeatureModuleInfo].binary[AndroidIdeInfo].native_libs) + + # Create res .proto-apk_, output depending on whether this split has native libs. + if has_native_libs: + res_apk = ctx.actions.declare_file(ctx.label.name + "/" + feature_target.label.name + "/res.proto-ap_") + else: + res_apk = out + _busybox.package( + ctx, + out_r_src_jar = ctx.actions.declare_file("R.srcjar", sibling = manifest), + out_r_txt = ctx.actions.declare_file("R.txt", sibling = manifest), + out_symbols = ctx.actions.declare_file("merged.bin", sibling = manifest), + out_manifest = ctx.actions.declare_file("AndroidManifest_processed.xml", sibling = manifest), + out_proguard_cfg = ctx.actions.declare_file("proguard.cfg", sibling = manifest), + out_main_dex_proguard_cfg = ctx.actions.declare_file( + "main_dex_proguard.cfg", + sibling = manifest, + ), + out_resource_files_zip = ctx.actions.declare_file("resource_files.zip", sibling = manifest), + out_file = res_apk, + manifest = manifest, + java_package = java_package, + direct_resources_nodes = res.direct_resources_nodes, + transitive_resources_nodes = res.transitive_resources_nodes, + transitive_manifests = [res.transitive_manifests], + transitive_assets = [res.transitive_assets], + transitive_compiled_assets = [res.transitive_compiled_assets], + transitive_resource_files = [res.transitive_resource_files], + transitive_compiled_resources = [res.transitive_compiled_resources], + transitive_r_txts = [res.transitive_r_txts], + additional_apks_to_link_against = [base_apk], + proto_format = True, # required for aab. + android_jar = ctx.attr._android_sdk[AndroidSdkInfo].android_jar, + aapt = get_android_toolchain(ctx).aapt2.files_to_run, + busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run, + host_javabase = _common.get_host_javabase(ctx), + should_throw_on_conflict = True, + application_id = application_id, + ) + + if not has_native_libs: + return + + # Extract libs/ from split binary + native_libs = ctx.actions.declare_file(ctx.label.name + "/" + feature_target.label.name + "/native_libs.zip") + _common.filter_zip(ctx, binary, native_libs, ["lib/*"]) + + # Extract AndroidManifest.xml and assets from res-ap_ + filtered_res = ctx.actions.declare_file(ctx.label.name + "/" + feature_target.label.name + "/filtered_res.zip") + _common.filter_zip(ctx, res_apk, filtered_res, ["AndroidManifest.xml", "assets/*"]) + + # Merge into output + _java.singlejar( + ctx, + inputs = [filtered_res, native_libs], + output = out, + exclude_build_data = True, + java_toolchain = _common.get_java_toolchain(ctx), + ) + +def _create_feature_manifest( + ctx, + base_apk, + java_package, + feature_target, + aapt2, + feature_manifest_script, + priority_feature_manifest_script, + android_resources_busybox, + host_javabase): + info = feature_target[AndroidFeatureModuleInfo] + manifest = ctx.actions.declare_file(ctx.label.name + "/" + feature_target.label.name + "/AndroidManifest.xml") + + # Rule has not specified a manifest. Populate the default manifest template. + if not info.manifest: + args = ctx.actions.args() + args.add(manifest.path) + args.add(base_apk.path) + args.add(java_package) + args.add(info.feature_name) + args.add(info.title_id) + args.add(info.fused) + args.add(aapt2.executable) + + ctx.actions.run( + executable = feature_manifest_script, + inputs = [base_apk], + outputs = [manifest], + arguments = [args], + tools = [ + aapt2, + ], + mnemonic = "GenFeatureManifest", + progress_message = "Generating AndroidManifest.xml for " + feature_target.label.name, + ) + return manifest + + # Rule has a manifest (already validated by android_feature_module). + # Generate a priority manifest and then merge the user supplied manifest. + priority_manifest = ctx.actions.declare_file( + ctx.label.name + "/" + feature_target.label.name + "/Prioriy_AndroidManifest.xml", + ) + args = ctx.actions.args() + args.add(priority_manifest.path) + args.add(base_apk.path) + args.add(java_package) + args.add(info.feature_name) + args.add(aapt2.executable) + ctx.actions.run( + executable = priority_feature_manifest_script, + inputs = [base_apk], + outputs = [priority_manifest], + arguments = [args], + tools = [ + aapt2, + ], + mnemonic = "GenPriorityFeatureManifest", + progress_message = "Generating Priority AndroidManifest.xml for " + feature_target.label.name, + ) + + _busybox.merge_manifests( + ctx, + out_file = manifest, + manifest = priority_manifest, + mergee_manifests = depset([info.manifest]), + java_package = java_package, + busybox = android_resources_busybox.files_to_run, + host_javabase = host_javabase, + manifest_values = {"MODULE_TITLE": "@string/" + info.title_id}, + ) + + return manifest + +def _impl(ctx): + # Convert base apk to .proto_ap_ + base_apk = ctx.attr.base_module[ApkInfo].unsigned_apk + base_proto_apk = ctx.actions.declare_file(ctx.label.name + "/modules/base.proto-ap_") + _aapt.convert( + ctx, + out = base_proto_apk, + input = base_apk, + to_proto = True, + aapt = get_android_toolchain(ctx).aapt2.files_to_run, + ) + proto_apks = [base_proto_apk] + + # Convert each feature to .proto-ap_ + for feature in ctx.attr.feature_modules: + feature_proto_apk = ctx.actions.declare_file( + "%s.proto-ap_" % feature.label.name, + sibling = base_proto_apk, + ) + _process_feature_module( + ctx, + out = feature_proto_apk, + base_apk = base_apk, + feature_target = feature, + java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.custom_package), + application_id = ctx.attr.application_id, + ) + proto_apks.append(feature_proto_apk) + + # Convert each each .proto-ap_ to module zip + modules = [] + for proto_apk in proto_apks: + module = ctx.actions.declare_file( + proto_apk.basename + ".zip", + sibling = proto_apk, + ) + modules.append(module) + _bundletool.proto_apk_to_module( + ctx, + out = module, + proto_apk = proto_apk, + unzip = get_android_toolchain(ctx).unzip_tool.files_to_run, + zip = get_android_toolchain(ctx).zip_tool.files_to_run, + ) + + metadata = dict() + if ProguardMappingInfo in ctx.attr.base_module: + metadata["com.android.tools.build.obfuscation/proguard.map"] = ctx.attr.base_module[ProguardMappingInfo].proguard_mapping + + if ctx.file.rotation_config: + metadata["com.google.play.apps.signing/RotationConfig.textproto"] = ctx.file.rotation_config + + if ctx.file.app_integrity_config: + metadata["com.google.play.apps.integrity/AppIntegrityConfig.pb"] = ctx.file.app_integrity_config + + # Create .aab + _bundletool.build( + ctx, + out = ctx.outputs.unsigned_aab, + modules = modules, + config = ctx.file.bundle_config_file, + metadata = metadata, + bundletool = get_android_toolchain(ctx).bundletool.files_to_run, + host_javabase = _common.get_host_javabase(ctx), + ) + + # Create `blaze run` script + subs = { + "%bundletool_path%": get_android_toolchain(ctx).bundletool.files_to_run.executable.short_path, + "%aab%": ctx.outputs.unsigned_aab.short_path, + "%key%": ctx.attr.base_module[ApkInfo].signing_keys[0].short_path, + } + ctx.actions.expand_template( + template = ctx.file._bundle_deploy, + output = ctx.outputs.deploy_script, + substitutions = subs, + is_executable = True, + ) + + return [ + ctx.attr.base_module[ApkInfo], + ctx.attr.base_module[AndroidPreDexJarInfo], + AndroidBundleInfo(unsigned_aab = ctx.outputs.unsigned_aab), + DefaultInfo( + executable = ctx.outputs.deploy_script, + runfiles = ctx.runfiles([ + ctx.outputs.unsigned_aab, + ctx.attr.base_module[ApkInfo].signing_keys[0], + get_android_toolchain(ctx).bundletool.files_to_run.executable, + ]), + ), + ] + +android_application = rule( + attrs = ANDROID_APPLICATION_ATTRS, + fragments = [ + "android", + "java", + ], + executable = True, + implementation = _impl, + outputs = { + "deploy_script": "%{name}.sh", + "unsigned_aab": "%{name}_unsigned.aab", + }, + toolchains = ["@rules_android//toolchains/android:toolchain_type"], + _skylark_testable = True, +) + +def android_application_macro(_android_binary, **attrs): + """android_application_macro. + + Args: + _android_binary: The android_binary rule to use. + **attrs: android_application attributes. + """ + + fqn = "//%s:%s" % (native.package_name(), attrs["name"]) + + # Must pop these because android_binary does not have these attributes. + app_integrity_config = attrs.pop("app_integrity_config", default = None) + rotation_config = attrs.pop("rotation_config", default = None) + + # Simply fall back to android_binary if no feature splits or bundle_config + if not attrs.get("feature_modules", None) and not (attrs.get("bundle_config", None) or attrs.get("bundle_config_file", None)): + _android_binary(**attrs) + return + + _verify_attrs(attrs, fqn) + + # Create an android_binary base split, plus an android_application to produce the aab + name = attrs.pop("name") + base_split_name = "%s_base" % name + + # default to [] if feature_modules = None is passed + feature_modules = attrs.pop("feature_modules", default = []) or [] + bundle_config = attrs.pop("bundle_config", default = None) + bundle_config_file = attrs.pop("bundle_config_file", default = None) + + # bundle_config is deprecated in favor of bundle_config_file + # In the future bundle_config will accept a build rule rather than a raw file. + bundle_config_file = bundle_config_file or bundle_config + + for feature_module in feature_modules: + if not feature_module.startswith("//") or ":" not in feature_module: + _log.error("feature_modules expects fully qualified paths, i.e. //some/path:target") + module_targets = get_feature_module_paths(feature_module) + attrs["deps"].append(str(module_targets.title_lib)) + + _android_binary( + name = base_split_name, + **attrs + ) + + android_application( + name = name, + base_module = ":%s" % base_split_name, + bundle_config_file = bundle_config_file, + app_integrity_config = app_integrity_config, + rotation_config = rotation_config, + custom_package = attrs.get("custom_package", None), + testonly = attrs.get("testonly"), + transitive_configs = attrs.get("transitive_configs", []), + feature_modules = feature_modules, + application_id = attrs["manifest_values"]["applicationId"], + ) diff --git a/rules/android_application/android_feature_module.bzl b/rules/android_application/android_feature_module.bzl new file mode 100644 index 0000000..840d961 --- /dev/null +++ b/rules/android_application/android_feature_module.bzl @@ -0,0 +1,58 @@ +# 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. + +"""android_feature_module rule. + +This file exists to inject the correct version of android_binary and android_library. +""" + +load( + ":android_feature_module_rule.bzl", + _android_feature_module_macro = "android_feature_module_macro", +) +load( + "@rules_android//rules:android_binary.bzl", + _android_binary = "android_binary", +) +load( + "@rules_android//rules/android_library:rule.bzl", + _android_library_macro = "android_library_macro", +) + +def android_feature_module(**attrs): + """Macro to declare a Dynamic Feature Module. + + Generates the following: + + * strings.xml containing a unique split identifier (currently a hash of the fully qualified target label) + * dummy AndroidManifest.xml for the split + * `android_library` to create the split resources + * `android_feature_module` rule to be consumed by `android_application` + + **Attributes** + + Name | Description + --- | --- + name | Required string, split name + custom_package | Optional string, custom package for this split + manifest | Required label, the AndroidManifest.xml to use for this module. + library | Required label, the `android_library` contained in this split. Must only contain assets. + title | Required string, the split title + feature_flags | Optional dict, pass through feature_flags dict for native split binary. + """ + _android_feature_module_macro( + _android_binary = _android_binary, + _android_library = _android_library_macro, + **attrs + ) diff --git a/rules/android_application/android_feature_module_rule.bzl b/rules/android_application/android_feature_module_rule.bzl new file mode 100644 index 0000000..3041656 --- /dev/null +++ b/rules/android_application/android_feature_module_rule.bzl @@ -0,0 +1,200 @@ +# 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. + +"""android_feature_module rule.""" + +load(":attrs.bzl", "ANDROID_FEATURE_MODULE_ATTRS") +load("@rules_android//rules:java.bzl", _java = "java") +load( + "@rules_android//rules:providers.bzl", + "AndroidFeatureModuleInfo", +) +load("@rules_android//rules:acls.bzl", "acls") +load( + "@rules_android//rules:utils.bzl", + "get_android_toolchain", +) + +def _impl(ctx): + validation = ctx.actions.declare_file(ctx.label.name + "_validation") + inputs = [ctx.attr.binary[ApkInfo].unsigned_apk] + args = ctx.actions.args() + args.add(validation.path) + if ctx.file.manifest: + args.add(ctx.file.manifest.path) + inputs.append(ctx.file.manifest) + else: + args.add("") + args.add(ctx.attr.binary[ApkInfo].unsigned_apk.path) + args.add(ctx.configuration.coverage_enabled) + args.add(ctx.fragments.android.desugar_java8_libs) + args.add(ctx.attr.library.label) + args.add(get_android_toolchain(ctx).xmllint_tool.files_to_run.executable) + args.add(get_android_toolchain(ctx).unzip_tool.files_to_run.executable) + + ctx.actions.run( + executable = ctx.executable._feature_module_validation_script, + inputs = inputs, + outputs = [validation], + arguments = [args], + tools = [ + get_android_toolchain(ctx).xmllint_tool.files_to_run.executable, + get_android_toolchain(ctx).unzip_tool.files_to_run.executable, + ], + mnemonic = "ValidateFeatureModule", + progress_message = "Validating feature module %s" % str(ctx.label), + ) + + return [ + AndroidFeatureModuleInfo( + binary = ctx.attr.binary, + library = ctx.attr.library, + title_id = ctx.attr.title_id, + title_lib = ctx.attr.title_lib, + feature_name = ctx.attr.feature_name, + fused = ctx.attr.fused, + manifest = ctx.file.manifest, + ), + OutputGroupInfo(_validation = depset([validation])), + ] + +android_feature_module = rule( + attrs = ANDROID_FEATURE_MODULE_ATTRS, + fragments = [ + "android", + "java", + ], + implementation = _impl, + provides = [AndroidFeatureModuleInfo], + toolchains = ["@rules_android//toolchains/android:toolchain_type"], + _skylark_testable = True, +) + +def get_feature_module_paths(fqn): + # Given a fqn to an android_feature_module, returns the absolute paths to + # all implicitly generated targets + return struct( + binary = Label("%s_bin" % fqn), + manifest_lib = Label("%s_AndroidManifest" % fqn), + title_strings_xml = Label("%s_title_strings_xml" % fqn), + title_lib = Label("%s_title_lib" % fqn), + ) + +def android_feature_module_macro(_android_binary, _android_library, **attrs): + """android_feature_module_macro. + + Args: + _android_binary: The android_binary rule to use. + _android_library: The android_library rule to use. + **attrs: android_feature_module attributes. + """ + + # Enable dot syntax + attrs = struct(**attrs) + fqn = "//%s:%s" % (native.package_name(), attrs.name) + + required_attrs = ["name", "library", "title"] + if not acls.in_android_feature_splits_dogfood(fqn): + required_attrs.append("manifest") + + # Check for required macro attributes + for attr in required_attrs: + if not getattr(attrs, attr, None): + fail("%s missing required attr <%s>" % (fqn, attr)) + + if hasattr(attrs, "fused") and hasattr(attrs, "manifest"): + fail("%s cannot specify <fused> and <manifest>. Prefer <manifest>") + + targets = get_feature_module_paths(fqn) + + tags = getattr(attrs, "tags", []) + transitive_configs = getattr(attrs, "transitive_configs", []) + visibility = getattr(attrs, "visibility", None) + testonly = getattr(attrs, "testonly", None) + + # Create strings.xml containing split title + title_id = "split_" + str(hash(fqn)).replace("-", "N") + native.genrule( + name = targets.title_strings_xml.name, + outs = [attrs.name + "/res/values/strings.xml"], + cmd = """cat > $@ <<EOF +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" +xmlns:tools="http://schemas.android.com/tools" +tools:keep="@string/{title_id}"> + <string name="{title_id}">{title}</string> +</resources> +EOF +""".format(title = attrs.title, title_id = title_id), + ) + + # Create AndroidManifest.xml + min_sdk_version = getattr(attrs, "min_sdk_version", "14") or "14" + package = _java.resolve_package_from_label(Label(fqn), getattr(attrs, "custom_package", None)) + native.genrule( + name = targets.manifest_lib.name, + outs = [attrs.name + "/AndroidManifest.xml"], + cmd = """cat > $@ <<EOF +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="{package}"> + <uses-sdk + android:minSdkVersion="{min_sdk_version}"/> +</manifest> +EOF +""".format(package = package, min_sdk_version = min_sdk_version), + ) + + # Resource processing requires an android_library target + _android_library( + name = targets.title_lib.name, + custom_package = getattr(attrs, "custom_package", None), + manifest = str(targets.manifest_lib), + resource_files = [str(targets.title_strings_xml)], + tags = tags, + transitive_configs = transitive_configs, + visibility = visibility, + testonly = testonly, + ) + + # Wrap any deps in an android_binary. Will be validated to ensure does not contain any dexes + binary_attrs = { + "name": targets.binary.name, + "custom_package": getattr(attrs, "custom_package", None), + "manifest": str(targets.manifest_lib), + "deps": [attrs.library], + "multidex": "native", + "tags": tags, + "transitive_configs": transitive_configs, + "visibility": visibility, + "feature_flags": getattr(attrs, "feature_flags", None), + "$enable_manifest_merging": False, + "testonly": testonly, + } + _android_binary(**binary_attrs) + + android_feature_module( + name = attrs.name, + library = attrs.library, + binary = str(targets.binary), + title_id = title_id, + title_lib = str(targets.title_lib), + feature_name = getattr(attrs, "feature_name", attrs.name), + fused = getattr(attrs, "fused", True), + manifest = getattr(attrs, "manifest", None), + tags = tags, + transitive_configs = transitive_configs, + visibility = visibility, + testonly = testonly, + ) diff --git a/rules/android_application/attrs.bzl b/rules/android_application/attrs.bzl new file mode 100644 index 0000000..33e43fb --- /dev/null +++ b/rules/android_application/attrs.bzl @@ -0,0 +1,89 @@ +# 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. + +"""Attributes for android_application.""" + +load( + "@rules_android//rules:attrs.bzl", + _attrs = "attrs", +) + +ANDROID_APPLICATION_ATTRS = _attrs.add( + dict( + application_id = attr.string(), + base_module = attr.label(allow_files = False), + bundle_config_file = attr.label( + allow_single_file = [".pb.json"], + doc = ("Path to config.pb.json file, see " + + "https://github.com/google/bundletool/blob/master/src/main/proto/config.proto " + + "for definition.\n\nNote: this attribute is subject to changes which may " + + "require teams to migrate their configurations to a build target."), + ), + app_integrity_config = attr.label( + allow_single_file = [".binarypb"], + doc = "Configuration of the integrity protection options. " + + "Provide a path to a binary .binarypb instance of " + + "https://github.com/google/bundletool/blob/master/src/main/proto/app_integrity_config.proto", + ), + rotation_config = attr.label( + allow_single_file = [".textproto"], + default = None, + ), + custom_package = attr.string(), + feature_modules = attr.label_list(allow_files = False), + _bundle_deploy = attr.label( + allow_single_file = True, + default = ":bundle_deploy.sh_template", + ), + _feature_manifest_script = attr.label( + allow_single_file = True, + cfg = "host", + executable = True, + default = ":gen_android_feature_manifest.sh", + ), + _java_toolchain = attr.label( + default = Label("//tools/jdk:toolchain_android_only"), + ), + _priority_feature_manifest_script = attr.label( + allow_single_file = True, + cfg = "host", + executable = True, + default = ":gen_priority_android_feature_manifest.sh", + ), + _host_javabase = attr.label( + cfg = "host", + default = Label("//tools/jdk:current_java_runtime"), + ), + ), + _attrs.ANDROID_SDK, +) + +ANDROID_FEATURE_MODULE_ATTRS = dict( + binary = attr.label(), + feature_name = attr.string(), + library = attr.label( + allow_rules = ["android_library"], + mandatory = True, + doc = "android_library target to include as a feature split.", + ), + manifest = attr.label(allow_single_file = True), + title_id = attr.string(), + title_lib = attr.string(), + _feature_module_validation_script = attr.label( + allow_single_file = True, + cfg = "host", + executable = True, + default = ":feature_module_validation.sh", + ), +) diff --git a/rules/android_application/bundle_deploy.sh_template b/rules/android_application/bundle_deploy.sh_template new file mode 100644 index 0000000..37f6d4d --- /dev/null +++ b/rules/android_application/bundle_deploy.sh_template @@ -0,0 +1,26 @@ +#!/bin/bash --posix + +bundletool="%bundletool_path%" +aab="%aab%" +key="%key%" +tmp="$(mktemp /tmp/XXXXbundle.apks)" + +function cleanup { + rm -r "$tmp" +} +trap cleanup EXIT + +java -jar "$bundletool" build-apks \ + --bundle="$aab" \ + --output="$tmp" \ + --overwrite \ + --local-testing \ + --ks="$key" \ + --ks-pass=pass:android \ + --ks-key-alias=androiddebugkey \ + --key-pass=pass:android || exit + +java -jar "$bundletool" install-apks \ + --adb="$(which adb)" \ + --apks "$tmp" \ + --modules=_ALL_ || exit diff --git a/rules/android_application/feature_module_validation.sh b/rules/android_application/feature_module_validation.sh new file mode 100644 index 0000000..405b77d --- /dev/null +++ b/rules/android_application/feature_module_validation.sh @@ -0,0 +1,78 @@ +#!/bin/bash --posix +# 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. + +out="${1}" +manifest="${2}" +apk="${3}" +is_coverage="${4}" +is_java8="${5}" +lib_label="${6}" +xmllint="${7}" +unzip="${8}" + +if [[ -n "$manifest" ]]; then + node_count=$("$xmllint" --xpath "count(//manifest/*)" "$manifest") + module_count=$("$xmllint" --xpath "count(//manifest/*[local-name()='module'])" "$manifest") + application_count=$("$xmllint" --xpath "count(//manifest/*[local-name()='application'])" "$manifest") + application_attr_count=$("$xmllint" --xpath "count(//manifest/application/@*)" "$manifest") + application_content_count=$("$xmllint" --xpath "count(//manifest/application/*)" "$manifest") + module_title=$("$xmllint" --xpath "string(//manifest/*[local-name()='module'][1]/@*[local-name()='title'])" "$manifest") + valid=0 + + # Valid manifest, containing a dist:module and an empty <application/> + if [[ "$node_count" == "2" && + "$module_count" == "1" && + "$application_count" == "1" && + "$application_attr_count" == "0" && + "$application_content_count" == "0" ]]; then + valid=1 + fi + + # Valid manifest, containing a dist:module + if [[ "$node_count" == "1" && "$module_count" == "1" ]]; then + valid=1 + fi + + if [[ "$valid" == "0" ]]; then + echo "" + echo "$manifest should only contain a single <dist:module /> element (and optional empty <application/>), nothing else" + echo "Manifest contents: " + cat "$manifest" + exit 1 + fi + + if [[ "$module_title" != "\${MODULE_TITLE}" ]]; then + echo "" + echo "$manifest dist:title should be \${MODULE_TITLE} placeholder" + echo "" + exit 1 + fi +fi + +# Skip dex validation when running under code coverage. +# When running under code coverage an additional dep is implicitly added to all +# binary targets, causing a validation failure. +if [[ "$is_coverage" == "false" ]]; then + dexes=$("$unzip" -l "$apk" | grep ".dex" | wc -l) + if [[ ("$is_java8" == "true" && "$dexes" -gt 1 ) || ( "$is_java8" == "false" && "$dexes" -gt 0)]]; then + echo "" + echo "android_feature_module does not support Java or Kotlin sources." + echo "Check $lib_label for any srcs or deps." + echo "" + exit 1 + fi +fi + +touch "$out" diff --git a/rules/android_application/gen_android_feature_manifest.sh b/rules/android_application/gen_android_feature_manifest.sh new file mode 100644 index 0000000..5b5552e --- /dev/null +++ b/rules/android_application/gen_android_feature_manifest.sh @@ -0,0 +1,51 @@ +#!/bin/bash --posix +# 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. + +out_manifest="${1}" +base_apk="${2}" +package="${3}" +split="${4}" +title_id="${5}" +fused="${6}" +aapt="${7}" + +aapt_cmd="$aapt dump xmltree $base_apk --file AndroidManifest.xml" +version_code=$(${aapt_cmd} | grep "http://schemas.android.com/apk/res/android:versionCode" | cut -d "=" -f2 | head -n 1 ) +if [[ -z "$version_code" ]] +then + echo "Base app missing versionCode in AndroidManifest.xml" + exit 1 +fi + +cat >$out_manifest <<EOF +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:dist="http://schemas.android.com/apk/distribution" + package="$package" + split="$split" + android:versionCode="$version_code" + android:isFeatureSplit="true"> + + <dist:module + dist:instant="false" + dist:title="@string/$title_id"> <!-- title must be an ID! Needs to work with proguard/resource shrinking --> + <dist:fusing dist:include="$fused" /> + <dist:delivery> + <dist:on-demand /></dist:delivery> + </dist:module> + + <application android:hasCode="false" /> <!-- currently only supports asset splits --> +</manifest> +EOF diff --git a/rules/android_application/gen_priority_android_feature_manifest.sh b/rules/android_application/gen_priority_android_feature_manifest.sh new file mode 100644 index 0000000..cf646c8 --- /dev/null +++ b/rules/android_application/gen_priority_android_feature_manifest.sh @@ -0,0 +1,49 @@ +#!/bin/bash --posix +# 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. + +out_manifest="${1}" +base_apk="${2}" +package="${3}" +split="${4}" +aapt="${5}" + +aapt_cmd="$aapt dump xmltree $base_apk --file AndroidManifest.xml" +version_code=$(${aapt_cmd} | grep "http://schemas.android.com/apk/res/android:versionCode" | cut -d "=" -f2 | head -n 1) +min_sdk=$(${aapt_cmd} | grep "http://schemas.android.com/apk/res/android:minSdkVersion" | cut -d "=" -f2 | head -n 1) +if [[ -z "$version_code" ]] +then + echo "Base app missing versionCode in AndroidManifest.xml" + exit 1 +fi + +if [[ -z "$min_sdk" ]] +then + echo "Base app missing minsdk in AndroidManifest.xml" + exit 1 +fi + +cat >$out_manifest <<EOF +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:dist="http://schemas.android.com/apk/distribution" + package="$package" + split="$split" + android:versionCode="$version_code" + android:isFeatureSplit="true"> + + <application android:hasCode="false" /> <!-- currently only supports asset splits --> + <uses-sdk android:minSdkVersion="$min_sdk" /> +</manifest> +EOF diff --git a/rules/android_binary.bzl b/rules/android_binary.bzl index 1760e75..5d33512 100644 --- a/rules/android_binary.bzl +++ b/rules/android_binary.bzl @@ -15,7 +15,7 @@ """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") +load("@rules_android//rules/android_binary_internal:rule.bzl", "android_binary_internal_macro") def android_binary(**attrs): """Bazel android_binary rule. @@ -25,11 +25,11 @@ def android_binary(**attrs): Args: **attrs: Rule attributes """ - packaged_resources_name = ":%s_RESOURCES_DO_NOT_USE" % attrs["name"] - android_packaged_resources_macro( + android_binary_internal_name = ":%s_RESOURCES_DO_NOT_USE" % attrs["name"] + android_binary_internal_macro( **dict( attrs, - name = packaged_resources_name[1:], + name = android_binary_internal_name[1:], visibility = ["//visibility:private"], ) ) @@ -37,6 +37,6 @@ def android_binary(**attrs): attrs.pop("$enable_manifest_merging", None) native.android_binary( - application_resources = packaged_resources_name, + application_resources = android_binary_internal_name, **add_migration_tag(attrs) ) diff --git a/rules/android_packaged_resources/BUILD b/rules/android_binary_internal/BUILD index f858689..2440016 100644 --- a/rules/android_packaged_resources/BUILD +++ b/rules/android_binary_internal/BUILD @@ -1,16 +1,9 @@ -# Starlark Resource Packaging for Android Rules. +# The android_binary_internal rule. 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(["**"]), diff --git a/rules/android_packaged_resources/attrs.bzl b/rules/android_binary_internal/attrs.bzl index 5a7bca7..5a7bca7 100644 --- a/rules/android_packaged_resources/attrs.bzl +++ b/rules/android_binary_internal/attrs.bzl diff --git a/rules/android_packaged_resources/impl.bzl b/rules/android_binary_internal/impl.bzl index e3d6ac0..6838a81 100644 --- a/rules/android_packaged_resources/impl.bzl +++ b/rules/android_binary_internal/impl.bzl @@ -44,7 +44,7 @@ def _process_resources(ctx, java_package, **unused_ctxs): 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, + deps = utils.dedupe_split_attr(ctx.split_attr.deps), instruments = ctx.attr.instruments, aapt = get_android_toolchain(ctx).aapt2.files_to_run, android_jar = ctx.attr._android_sdk[AndroidSdkInfo].android_jar, diff --git a/rules/android_packaged_resources/rule.bzl b/rules/android_binary_internal/rule.bzl index db3f96a..3070688 100644 --- a/rules/android_packaged_resources/rule.bzl +++ b/rules/android_binary_internal/rule.bzl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Starlark Resource Packaging for Android Rules.""" +"""Starlark Android Binary for Android Rules.""" load(":attrs.bzl", "ATTRS") load(":impl.bzl", "impl") @@ -25,7 +25,6 @@ _DEFAULT_ALLOWED_ATTRS = ["name", "visibility", "tags", "testonly", "transitive_ _DEFAULT_PROVIDES = [AndroidApplicationResourceInfo, OutputGroupInfo] -# TODO(b/167721629): Rename android_packaged_resources to android_binary_internal. def make_rule( attrs = ATTRS, implementation = impl, @@ -52,17 +51,17 @@ def make_rule( ], ) -_android_packaged_resources = make_rule() +android_binary_internal = 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 + The android_binary_internal 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. + attrs: A dict. The attributes for the android_binary_internal rule. allowed_attrs: The list of attribute keys to keep. Returns: @@ -82,10 +81,10 @@ def sanitize_attrs(attrs, allowed_attrs = ATTRS.keys()): return attrs -def android_packaged_resources_macro(**attrs): - """android_packaged_resources rule. +def android_binary_internal_macro(**attrs): + """android_binary_internal rule. Args: **attrs: Rule attributes """ - _android_packaged_resources(**sanitize_attrs(attrs)) + android_binary_internal(**sanitize_attrs(attrs)) diff --git a/rules/android_library/attrs.bzl b/rules/android_library/attrs.bzl index 16a18e7..8e38b01 100644 --- a/rules/android_library/attrs.bzl +++ b/rules/android_library/attrs.bzl @@ -29,8 +29,8 @@ ATTRS = _attrs.add( ), enable_data_binding = attr.bool(default = False), exported_plugins = attr.label_list( - allow_rules = [ - "java_plugin", + providers = [ + [JavaPluginInfo], ], cfg = "host", ), @@ -59,7 +59,6 @@ ATTRS = _attrs.add( _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 @@ -67,6 +66,7 @@ ATTRS = _attrs.add( _flags = attr.label( default = "@rules_android//rules/flags", ), + _package_name = attr.string(), # for sending the package name to the outputs callback ), _attrs.COMPILATION, _attrs.DATA_CONTEXT, diff --git a/rules/android_library/impl.bzl b/rules/android_library/impl.bzl index 232899c..286d7b5 100644 --- a/rules/android_library/impl.bzl +++ b/rules/android_library/impl.bzl @@ -151,7 +151,7 @@ def _process_resources(ctx, java_package, **unused_ctxs): # 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, + propagate_resources = not ctx.attr._android_test_migration, # Tool and Processing related inputs aapt = get_android_toolchain(ctx).aapt2.files_to_run, @@ -211,11 +211,12 @@ def _process_data_binding(ctx, java_package, resources_ctx, **unused_sub_ctxs): defines_resources = resources_ctx.defines_resources, enable_data_binding = ctx.attr.enable_data_binding, java_package = java_package, + layout_info = resources_ctx.data_binding_layout_info, 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], + get_android_toolchain(ctx).data_binding_annotation_processor[JavaPluginInfo], data_binding_annotation_template = utils.only(get_android_toolchain(ctx).data_binding_annotation_template.files.to_list()), ), @@ -252,11 +253,11 @@ def _process_jvm(ctx, exceptions_ctx, resources_ctx, idl_ctx, db_ctx, **unused_s 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) + + utils.collect_providers(JavaPluginInfo, ctx.attr.plugins) + db_ctx.java_plugins ), exported_plugins = utils.collect_providers( - JavaInfo, + JavaPluginInfo, ctx.attr.exported_plugins, ), annotation_processor_additional_outputs = ( @@ -339,9 +340,9 @@ def _process_native(ctx, idl_ctx, **unused_ctx): AndroidCcLinkParamsInfo( cc_common.merge_cc_infos( cc_infos = [ - info.cc_info + info.cc_link_params_info for info in utils.collect_providers( - JavaCcLinkParamsInfo, + JavaInfo, ctx.attr.deps, ctx.attr.exports, idl_ctx.idl_deps, @@ -431,11 +432,9 @@ def _make_legacy_provider(intellij_ctx, jvm_ctx, providers): 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, ), @@ -500,6 +499,7 @@ def finalize( [ctx.outputs.lib_src_jar], transitive = [jvm_ctx.java_info.transitive_source_jars], ), + _direct_source_jars = depset([ctx.outputs.lib_src_jar]), _hidden_top_level_INTERNAL_ = depset( resources_ctx.validation_results, transitive = [ diff --git a/rules/android_library/rule.bzl b/rules/android_library/rule.bzl index f267b37..02cc1fc 100644 --- a/rules/android_library/rule.bzl +++ b/rules/android_library/rule.bzl @@ -14,6 +14,7 @@ """android_library rule.""" +load("@rules_android//rules:acls.bzl", "acls") load(":attrs.bzl", _ATTRS = "ATTRS") load(":impl.bzl", _impl = "impl") load( @@ -21,7 +22,7 @@ load( _attrs = "attrs", ) -def _outputs(_defined_local_resources): +def _outputs(name, _package_name, _defined_local_resources): outputs = dict( lib_jar = "lib%{name}.jar", lib_src_jar = "lib%{name}-src.jar", @@ -31,11 +32,16 @@ def _outputs(_defined_local_resources): if _defined_local_resources: # TODO(b/177261846): resource-related predeclared outputs need to be re-pointed at the # corresponding artifacts in the Starlark pipeline. + label = "//" + _package_name + ":" + name + if acls.in_android_library_starlark_resource_outputs_rollout(label): + path_prefix = "_migrated/" + else: + path_prefix = "" outputs.update( dict( - resources_src_jar = "_migrated/%{name}.srcjar", - resources_txt = "_migrated/%{name}_symbols/R.txt", - resources_jar = "_migrated/%{name}_resources.jar", + resources_src_jar = path_prefix + "%{name}.srcjar", + resources_txt = path_prefix + "%{name}_symbols/R.txt", + resources_jar = path_prefix + "%{name}_resources.jar", ), ) @@ -51,6 +57,8 @@ def make_rule( Args: attrs: A dict. The attributes for the rule. implementation: A function. The rule's implementation method. + outputs: A dict, function, or None. The rule's outputs. + additional_toolchains: A list. Additional toolchains passed to pass to rule(toolchains). Returns: A rule. @@ -122,6 +130,11 @@ def attrs_metadata(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) + + # Required for ACLs check in _outputs(), since the callback can't access + # the native module. + attrs["$package_name"] = native.package_name() + return attrs def android_library_macro(**attrs): diff --git a/rules/android_sdk.bzl b/rules/android_sdk.bzl index cf824e1..e5e1fa7 100644 --- a/rules/android_sdk.bzl +++ b/rules/android_sdk.bzl @@ -39,6 +39,7 @@ def _impl(ctx): # 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, + ctx.attr.legacy_main_dex_list_generator.files_to_run if ctx.attr.legacy_main_dex_list_generator else None, ) return [ android_sdk_info, diff --git a/rules/attrs.bzl b/rules/attrs.bzl index eca1947..af389ff 100644 --- a/rules/attrs.bzl +++ b/rules/attrs.bzl @@ -79,7 +79,7 @@ _tristate = struct( _JAVA_RUNTIME = dict( _host_javabase = attr.label( cfg = "host", - default = Label("@rules_android//rules:current_java_runtime"), + default = Label("@rules_android//tools/jdk:current_java_runtime"), ), ) @@ -115,7 +115,7 @@ _COMPILATION = _add( allow_files = True, ), plugins = attr.label_list( - allow_rules = ["java_plugin"], + providers = [JavaPluginInfo], cfg = "host", ), javacopts = attr.string_list(), @@ -228,6 +228,11 @@ ANDROID_SDK_ATTRS = dict( cfg = "host", mandatory = True, ), + legacy_main_dex_list_generator = attr.label( + allow_files = True, + cfg = "host", + executable = True, + ), main_dex_classes = attr.label( allow_single_file = True, cfg = "host", @@ -248,7 +253,6 @@ ANDROID_SDK_ATTRS = dict( shrinked_android_jar = attr.label( allow_single_file = True, cfg = "host", - mandatory = True, ), source_properties = attr.label( allow_single_file = True, diff --git a/rules/bundletool.bzl b/rules/bundletool.bzl new file mode 100644 index 0000000..161882a --- /dev/null +++ b/rules/bundletool.bzl @@ -0,0 +1,263 @@ +# 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 Bundletool Commands.""" + +load(":java.bzl", _java = "java") + +_density_mapping = { + "ldpi": 120, + "mdpi": 160, + "hdpi": 240, + "xhdpi": 320, + "xxhdpi": 480, + "xxxhdpi": 640, + "tvdpi": 213, +} + +def _proto_apk_to_module( + ctx, + out = None, + proto_apk = None, + zip = None, + unzip = None): + # TODO(timpeut): rewrite this as a standalone golang tool + ctx.actions.run_shell( + command = """ +set -e + +IN_DIR=$(mktemp -d) +OUT_DIR=$(mktemp -d) +CUR_PWD=$(pwd) +UNZIP=%s +ZIP=%s +INPUT=%s +OUTPUT=%s + +"${UNZIP}" -qq "${INPUT}" -d "${IN_DIR}" +cd "${IN_DIR}" + +if [ -f resources.pb ]; then + mv resources.pb "${OUT_DIR}/" +fi + +if [ -f AndroidManifest.xml ]; then + mkdir "${OUT_DIR}/manifest" + mv AndroidManifest.xml "${OUT_DIR}/manifest/" +fi + +NUM_DEX=`ls -1 *.dex 2>/dev/null | wc -l` +if [ $NUM_DEX != 0 ]; then + mkdir "${OUT_DIR}/dex" + mv *.dex "${OUT_DIR}/dex/" +fi + +if [ -d res ]; then + mv res "${OUT_DIR}/res" +fi + +if [ -d assets ]; then + mv assets "${OUT_DIR}/" +fi + +if [ -d lib ]; then + mv lib "${OUT_DIR}/" +fi + +UNKNOWN=`ls -1 * 2>/dev/null | wc -l` +if [ $UNKNOWN != 0 ]; then + mkdir "${OUT_DIR}/root" + mv * "${OUT_DIR}/root/" +fi + +cd "${OUT_DIR}" +"${CUR_PWD}/${ZIP}" "${CUR_PWD}/${OUTPUT}" -Drq0 . +""" % ( + unzip.executable.path, + zip.executable.path, + proto_apk.path, + out.path, + ), + tools = [zip, unzip], + arguments = [], + inputs = [proto_apk], + outputs = [out], + mnemonic = "Rebundle", + progress_message = "Rebundle to %s" % out.short_path, + ) + +def _build( + ctx, + out = None, + modules = [], + config = None, + metadata = dict(), + bundletool = None, + host_javabase = None): + args = ctx.actions.args() + args.add("build-bundle") + args.add("--output", out) + if modules: + args.add_joined("--modules", modules, join_with = ",") + if config: + args.add("--config", config) + for path, f in metadata.items(): + args.add("--metadata-file", "%s:%s" % (path, f.path)) + + _java.run( + ctx = ctx, + host_javabase = host_javabase, + executable = bundletool, + arguments = [args], + inputs = ( + modules + + ([config] if config else []) + + metadata.values() + ), + outputs = [out], + mnemonic = "BuildBundle", + progress_message = "Building bundle %s" % out.short_path, + ) + +def _extract_config( + ctx, + out = None, + aab = None, + bundletool = None, + host_javabase = None): + # Need to execute as a shell script as the tool outputs to stdout + cmd = """ +set -e +contents=`%s -jar %s dump config --bundle %s` +echo "$contents" > %s +""" % ( + host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path, + bundletool.executable.path, + aab.path, + out.path, + ) + + ctx.actions.run_shell( + inputs = [aab], + outputs = [out], + tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]), + mnemonic = "ExtractBundleConfig", + progress_message = "Extract bundle config to %s" % out.short_path, + command = cmd, + ) + +def _extract_manifest( + ctx, + out = None, + aab = None, + module = None, + xpath = None, + bundletool = None, + host_javabase = None): + # Need to execute as a shell script as the tool outputs to stdout + extra_flags = [] + if module: + extra_flags.append("--module " + module) + if xpath: + extra_flags.append("--xpath " + xpath) + cmd = """ +set -e +contents=`%s -jar %s dump manifest --bundle %s %s` +echo "$contents" > %s +""" % ( + host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path, + bundletool.executable.path, + aab.path, + " ".join(extra_flags), + out.path, + ) + + ctx.actions.run_shell( + inputs = [aab], + outputs = [out], + tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]), + mnemonic = "ExtractBundleManifest", + progress_message = "Extract bundle manifest to %s" % out.short_path, + command = cmd, + ) + +def _bundle_to_apks( + ctx, + out = None, + bundle = None, + universal = False, + device_spec = None, + keystore = None, + modules = None, + aapt2 = None, + bundletool = None, + host_javabase = None): + inputs = [bundle] + args = ctx.actions.args() + args.add("build-apks") + args.add("--output", out) + args.add("--bundle", bundle) + args.add("--aapt2", aapt2.executable.path) + + if universal: + args.add("--mode=universal") + + if keystore: + args.add("--ks", keystore.path) + args.add("--ks-pass", "pass:android") + args.add("--ks-key-alias", "AndroidDebugKey") + inputs.append(keystore) + + if device_spec: + args.add("--device-spec", device_spec) + inputs.append(device_spec) + + if modules: + args.add_joined("--modules", modules, join_with = ",") + + _java.run( + ctx = ctx, + host_javabase = host_javabase, + executable = bundletool, + arguments = [args], + inputs = inputs, + outputs = [out], + tools = [aapt2], + mnemonic = "BundleToApks", + progress_message = "Converting bundle to .apks: %s" % out.short_path, + ) + +def _build_device_json( + ctx, + out, + abis, + locales, + density, + sdk_version): + json_content = json.encode(struct( + supportedAbis = abis, + supportedLocales = locales, + screenDensity = _density_mapping[density], + sdkVersion = int(sdk_version), + )) + ctx.actions.write(out, json_content) + +bundletool = struct( + build = _build, + build_device_json = _build_device_json, + bundle_to_apks = _bundle_to_apks, + extract_config = _extract_config, + extract_manifest = _extract_manifest, + proto_apk_to_module = _proto_apk_to_module, +) diff --git a/rules/busybox.bzl b/rules/busybox.bzl index f0d78ac..a92fe68 100644 --- a/rules/busybox.bzl +++ b/rules/busybox.bzl @@ -191,6 +191,7 @@ def _package( resource_configs = None, densities = [], application_id = None, + package_id = None, direct_resources_nodes = [], transitive_resources_nodes = [], transitive_manifests = [], @@ -233,6 +234,11 @@ def _package( 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. + package_id: An optional integer in [2,255]. This is the prefix byte for + all generated resource IDs, defaults to 0x7F (127). 1 is reserved by the + framework, and some builds are known to crash when given IDs > 127. + Shared libraries are also assigned monotonically increasing IDs in + [2,126], so care should be taken that there is room at the lower end. direct_resources_nodes: Depset of ResourcesNodeInfo providers. The set of ResourcesNodeInfo from direct dependencies. transitive_resources_nodes: Depset of ResourcesNodeInfo providers. The set @@ -356,6 +362,8 @@ def _package( args.add_joined("--densities", _extract_filters(densities), join_with = ",") if application_id: args.add("--applicationId", application_id) + if package_id: + args.add("--packageId", package_id) if additional_apks_to_link_against: args.add_joined( "--additionalApksToLinkAgainst", @@ -372,7 +380,8 @@ def _package( args.add("--versionName", version_name) if version_code: args.add("--versionCode", version_code) - args.add("--packageForR", java_package) + if java_package: + args.add("--packageForR", java_package) _java.run( ctx = ctx, @@ -792,7 +801,7 @@ def _merge_manifests( fail("Unexpected manifest merge type: " + merge_type) outputs = [out_file] - directs = [manifest] + directs = [manifest] if manifest else [] transitives = [mergee_manifests] # Args for busybox @@ -800,7 +809,8 @@ def _merge_manifests( args.use_param_file("@%s", use_always = True) args.add("--tool", "MERGE_MANIFEST") args.add("--") - args.add("--manifest", manifest) + if manifest: + args.add("--manifest", manifest) args.add_all( "--mergeeManifests", [mergee_manifests], @@ -812,7 +822,8 @@ def _merge_manifests( ",".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) + if java_package: + args.add("--customPackage", java_package) args.add("--manifestOutput", out_file) if out_log_file: args.add("--log", out_log_file) @@ -919,7 +930,8 @@ def _generate_binary_r( args.add("--") args.add("--primaryRTxt", r_txt) args.add("--primaryManifest", manifest) - args.add("--packageForR", package_for_r) + if package_for_r: + args.add("--packageForR", package_for_r) args.add_all( resources_nodes, map_each = _make_generate_binay_r_flags, @@ -933,6 +945,7 @@ def _generate_binary_r( # 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)) + args.use_param_file("@%s") _java.run( ctx = ctx, diff --git a/rules/data_binding.bzl b/rules/data_binding.bzl index 39923ec..9243673 100644 --- a/rules/data_binding.bzl +++ b/rules/data_binding.bzl @@ -54,8 +54,7 @@ def _copy_annotation_file(ctx, output_dir, annotation_template): _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") +def _gen_sources(ctx, output_dir, java_package, deps, layout_info, data_binding_exec): class_info = ctx.actions.declare_file(output_dir + "class-info.zip") srcjar = ctx.actions.declare_file(output_dir + "baseClassSrc.srcjar") @@ -67,22 +66,34 @@ def _gen_sources(ctx, output_dir, java_package, deps, data_binding_exec): args.add("-zipSourceOutput", "true") args.add("-useAndroidX", "false") - class_infos = [] - for info in deps: - class_infos.extend(info.class_infos) + if deps: + if type(deps[0].class_infos) == "depset": + class_infos = depset(transitive = [info.class_infos for info in deps]) + inputs = depset(direct = [layout_info], transitive = [class_infos]) + elif type(deps[0].class_infos) == "list": + class_infos = [] + for info in deps: + class_infos.extend(info.class_infos) + inputs = class_infos + [layout_info] + else: + fail("Expected list or depset. Got %s" % type(deps[0].class_infos)) + else: + class_infos = [] + inputs = [layout_info] + 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], + inputs = inputs, outputs = [class_info, srcjar], mnemonic = "GenerateDataBindingBaseClasses", progress_message = ( "GenerateDataBindingBaseClasses %s" % class_info.short_path ), ) - return srcjar, class_info, layout_info + return srcjar, class_info def _setup_dependent_lib_artifacts(ctx, output_dir, deps): # DataBinding requires files in very specific locations. @@ -92,8 +103,8 @@ def _setup_dependent_lib_artifacts(ctx, output_dir, deps): for info in deps: # Yes, DataBinding requires depsets iterations. for artifact in (info.transitive_br_files.to_list() + - info.setter_stores + - info.class_infos): + _utils.list_or_depset_to_list(info.setter_stores) + + _utils.list_or_depset_to_list(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 @@ -157,6 +168,7 @@ def _process( defines_resources = False, enable_data_binding = False, java_package = None, + layout_info = None, deps = [], exports = [], data_binding_exec = None, @@ -174,6 +186,7 @@ def _process( deps: sequence of DataBindingV2Info providers. A list of deps. Optional. exports: sequence of DataBindingV2Info providers. A list of exports. Optional. + layout_info: A file. The layout-info zip file. data_binding_exec: The DataBinding executable. data_binding_annotation_processor: JavaInfo. The JavaInfo for the annotation processor. @@ -207,7 +220,7 @@ def _process( ] return struct(**db_info) - output_dir = "_migrated/databinding/%s/" % ctx.label.name + output_dir = "databinding/%s/" % ctx.label.name db_info[_JAVA_SRCS].append(_copy_annotation_file( ctx, @@ -219,7 +232,6 @@ def _process( 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( @@ -233,11 +245,12 @@ def _process( setter_store_out, ) - srcjar, class_info, layout_info = _gen_sources( + srcjar, class_info = _gen_sources( ctx, output_dir, java_package, deps, + layout_info, data_binding_exec, ) db_info[_JAVA_SRCS].append(srcjar) diff --git a/rules/flags/flag_defs.bzl b/rules/flags/flag_defs.bzl index cecb40a..08eee2d 100644 --- a/rules/flags/flag_defs.bzl +++ b/rules/flags/flag_defs.bzl @@ -31,7 +31,7 @@ def define_flags(): flags.DEFINE_int( name = "num_dex_shards", - default = 16, + default = 32, description = "Number of dex shards to use for mobile-install.", ) @@ -64,7 +64,7 @@ def define_flags(): flags.DEFINE_bool( name = "enable_splits", - default = False, + default = True, description = "Build and install split apks if the device supports them.", ) @@ -86,6 +86,7 @@ def define_flags(): description = "", ) + flags.EXPOSE_native_bool( name = "stamp", description = "Accesses the native --stamp CLI flag", diff --git a/rules/java.bzl b/rules/java.bzl index 7b23b35..2e2fc58 100644 --- a/rules/java.bzl +++ b/rules/java.bzl @@ -88,8 +88,7 @@ def _resolve_package(path): def _resolve_package_from_label( label, - custom_package = None, - fallback = True): + custom_package = None): """Resolves the Java package from a Label. When no legal Java package can be resolved from the label, None will be @@ -110,15 +109,7 @@ def _resolve_package_from_label( [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 + return _resolve_package(label_path) def _root(path): """Determines the Java root from the given path. @@ -203,8 +194,8 @@ def _compile_android( 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: sequence of JavaPluginInfo providers. A list of plugins. Optional. + exported_plugins: sequence of JavaPluginInfo providers. A list of exported plugins. Optional. annotation_processor_additional_outputs: sequence of Files. A list of files produced by an annotation processor. @@ -219,7 +210,6 @@ def _compile_android( 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. @@ -304,8 +294,8 @@ def _compile( 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: sequence of JavaPluginInfo providers. A list of plugins. Optional. + exported_plugins: sequence of JavaPluginInfo providers. A list of exported plugins. Optional. annotation_processor_additional_outputs: sequence of Files. A list of files produced by an annotation processor. @@ -321,7 +311,6 @@ def _compile( 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. @@ -384,8 +373,11 @@ def _singlejar( args.add("--sources") args.add_all(inputs) + args.use_param_file("@%s") + args.set_param_file_format("multiline") + ctx.actions.run( - executable = java_toolchain.java_toolchain.single_jar, + executable = java_toolchain[java_common.JavaToolchainInfo].single_jar, arguments = [args], inputs = inputs, outputs = [output], @@ -396,12 +388,14 @@ def _singlejar( def _run( ctx, host_javabase, + jvm_flags = [], **args): """Run a java binary Args: ctx: The context. host_javabase: Target. The host_javabase. + jvm_flags: Additional arguments to the JVM itself. **args: Additional arguments to pass to ctx.actions.run(). Some will get modified. """ @@ -411,6 +405,10 @@ def _run( if type(host_javabase) != "Target": fail("Expected type Target for argument host_javabase, got %s" % type(host_javabase)) + # Set reasonable max heap default. Required to prevent runaway memory usage. + # Can still be overridden by callers of this method. + jvm_flags = ["-Xmx4G", "-XX:+ExitOnOutOfMemoryError"] + jvm_flags + # executable should be a File or a FilesToRunProvider jar = args.get("executable") if type(jar) == "FilesToRunProvider": @@ -431,7 +429,7 @@ def _run( jar_args = ctx.actions.args() jar_args.add("-jar", jar) - args["arguments"] = [jar_args] + args.get("arguments", default = []) + args["arguments"] = jvm_flags + [jar_args] + args.get("arguments", default = []) ctx.actions.run(**args) diff --git a/rules/platforms/BUILD b/rules/platforms/BUILD deleted file mode 100644 index 778c849..0000000 --- a/rules/platforms/BUILD +++ /dev/null @@ -1,33 +0,0 @@ -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/providers.bzl b/rules/providers.bzl index fd92708..e7db209 100644 --- a/rules/providers.bzl +++ b/rules/providers.bzl @@ -92,6 +92,7 @@ StarlarkAndroidResourcesInfo = provider( transitive_manifests = "Depset of transitive manifests", transitive_r_txts = "Depset of transitive R.txt files", transitive_resource_files = "Depset of transitive resource files", + packages_to_r_txts = "Map of packages to depset of r_txt files", ), ) @@ -102,7 +103,37 @@ AndroidLintRulesInfo = provider( ), ) +AndroidFeatureModuleInfo = provider( + doc = "Contains data required to build an Android feature split.", + fields = dict( + binary = "String, target of the underlying split android_binary target", + feature_name = "String, the name of the feature module. If unspecified, the target name will be used.", + fused = "Boolean, whether the split is \"fused\" for the system image and for pre-L devices.", + library = "String, target of the underlying split android_library target", + manifest = "Optional AndroidManifest.xml file to use for this feature.", + min_sdk_version = "String, the min SDK version for this feature.", + title_id = "String, resource identifier for the split title.", + title_lib = "String, target of the split title android_library.", + ), +) + + +Dex2OatApkInfo = provider( + doc = "Contains data about artifacts generated through host dex2oat.", + fields = dict( + signed_apk = "Signed APK", + oat_file = "Oat file generated through dex2oat.", + vdex_file = "Vdex file generated through dex2oat.", + art_file = "ART file generated through dex2oat.", + ), +) +InstrumentedAppInfo = provider( + doc = "Contains data about an android_binary's instrumented android_binary.", + fields = dict( + android_ide_info = "AndroidIdeInfo provider from the instrumented android_binary.", + ), +) FailureInfo = provider( fields = dict( diff --git a/rules/resources.bzl b/rules/resources.bzl index 386196d..2ad89c6 100644 --- a/rules/resources.bzl +++ b/rules/resources.bzl @@ -60,11 +60,6 @@ _ASSET_DEFINITION_ERROR = ( "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) @@ -76,6 +71,7 @@ _VERSION_CODE = "versionCode" # Resources context attributes. _ASSETS_PROVIDER = "assets_provider" +_DATA_BINDING_LAYOUT_INFO = "data_binding_layout_info" _DEFINES_RESOURCES = "defines_resources" _DIRECT_ANDROID_RESOURCES = "direct_android_resources" _MERGED_MANIFEST = "merged_manifest" @@ -97,6 +93,7 @@ _ResourcesProcessContextInfo = provider( _MERGED_MANIFEST: "Merged manifest.", _PROVIDERS: "The list of all providers to propagate.", _R_JAVA: "JavaInfo for R.jar.", + _DATA_BINDING_LAYOUT_INFO: "Databinding layout info file.", _RESOURCES_APK: "ResourcesApk.", _VALIDATION_RESULTS: "List of validation results.", _VALIDATION_OUTPUTS: "List of outputs given to OutputGroupInfo _validation group", @@ -125,6 +122,7 @@ _ResourcesPackageContextInfo = provider( _PACKAGED_CLASS_JAR: "R class jar.", _PACKAGED_VALIDATION_RESULT: "Validation result.", _R_JAVA: "JavaInfo for R.jar", + _DATA_BINDING_LAYOUT_INFO: "Databinding layout info file.", _PROVIDERS: "The list of all providers to propagate.", }, ) @@ -136,7 +134,7 @@ def _generate_dummy_manifest( 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 + package="%s">""" % (java_package or "com.default") if min_sdk_version: content = content + """ @@ -313,6 +311,7 @@ def _fix_databinding_compiled_resources( ctx: The context. out_compiled_resources: File. The modified compiled_resources output. compiled_resources: File. The compiled_resources zip. + zip_tool: FilesToRunProvider. The zip tool executable or FilesToRunProvider """ ctx.actions.run_shell( outputs = [out_compiled_resources], @@ -417,6 +416,7 @@ def _package( resource_files = [], nocompress_extensions = [], java_package = None, + package_id = None, compilation_mode = _compilation_mode.FASTBUILD, shrink_resources = None, use_android_resource_shrinking = None, @@ -457,6 +457,11 @@ def _package( 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. + package_id: An optional integer in [2,255]. This is the prefix byte for + all generated resource IDs, defaults to 0x7F (127). 1 is reserved by the + framework, and some builds are known to crash when given IDs > 127. + Shared libraries are also assigned monotonically increasing IDs in + [2,126], so care should be taken that there is room at the lower end. 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. @@ -490,9 +495,6 @@ def _package( """ _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: [], } @@ -520,6 +522,7 @@ def _package( transitive_compiled_resources = [] transitive_manifests = [] transitive_r_txts = [] + packages_to_r_txts_depset = dict() for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, deps): direct_resources_nodes.append(dep.direct_resources_nodes) transitive_resources_nodes.append(dep.transitive_resources_nodes) @@ -530,6 +533,8 @@ def _package( transitive_compiled_resources.append(dep.transitive_compiled_resources) transitive_manifests.append(dep.transitive_manifests) transitive_r_txts.append(dep.transitive_r_txts) + for pkg, r_txts in dep.packages_to_r_txts.items(): + packages_to_r_txts_depset.setdefault(pkg, []).append(r_txts) mergee_manifests = depset([ node_info.manifest @@ -574,16 +579,16 @@ def _package( ) processed_resources = resource_files - databinding_info = None + data_binding_layout_info = None if enable_data_binding: - databinding_info = ctx.actions.declare_file("_migrated/databinding/" + ctx.label.name + "/layout-info.zip") + data_binding_layout_info = ctx.actions.declare_file("_migrated/" + 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_info = data_binding_layout_info, out_databinding_processed_resources = processed_resources, databinding_resources_dirname = resources_dirname, resource_files = resource_files, @@ -617,6 +622,7 @@ def _package( out_main_dex_proguard_cfg = main_dex_proguard_cfg, out_resource_files_zip = resource_files_zip, application_id = manifest_values.get("applicationId", None), + package_id = package_id, manifest = merged_manifest, assets = assets, assets_dir = assets_dir, @@ -688,6 +694,29 @@ def _package( ) packaged_resources_ctx[_R_JAVA] = java_info + packaged_resources_ctx[_DATA_BINDING_LAYOUT_INFO] = data_binding_layout_info + + packages_to_r_txts_depset.setdefault(java_package, []).append(depset([r_txt])) + + packages_to_r_txts = dict() + for pkg, depsets in packages_to_r_txts_depset.items(): + packages_to_r_txts[pkg] = depset(transitive = depsets) + + # Adding empty depsets to unused fields of StarlarkAndroidResourcesInfo. + # Some root targets may depends on other root targets and try to access those fields. + packaged_resources_ctx[_PROVIDERS].append(StarlarkAndroidResourcesInfo( + direct_resources_nodes = depset(), + transitive_resources_nodes = depset(), + transitive_assets = depset(), + transitive_assets_symbols = depset(), + transitive_compiled_assets = depset(), + transitive_resource_files = depset(), + direct_compiled_resources = depset(), + transitive_compiled_resources = depset(), + transitive_manifests = depset(), + transitive_r_txts = depset(), + packages_to_r_txts = packages_to_r_txts, + )) packaged_resources_ctx[_PROVIDERS].append(AndroidApplicationResourceInfo( resource_apk = resource_apk, @@ -698,7 +727,7 @@ def _package( main_dex_proguard_config = main_dex_proguard_cfg, r_txt = r_txt, resources_zip = resource_files_zip, - databinding_info = databinding_info, + databinding_info = data_binding_layout_info, )) return _ResourcesPackageContextInfo(**packaged_resources_ctx) @@ -955,7 +984,7 @@ def _process_starlark( resource_files = None, neverlink = False, enable_data_binding = False, - android_test_migration = False, + propagate_resources = True, fix_resource_transitivity = False, aapt = None, android_jar = None, @@ -1002,9 +1031,9 @@ def _process_starlark( 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. + propagate_resources: boolean. If false, the target will no longer propagate + providers required for Android Resource processing/packaging. But will + continue to propagate others (AndroidLibraryResourceClassJarProvider). fix_resource_transitivity: Whether to ensure that transitive resources are correctly marked as transitive. aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider. @@ -1056,6 +1085,7 @@ def _process_starlark( _VALIDATION_RESULTS: [], _DEFINES_RESOURCES: defines_resources, _R_JAVA: None, + _DATA_BINDING_LAYOUT_INFO: None, _MERGED_MANIFEST: None, _STARLARK_PROCESSED_MANIFEST: None, _STARLARK_R_TXT: None, @@ -1065,9 +1095,6 @@ def _process_starlark( 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 = [] @@ -1078,6 +1105,7 @@ def _process_starlark( transitive_resources_files = [] transitive_manifests = [] transitive_r_txts = [] + packages_to_r_txts_depset = dict() for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, deps): direct_resources_nodes.append(dep.direct_resources_nodes) @@ -1090,6 +1118,8 @@ def _process_starlark( transitive_resources_files.append(dep.transitive_resource_files) transitive_manifests.append(dep.transitive_manifests) transitive_r_txts.append(dep.transitive_r_txts) + for pkg, r_txts in dep.packages_to_r_txts.items(): + packages_to_r_txts_depset.setdefault(pkg, []).append(r_txts) exports_direct_resources_nodes = [] exports_transitive_resources_nodes = [] @@ -1112,6 +1142,8 @@ def _process_starlark( 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) + for pkg, r_txts in dep.packages_to_r_txts.items(): + packages_to_r_txts_depset.setdefault(pkg, []).append(r_txts) # TODO(b/144134042): Don't merge exports; exports are not deps. direct_resources_nodes.extend(exports_direct_resources_nodes) @@ -1130,6 +1162,7 @@ def _process_starlark( compiled_resources = None out_aapt2_r_txt = None r_txt = None + data_binding_layout_info = None processed_resources = resource_files processed_manifest = None if not defines_resources: @@ -1140,8 +1173,9 @@ def _process_starlark( ) _generate_dummy_manifest( ctx, - generated_manifest, - java_package if java_package else ctx.label.package.replace("/", "."), + out_manifest = generated_manifest, + java_package = java_package if java_package else ctx.label.package.replace("/", "."), + min_sdk_version = 14, ) r_txt = ctx.actions.declare_file( "_migrated/" + ctx.label.name + "_symbols/R.txt", @@ -1261,7 +1295,7 @@ def _process_starlark( ) if enable_data_binding: - out_databinding_info = ctx.actions.declare_file( + data_binding_layout_info = ctx.actions.declare_file( "_migrated/databinding/" + ctx.label.name + "/layout-info.zip", ) processed_resources, resources_dirname = _make_databinding_outputs( @@ -1270,7 +1304,7 @@ def _process_starlark( ) _busybox.process_databinding( ctx, - out_databinding_info = out_databinding_info, + out_databinding_info = data_binding_layout_info, out_databinding_processed_resources = processed_resources, databinding_resources_dirname = resources_dirname, resource_files = resource_files, @@ -1375,7 +1409,10 @@ def _process_starlark( source_jar = r_java, ) + packages_to_r_txts_depset.setdefault(java_package, []).append(depset([out_aapt2_r_txt])) + resources_ctx[_R_JAVA] = java_info + resources_ctx[_DATA_BINDING_LAYOUT_INFO] = data_binding_layout_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. @@ -1406,6 +1443,10 @@ def _process_starlark( # 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. + packages_to_r_txts = dict() + for pkg, depsets in packages_to_r_txts_depset.items(): + packages_to_r_txts[pkg] = depset(transitive = depsets) + # 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: @@ -1452,6 +1493,7 @@ def _process_starlark( transitive = exports_transitive_r_txts, order = "preorder", ), + packages_to_r_txts = packages_to_r_txts, )) else: # Depsets are ordered below to match the order in the legacy native rules. @@ -1516,10 +1558,10 @@ def _process_starlark( transitive = transitive_r_txts + exports_transitive_r_txts, order = "preorder", ), + packages_to_r_txts = packages_to_r_txts, )) - # Do not collect resources and R.java for test apk - if android_test_migration: + if not propagate_resources: resources_ctx[_R_JAVA] = None resources_ctx[_PROVIDERS] = [] @@ -1574,7 +1616,7 @@ def _process( res_v3_dummy_r_txt = None, fix_resource_transitivity = False, fix_export_exporting = False, - android_test_migration = False, + propagate_resources = True, zip_tool = None): out_ctx = _process_starlark( ctx, @@ -1596,7 +1638,7 @@ def _process( enable_data_binding = enable_data_binding, fix_resource_transitivity = fix_resource_transitivity, neverlink = neverlink, - android_test_migration = android_test_migration, + propagate_resources = propagate_resources, android_jar = android_jar, aapt = aapt, android_kit = android_kit, diff --git a/rules/rules.bzl b/rules/rules.bzl index e849d72..315fd4f 100644 --- a/rules/rules.bzl +++ b/rules/rules.bzl @@ -12,50 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Skylark rules for building Android apps.""" +"""Starlark rules for building Android apps.""" load( "//rules/aar_import:rule.bzl", _aar_import = "aar_import", ) - -#load( -# ":apk_import.bzl", -# _apk_import = "apk_import", -#) - +load( + "//rules/android_application:android_application.bzl", + _android_application = "android_application", +) 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", @@ -77,53 +51,10 @@ load( RULES_ANDROID_VERSION = "0.1.0" aar_import = _aar_import - -"""https://docs.bazel.build/versions/master/be/android.html#android_apk_to_bundle""" - +android_application = _android_application 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 deleted file mode 100644 index a02375a..0000000 --- a/rules/toolchains/emulator/BUILD +++ /dev/null @@ -1,27 +0,0 @@ -# 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/utils.bzl b/rules/utils.bzl index 76a0fd2..d796371 100644 --- a/rules/utils.bzl +++ b/rules/utils.bzl @@ -195,6 +195,14 @@ def _only(collection): _error("Expected one element, has %s." % len(collection)) return _first(collection) +def _list_or_depset_to_list(list_or_depset): + if type(list_or_depset) == "list": + return list_or_depset + elif type(list_or_depset) == "depset": + return list_or_depset.to_list() + else: + return _error("Expected a list or a depset. Got %s" % type(list_or_depset)) + def _copy_file(ctx, src, dest): if src.is_directory or dest.is_directory: fail("Cannot use copy_file with directories") @@ -278,6 +286,12 @@ def _expand_make_vars(ctx, vals): res[k] = _expand_var(ctx.var, v) return res +def _dedupe_split_attr(attr): + if not attr: + return [] + arch = _first(sorted(attr.keys())) + return attr[arch] + def _get_runfiles(ctx, attrs): runfiles = ctx.runfiles() for attr in attrs: @@ -430,6 +444,7 @@ utils = struct( copy_dir = _copy_dir, expand_make_vars = _expand_make_vars, first = _first, + dedupe_split_attr = _dedupe_split_attr, get_runfiles = _get_runfiles, join_depsets = _join_depsets, only = _only, @@ -437,6 +452,7 @@ utils = struct( sanitize_string = _sanitize_string, sanitize_java_package = _sanitize_java_package, hex = _hex, + list_or_depset_to_list = _list_or_depset_to_list, ) log = struct( diff --git a/src/validations/aar_import_checks/BUILD b/src/validations/aar_import_checks/BUILD new file mode 100644 index 0000000..8f7bb2a --- /dev/null +++ b/src/validations/aar_import_checks/BUILD @@ -0,0 +1,27 @@ +# Description: +# Package for aar_import validation checks +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +genrule( + name = "gen_aar_import_checks", + outs = ["aar_import_checks"], + cmd = """ +cat > $@ <<"EOF" +#!/bin/bash +while [[ $$# -gt 0 ]] +do + case $$1 in + -output) + out="$$2" + ;; + esac + shift # past argument + shift # past value +done +touch $$out +EOF +""", + executable = True, +) diff --git a/toolchains/android/toolchain.bzl b/toolchains/android/toolchain.bzl index b356447..42cdf9d 100644 --- a/toolchains/android/toolchain.bzl +++ b/toolchains/android/toolchain.bzl @@ -19,61 +19,91 @@ _ATTRS = dict( allow_files = True, default = "@androidsdk//:aapt2_binary", ), + aar_import_checks = attr.label( + allow_single_file = True, + cfg = "exec", + default = "//src/validations/aar_import_checks", + executable = True, + ), aar_embedded_jars_extractor = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@bazel_tools//tools/android:aar_embedded_jars_extractor", executable = True, ), + aar_embedded_proguard_extractor = attr.label( + allow_files = True, + cfg = "exec", + default = "@bazel_tools//tools/android:aar_embedded_proguard_extractor", + executable = True, + ), aar_native_libs_zip_creator = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@bazel_tools//tools/android:aar_native_libs_zip_creator", executable = True, ), aar_resources_extractor = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@bazel_tools//tools/android:aar_resources_extractor", executable = True, ), adb = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@androidsdk//:platform-tools/adb", executable = True, ), add_g3itr_xslt = attr.label( - cfg = "host", + cfg = "exec", default = Label("//tools/android/xslt:add_g3itr.xslt"), allow_files = True, ), + android_archive_jar_optimization_inputs_validator = attr.label( + allow_files = True, + default = "@androidsdk//:fail", + cfg = "exec", + executable = True, + ), + android_archive_manifest_package_validator = attr.label( + allow_files = True, + default = "@androidsdk//:fail", + cfg = "exec", + executable = True, + ), + android_archive_packages_validator = attr.label( + allow_files = True, + default = "@androidsdk//:fail", + cfg = "exec", + executable = True, + ), android_kit = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@androidsdk//:fail", # TODO: "//src/tools/ak", needs Go executable = True, ), android_resources_busybox = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", 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", + cfg = "exec", default = "@androidsdk//:fail", executable = True, ), bundletool = attr.label( allow_files = True, - cfg = "host", - default = "@androidsdk//:fail", + cfg = "exec", + default = "//tools/android:bundletool_deploy.jar", executable = True, ), data_binding_annotation_processor = attr.label( - cfg = "host", + cfg = "exec", default = "@//tools/android:compiler_annotation_processor", # TODO: processor rules should be moved into rules_android ), data_binding_annotation_template = attr.label( @@ -81,25 +111,25 @@ _ATTRS = dict( allow_files = True, ), data_binding_exec = attr.label( - cfg = "host", + cfg = "exec", default = "@bazel_tools//tools/android:databinding_exec", executable = True, ), desugar_java8_extra_bootclasspath = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@bazel_tools//tools/android:desugar_java8_extra_bootclasspath", executable = True, ), idlclass = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@bazel_tools//tools/android:IdlClass", # _deploy.jar? executable = True, ), import_deps_checker = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", default = "@android_tools//:ImportDepsChecker_deploy.jar", executable = True, ), @@ -113,16 +143,22 @@ _ATTRS = dict( ), jdeps_tool = attr.label( allow_files = True, - cfg = "host", + cfg = "exec", # used in android_local_test default = "@androidsdk//:fail", # TODO: "//src/tools/jdeps", needs Go executable = True, ), proguard_allowlister = attr.label( - cfg = "host", + cfg = "exec", default = "@bazel_tools//tools/jdk:proguard_whitelister", executable = True, ), + proto_map_generator = attr.label( + cfg = "exec", + default = "@androidsdk//:fail", + allow_files = True, + executable = True, + ), res_v3_dummy_manifest = attr.label( allow_files = True, default = "//rules:res_v3_dummy_AndroidManifest.xml", @@ -139,18 +175,18 @@ _ATTRS = dict( default = "@androidsdk//:fail", ), unzip_tool = attr.label( - cfg = "host", + cfg = "exec", default = "//toolchains/android:unzip", executable = True, ), xsltproc_tool = attr.label( - cfg = "host", + cfg = "exec", default = Label("//tools/android/xslt:xslt"), allow_files = True, executable = True, ), zip_tool = attr.label( - cfg = "host", + cfg = "exec", default = "//toolchains/android:zip", executable = True, ), diff --git a/tools/android/BUILD b/tools/android/BUILD index 7c33f67..cb8148a 100644 --- a/tools/android/BUILD +++ b/tools/android/BUILD @@ -13,13 +13,20 @@ alias( ) genrule( - name = "gen_fail", - outs = ["fail.sh"], - cmd = "echo 'exit 1' > $@", - executable = 1, + name = "gen_fail", + outs = ["fail.sh"], + cmd = "echo 'exit 1' > $@", + executable = 1, ) sh_binary( - name = "fail", - srcs =[":fail.sh"], + name = "fail", + srcs = [":fail.sh"], +) + +java_binary( + name = "bundletool", + main_class = "com.android.tools.build.bundletool.BundleToolMain", + visibility = ["//visibility:public"], + runtime_deps = ["@rules_android_maven//:com_android_tools_build_bundletool"], ) diff --git a/tools/jdk/BUILD b/tools/jdk/BUILD index c688d1a..d83484b 100644 --- a/tools/jdk/BUILD +++ b/tools/jdk/BUILD @@ -9,3 +9,9 @@ default_java_toolchain( ], visibility = ["//visibility:public"], ) + +alias( + name = "current_java_runtime", + actual = "@bazel_tools//tools/jdk:current_java_runtime", + visibility = ["//visibility:public"], +) |