First step towards the migration of --desugar_java8_libs to starlark. This cl is NOOP. #FLAG_CHANGE PiperOrigin-RevId: 945839632 Change-Id: I1332095d7eae7a7c66000b3cc7fddcd1998d1c04
diff --git a/flags/BUILD b/flags/BUILD new file mode 100644 index 0000000..e6f363b --- /dev/null +++ b/flags/BUILD
@@ -0,0 +1,211 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "int_flag", "string_flag", "string_list_flag") +load("//flags:flags_wrapper.bzl", "flags_wrapper_macro") + +package( + default_applicable_licenses = ["//:license"], + default_visibility = ["//:__subpackages__"], +) + +licenses(["notice"]) + +filegroup( + name = "all_files", + srcs = glob(["**"]), + visibility = [ + "//:__subpackages__", + ], +) + +filegroup( + name = "empty", + srcs = [], +) + +bzl_library( + name = "bzl", + srcs = glob(["*.bzl"]), + visibility = ["//:__subpackages__"], + deps = [ + "//rules:visibility_bzl", + "@bazel_features//:features", + "@bazel_skylib//rules:common_settings", + ], +) + +bool_flag( + name = "desugar_for_android", + build_setting_default = True, + scope = "universal", + visibility = ["//visibility:public"], +) + +string_flag( + name = "runfiles_root_prefix", + build_setting_default = "google3/", + visibility = ["//visibility:public"], +) + +string_list_flag( + name = "android_platforms", + build_setting_default = [], + visibility = ["//visibility:public"], +) + +bool_flag( + name = "desugar_java8_libs", + build_setting_default = True, + scope = "universal", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "android_resource_shrinking", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "experimental_android_resource_path_shortening", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +string_flag( + name = "android_manifest_merger_order", + build_setting_default = "alphabetical", + scope = "universal", + values = [ + "alphabetical", + "alphabetical_by_configuration", + "dependency", + ], + visibility = ["//visibility:public"], +) + +bool_flag( + name = "experimental_android_compress_java_resources", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "android_fixed_resource_neverlinking", + build_setting_default = True, + visibility = ["//visibility:public"], +) + +bool_flag( + name = "internal_persistent_busybox_tools", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "internal_persistent_multiplex_busybox_tools", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "internal_persistent_android_dex_desugar", + build_setting_default = False, + visibility = ["//visibility:public"], +) + +bool_flag( + name = "internal_persistent_multiplex_android_dex_desugar", + build_setting_default = False, + visibility = ["//visibility:public"], +) + +label_flag( + name = "optimizing_dexer", + build_setting_default = ":empty", + visibility = ["//visibility:public"], +) + +string_flag( + name = "android_compiler", + build_setting_default = "null", + visibility = ["//visibility:public"], +) + +string_list_flag( + name = "dexopts_supported_in_dexmerger", + build_setting_default = [ + "--minimal-main-dex", + "--set-max-idx-number", + ], + scope = "universal", + visibility = ["//visibility:public"], +) + +string_list_flag( + name = "dexopts_supported_in_dexsharder", + build_setting_default = ["--minimal-main-dex"], + scope = "universal", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "experimental_android_resource_shrinking", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "experimental_android_resource_cycle_shrinking", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +string_flag( + name = "android_manifest_merger", + build_setting_default = "android", + scope = "universal", + values = [ + "legacy", + "android", + "force_android", + ], + visibility = ["//visibility:public"], +) + +bool_flag( + name = "experimental_android_library_exports_manifest_default", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +label_flag( + name = "legacy_main_dex_list_generator", + build_setting_default = ":empty", + visibility = ["//visibility:public"], +) + +bool_flag( + name = "experimental_get_android_java_resources_from_optimized_jar", + build_setting_default = False, + scope = "universal", + visibility = ["//visibility:public"], +) + +int_flag( + name = "incremental_dexing_after_proguard", + build_setting_default = 50, + scope = "universal", + visibility = ["//visibility:public"], +) + +flags_wrapper_macro( + name = "flags_wrapper", +)
diff --git a/flags/flags_wrapper.bzl b/flags/flags_wrapper.bzl new file mode 100644 index 0000000..f82e922 --- /dev/null +++ b/flags/flags_wrapper.bzl
@@ -0,0 +1,46 @@ +# Copyright 2026 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. +"""Custom flags wrapper.""" + +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") + +WrappedFlagsInfo = provider( + doc = "Provides all flags", + fields = dict( + flags = "Map of flag name to BuildSettingInfo", + ), +) + +def _flags_wrapper_impl(ctx): + return [WrappedFlagsInfo( + flags = { + t.label.name: t[BuildSettingInfo] + for t in ctx.attr.targets + if BuildSettingInfo in t + }, + )] + +flags_wrapper = rule( + implementation = _flags_wrapper_impl, + attrs = dict( + targets = attr.label_list(), + ), +) + +def flags_wrapper_macro(name = "flags_wrapper"): + flags_wrapper( + name = name, + targets = native.existing_rules().keys(), + visibility = ["//visibility:public"], + )
diff --git a/rules/android_binary/attrs.bzl b/rules/android_binary/attrs.bzl index b6cd67c..fffa5b7 100644 --- a/rules/android_binary/attrs.bzl +++ b/rules/android_binary/attrs.bzl
@@ -274,6 +274,7 @@ _attrs.DATA_CONTEXT, _attrs.ANDROID_TOOLCHAIN_ATTRS, _attrs.AUTOMATIC_EXEC_GROUPS_ENABLED, + _attrs.FLAGS_ATTRS, ), # TODO(b/167599192): don't override manifest attr to remove .xml file restriction. manifest = attr.label(
diff --git a/rules/android_binary/impl.bzl b/rules/android_binary/impl.bzl index 5461f17..2b99ff1 100644 --- a/rules/android_binary/impl.bzl +++ b/rules/android_binary/impl.bzl
@@ -46,7 +46,7 @@ "utils", ) load("//rules:visibility.bzl", "PROJECT_VISIBILITY") -load("//rules/flags:flags.bzl", _flags = "flags") +load("//rules/flags:flags.bzl", "read_possibly_native_flag", _flags = "flags") load("@rules_java//java/common:java_common.bzl", "java_common") load("@rules_java//java/common:java_info.bzl", "JavaInfo") load("@rules_java//java/common:java_plugin_info.bzl", "JavaPluginInfo") @@ -292,14 +292,14 @@ if proguard_output_map: # Proguard map from preprocessing will be merged with Proguard map for desugared # library. - if should_optimize_dex and ctx.fragments.android.desugar_java8_libs: + if should_optimize_dex and read_possibly_native_flag(ctx, "desugar_java8_libs"): postprocessing_output_map = _dex.get_dx_artifact(ctx, "_proguard_output_for_desugared_library.map") final_proguard_output_map = ctx.actions.declare_file(ctx.label.name + "_proguard.map") elif should_optimize_dex: # No desugared library, Proguard map from postprocessing is the final Proguard map. postprocessing_output_map = ctx.actions.declare_file(ctx.label.name + "_proguard.map") final_proguard_output_map = postprocessing_output_map - elif ctx.fragments.android.desugar_java8_libs: + elif read_possibly_native_flag(ctx, "desugar_java8_libs"): # No postprocessing, Proguard map from merging with the desugared library map is the # final Proguard map. postprocessing_output_map = proguard_output_map @@ -357,7 +357,7 @@ toolchain_type = ANDROID_TOOLCHAIN_TYPE, ) - if ctx.fragments.android.desugar_java8_libs and classes_dex_zip.extension == "zip": + if read_possibly_native_flag(ctx, "desugar_java8_libs") and classes_dex_zip.extension == "zip": final_classes_dex_zip = _dex.get_dx_artifact(ctx, "final_classes_dex.zip") java8_legacy_dex, java8_legacy_dex_map = _dex.get_java8_legacy_dex_and_map(
diff --git a/rules/android_binary/r8.bzl b/rules/android_binary/r8.bzl index 651dd23..4c63947 100644 --- a/rules/android_binary/r8.bzl +++ b/rules/android_binary/r8.bzl
@@ -34,7 +34,7 @@ "utils", ) load("//rules:visibility.bzl", "PROJECT_VISIBILITY") -load("//rules/flags:flags.bzl", _flags = "flags") +load("//rules/flags:flags.bzl", "read_possibly_native_flag", _flags = "flags") visibility(PROJECT_VISIBILITY) @@ -131,7 +131,7 @@ args.add("--build-metadata-output", build_metadata_output) r8_inputs = [android_jar, deploy_jar] + proguard_specs - if ctx.fragments.android.desugar_java8_libs and desugared_lib_config: + if read_possibly_native_flag(ctx, "desugar_java8_libs") and desugared_lib_config: args.add("--desugared-lib", desugared_lib_config) r8_inputs.append(desugared_lib_config) @@ -151,7 +151,7 @@ # backport references, but does NOT include the j$.* implementation classes # in its output. Append the prebuilt desugared library DEX so the j$.* # classes are available at runtime. - if ctx.fragments.android.desugar_java8_libs and desugared_lib_config: + if read_possibly_native_flag(ctx, "desugar_java8_libs") and desugared_lib_config: final_classes_dex_zip = ctx.actions.declare_file(ctx.label.name + "_final_dexes.zip") java8_legacy_dex = utils.only( get_android_toolchain(ctx).java8_legacy_dex.files.to_list(),
diff --git a/rules/attrs.bzl b/rules/attrs.bzl index fbe58fe..d80a0a0 100644 --- a/rules/attrs.bzl +++ b/rules/attrs.bzl
@@ -13,6 +13,7 @@ # limitations under the License. """Common attributes for Android rules.""" +load("//flags:flags_wrapper.bzl", "WrappedFlagsInfo") load("//providers:providers.bzl", "ApkInfo") load("//rules:android_split_transition.bzl", "android_transition") load("//rules:visibility.bzl", "PROJECT_VISIBILITY") @@ -312,6 +313,10 @@ _desugared_java8_legacy_apis = attr.label( default = Label("//tools/android:desugared_java8_legacy_apis"), ), + _wrapped_flags = attr.label( + default = Label("//flags:flags_wrapper"), + providers = [WrappedFlagsInfo], + ), _dexbuilder = attr.label( cfg = "exec", default = Label("//tools/android:dexbuilder"), @@ -508,6 +513,13 @@ _use_auto_exec_groups = attr.bool(default = True), ) +_FLAGS_ATTRS = dict( + _wrapped_flags = attr.label( + default = Label("//flags:flags_wrapper"), + providers = [WrappedFlagsInfo], + ), +) + attrs = struct( ANDROID_SDK = _ANDROID_SDK, compilation_attributes = _compilation_attributes, @@ -518,4 +530,5 @@ add = _add, replace = _replace, AUTOMATIC_EXEC_GROUPS_ENABLED = _AUTOMATIC_EXEC_GROUPS_ENABLED, + FLAGS_ATTRS = _FLAGS_ATTRS, )
diff --git a/rules/desugar.bzl b/rules/desugar.bzl index 74348f8..d75133f 100644 --- a/rules/desugar.bzl +++ b/rules/desugar.bzl
@@ -14,6 +14,7 @@ """Bazel Desugar Commands.""" load("//rules:visibility.bzl", "PROJECT_VISIBILITY") +load("//rules/flags:flags.bzl", "read_possibly_native_flag") visibility(PROJECT_VISIBILITY) @@ -56,7 +57,7 @@ input_file_deps = [input] if library_desugaring: args.add("--emit_dependency_metadata_as_needed") - if ctx.fragments.android.desugar_java8_libs: + if read_possibly_native_flag(ctx, "desugar_java8_libs"): args.add("--desugar_supported_core_libs") # Unconditionally add --desugared_lib_config. This matches the behavior of tools/android/d8_desugar.sh.
diff --git a/rules/dex_desugar_aspect.bzl b/rules/dex_desugar_aspect.bzl index 32a73f4..2d4850b 100644 --- a/rules/dex_desugar_aspect.bzl +++ b/rules/dex_desugar_aspect.bzl
@@ -296,6 +296,7 @@ }, _attrs.ANDROID_SDK, _min_sdk_version.attrs, + _attrs.FLAGS_ATTRS, ), fragments = ["android"], toolchains = [
diff --git a/rules/flags/BUILD b/rules/flags/BUILD index ed32594..9c305a4 100644 --- a/rules/flags/BUILD +++ b/rules/flags/BUILD
@@ -1,7 +1,7 @@ # Flags for Android rules and mobile-install load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "int_flag", "string_flag", "string_list_flag") +load("@bazel_skylib//rules:common_settings.bzl", "string_flag") load("//rules/flags:additional_flags.bzl", "additional_flags") load("//rules/flags:configurations.bzl", "configurations") load("//rules/flags:flag_defs.bzl", "define_flags") @@ -28,183 +28,17 @@ visibility = ["//:__subpackages__"], deps = [ "//rules:visibility_bzl", + "@bazel_features//:features", "@bazel_skylib//rules:common_settings", ], ) -bool_flag( - name = "desugar_for_android", - build_setting_default = True, - scope = "universal", - visibility = ["//visibility:public"], -) - string_flag( name = "runfiles_root_prefix", build_setting_default = "rules_android/", visibility = ["//visibility:public"], ) -string_list_flag( - name = "android_platforms", - build_setting_default = [], - visibility = ["//visibility:public"], -) - -bool_flag( - name = "desugar_java8_libs", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "android_resource_shrinking", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "experimental_android_resource_path_shortening", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -string_flag( - name = "android_manifest_merger_order", - build_setting_default = "alphabetical", - scope = "universal", - values = [ - "alphabetical", - "alphabetical_by_configuration", - "dependency", - ], - visibility = ["//visibility:public"], -) - -bool_flag( - name = "experimental_android_compress_java_resources", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "android_fixed_resource_neverlinking", - build_setting_default = True, - visibility = ["//visibility:public"], -) - -bool_flag( - name = "internal_persistent_busybox_tools", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "internal_persistent_multiplex_busybox_tools", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "internal_persistent_android_dex_desugar", - build_setting_default = False, - visibility = ["//visibility:public"], -) - -bool_flag( - name = "internal_persistent_multiplex_android_dex_desugar", - build_setting_default = False, - visibility = ["//visibility:public"], -) - -label_flag( - name = "optimizing_dexer", - build_setting_default = ":empty", - visibility = ["//visibility:public"], -) - -string_flag( - name = "android_compiler", - build_setting_default = "null", - visibility = ["//visibility:public"], -) - -string_list_flag( - name = "dexopts_supported_in_dexmerger", - build_setting_default = [ - "--minimal-main-dex", - "--set-max-idx-number", - ], - scope = "universal", - visibility = ["//visibility:public"], -) - -string_list_flag( - name = "dexopts_supported_in_dexsharder", - build_setting_default = ["--minimal-main-dex"], - scope = "universal", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "experimental_android_resource_shrinking", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "experimental_android_resource_cycle_shrinking", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -string_flag( - name = "android_manifest_merger", - build_setting_default = "android", - scope = "universal", - values = [ - "legacy", - "android", - "force_android", - ], - visibility = ["//visibility:public"], -) - -bool_flag( - name = "experimental_android_library_exports_manifest_default", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -label_flag( - name = "legacy_main_dex_list_generator", - build_setting_default = ":empty", - visibility = ["//visibility:public"], -) - -bool_flag( - name = "experimental_get_android_java_resources_from_optimized_jar", - build_setting_default = False, - scope = "universal", - visibility = ["//visibility:public"], -) - -int_flag( - name = "incremental_dexing_after_proguard", - build_setting_default = 50, - scope = "universal", - visibility = ["//visibility:public"], -) - configurations() define_flags()
diff --git a/rules/flags/flags.bzl b/rules/flags/flags.bzl index 6a8d4f7..7af21b9 100644 --- a/rules/flags/flags.bzl +++ b/rules/flags/flags.bzl
@@ -13,6 +13,8 @@ # limitations under the License. """Bazel Flags.""" +load("@bazel_features//private:util.bzl", "lt") # buildifier: disable=bzl-visibility +load("//flags:flags_wrapper.bzl", "WrappedFlagsInfo") load("//rules:utils.bzl", "utils") load("//rules:visibility.bzl", "PROJECT_VISIBILITY") @@ -187,6 +189,51 @@ return flags[FlagsInfo] return flags[0][FlagsInfo] +_POSSIBLY_NATIVE_FLAGS = { + "desugar_java8_libs": (lambda ctx: ctx.fragments.android.desugar_java8_libs, "starlark"), +} + +def read_possibly_native_flag(ctx, flag_name): + """ + Canonical API for reading a Android build flag. + + Flags might be defined in Starlark or native-Bazel. This function reads flags + from the correct source based on supporting Bazel version and --incompatible* + flags that disable native references. + + Args: + ctx: Rule's configuration context. + flag_name: Name of the flag to read, without preceding "--". + + Returns: + The flag's value. + """ + + # Bazel 9.1+ can disable these fragments with --incompatible_remove_ctx_android_fragment. + # Disabling them means bazel expects Android to read Starlark flags. + use_native_def = hasattr(ctx.fragments, "android") + + # Developer override to force the Starlark definition for testing. + # This would allow us to migrate flags gradually from native to Starlark with flag aliases. + if _POSSIBLY_NATIVE_FLAGS[flag_name][1] == "starlark": + use_native_def = False + + if lt("9.1.0"): + use_native_def = True + + if use_native_def: + return _POSSIBLY_NATIVE_FLAGS[flag_name][0](ctx) + else: + # First check the new wrapped_flags attribute + if hasattr(ctx.attr, "_wrapped_flags") and ctx.attr._wrapped_flags: + wrapped_flags = ctx.attr._wrapped_flags[WrappedFlagsInfo].flags + if flag_name in wrapped_flags: + return wrapped_flags[flag_name].value + elif hasattr(ctx.fragments, "android"): + return _POSSIBLY_NATIVE_FLAGS[flag_name][0](ctx) + + fail("Unable to read flag value for " + flag_name) + flags = struct( DEFINE_bool = bool_flag, DEFINE_bool_group = bool_flag_group,