diff options
author | Romain Jobredeaux <jobredeaux@google.com> | 2023-04-13 20:53:06 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2023-04-13 20:53:06 +0000 |
commit | 85aa6aa91a11bccba5da61f942595dfa9101b650 (patch) | |
tree | e5c7021a1959668d38705068a5565a1cee602097 /rules | |
parent | f38ce298db994d9cd088c67c16dff6005dc5e1d8 (diff) | |
parent | 9afe61a6a24b5f73561ae8e29e3068c11967809e (diff) | |
download | bazel-85aa6aa91a11bccba5da61f942595dfa9101b650.tar.gz |
Merge "Support sdk_version for java/android/kotlin targets."
Diffstat (limited to 'rules')
-rw-r--r-- | rules/android/aar_import.bzl | 75 | ||||
-rw-r--r-- | rules/android/android_binary.bzl | 51 | ||||
-rw-r--r-- | rules/android/android_library.bzl | 100 | ||||
-rw-r--r-- | rules/android/rules.bzl | 2 | ||||
-rw-r--r-- | rules/common/sdk_version.bzl | 45 | ||||
-rw-r--r-- | rules/common/sdk_version_test.bzl | 4 | ||||
-rw-r--r-- | rules/java/BUILD | 36 | ||||
-rw-r--r-- | rules/java/host_for_device.bzl | 6 | ||||
-rw-r--r-- | rules/java/host_for_device_test.bzl | 8 | ||||
-rw-r--r-- | rules/java/import.bzl | 67 | ||||
-rw-r--r-- | rules/java/java_aidl_library.bzl | 22 | ||||
-rw-r--r-- | rules/java/library.bzl | 61 | ||||
-rw-r--r-- | rules/java/proto.bzl | 4 | ||||
-rw-r--r-- | rules/java/rules.bzl | 2 | ||||
-rw-r--r-- | rules/java/sdk/BUILD.bazel | 86 | ||||
-rw-r--r-- | rules/java/sdk/config_setting_names.bzl | 35 | ||||
-rw-r--r-- | rules/java/sdk_transition.bzl | 19 | ||||
-rw-r--r-- | rules/java/sdk_transition_test.bzl | 8 | ||||
-rw-r--r-- | rules/java/versions.bzl | 15 | ||||
-rw-r--r-- | rules/java/wrapper_test.sh | 38 | ||||
-rw-r--r-- | rules/kotlin/kt_jvm_library.bzl | 44 |
21 files changed, 670 insertions, 58 deletions
diff --git a/rules/android/aar_import.bzl b/rules/android/aar_import.bzl new file mode 100644 index 00000000..e93a821f --- /dev/null +++ b/rules/android/aar_import.bzl @@ -0,0 +1,75 @@ +# Copyright (C) 2023 The Android Open Source Project +# +# 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. + +"""Macro wrapping the aar_import for bp2build. """ + +load("@rules_android//rules:rules.bzl", _aar_import = "aar_import") +load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs") + +# TODO(b/277801336): document these attributes. +def aar_import( + name = "", + aar = [], + sdk_version = None, + deps = [], + tags = [], + target_compatible_with = [], + visibility = None, + **kwargs): + lib_name = name + "_private" + _aar_import( + name = lib_name, + aar = aar, + deps = deps, + tags = tags + ["manual"], + target_compatible_with = target_compatible_with, + visibility = ["//visibility:private"], + **kwargs + ) + + aar_import_sdk_transition( + name = name, + sdk_version = sdk_version, + java_version = None, + exports = lib_name, + tags = tags, + target_compatible_with = target_compatible_with, + visibility = visibility, + ) + +# The list of providers to forward was determined using cquery on one +# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at +# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit +# test ensures that the wrapper's providers and the wrapped rule's do +# match. +def _aar_import_sdk_transition_impl(ctx): + return [ + ctx.attr.exports[0][AndroidLibraryResourceClassJarProvider], + ctx.attr.exports[0][JavaInfo], + ctx.attr.exports[0][AndroidNativeLibsInfo], + ctx.attr.exports[0][ProguardSpecProvider], + ctx.attr.exports[0][AndroidIdeInfo], + ctx.attr.exports[0][DefaultInfo], + ] + +aar_import_sdk_transition = rule( + implementation = _aar_import_sdk_transition_impl, + attrs = sdk_transition_attrs, + provides = [ + AndroidIdeInfo, + AndroidLibraryResourceClassJarProvider, + AndroidNativeLibsInfo, + JavaInfo, + ], +) diff --git a/rules/android/android_binary.bzl b/rules/android/android_binary.bzl index 1b30efd7..64465a15 100644 --- a/rules/android/android_binary.bzl +++ b/rules/android/android_binary.bzl @@ -20,7 +20,9 @@ load( ) load("android_app_certificate.bzl", "android_app_certificate_with_default_cert") load("android_app_keystore.bzl", "android_app_keystore") +load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs") +# TODO(b/277801336): document these attributes. def _android_binary_helper(**attrs): """ Duplicates the logic in top-level android_binary macro in rules_android/rules/android_binary.bzl but uses @@ -51,6 +53,11 @@ def android_binary( name, certificate = None, certificate_name = None, + sdk_version = None, + java_version = None, + tags = [], + target_compatible_with = [], + visibility = None, **kwargs): """ android_binary macro wrapper that handles custom attrs needed in AOSP Bazel macro to find and create a keystore to use for debug_signing_keys @@ -91,8 +98,50 @@ def android_binary( debug_signing_keys.append(app_keystore_name) + bin_name = name + "_private" _android_binary_helper( - name = name, + name = bin_name, debug_signing_keys = debug_signing_keys, + target_compatible_with = target_compatible_with, + tags = tags + ["manual"], + visibility = ["//visibility:private"], **kwargs ) + + android_binary_sdk_transition( + name = name, + sdk_version = sdk_version, + java_version = java_version, + exports = bin_name, + tags = tags, + target_compatible_with = target_compatible_with, + visibility = visibility, + ) + +# The list of providers to forward was determined using cquery on one +# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at +# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit +# test ensures that the wrapper's providers and the wrapped rule's do +# match. +def _android_binary_sdk_transition_impl(ctx): + return struct( + android = ctx.attr.exports[0].android, + JavaGenJarsProvider = ctx.attr.exports[0][JavaInfo].annotation_processing, + providers = [ + ctx.attr.exports[0][AndroidIdlInfo], + ctx.attr.exports[0][InstrumentedFilesInfo], + ctx.attr.exports[0][DataBindingV2Info], + ctx.attr.exports[0][JavaInfo], + ctx.attr.exports[0][AndroidIdeInfo], + ctx.attr.exports[0][ApkInfo], + ctx.attr.exports[0][AndroidPreDexJarInfo], + ctx.attr.exports[0][AndroidFeatureFlagSet], + ctx.attr.exports[0][OutputGroupInfo], + ctx.attr.exports[0][DefaultInfo], + ], + ) + +android_binary_sdk_transition = rule( + implementation = _android_binary_sdk_transition_impl, + attrs = sdk_transition_attrs, +) diff --git a/rules/android/android_library.bzl b/rules/android/android_library.bzl index 99f4f0f3..514cc4df 100644 --- a/rules/android/android_library.bzl +++ b/rules/android/android_library.bzl @@ -1,14 +1,110 @@ +# Copyright (C) 2023 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + """android_library rule.""" +load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs") load( "//build/bazel/rules/android/android_library_aosp_internal:rule.bzl", "android_library_aosp_internal_macro", ) +load("@rules_android//rules:providers.bzl", "StarlarkAndroidResourcesInfo") -def android_library(**attrs): +# TODO(b/277801336): document these attributes. +def android_library( + name, + sdk_version = None, + java_version = None, + tags = [], + target_compatible_with = [], + visibility = None, + **attrs): """ android_library macro wrapper that handles custom attrs needed in AOSP Args: + name: the wrapper rule name. + sdk_version: string representing which sdk_version to build against. See + //build/bazel/rules/common/sdk_version.bzl for formatting and semantics. + java_version: string representing which version of java the java code in this rule should be + built with. + tags, target_compatible_with and visibility have Bazel's traditional semantics. **attrs: Rule attributes """ - android_library_aosp_internal_macro(**attrs) + lib_name = name + "_private" + android_library_aosp_internal_macro( + name = lib_name, + tags = tags + ["manual"], + target_compatible_with = target_compatible_with, + visibility = ["//visibility:private"], + **attrs + ) + + android_library_sdk_transition( + aar = name + ".aar", + name = name, + sdk_version = sdk_version, + java_version = java_version, + exports = lib_name, + tags = tags, + target_compatible_with = target_compatible_with, + visibility = visibility, + ) + +# The list of providers to forward was determined using cquery on one +# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at +# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit +# test ensures that the wrapper's providers and the wrapped rule's do +# match. +def _android_library_sdk_transition_impl(ctx): + ctx.actions.symlink( + output = ctx.outputs.aar, + target_file = ctx.attr.exports[0][AndroidIdeInfo].aar, + ) + + providers = [] + if AndroidLibraryAarInfo in ctx.attr.exports[0]: + providers.append(ctx.attr.exports[0][AndroidLibraryAarInfo]) + return struct( + android = ctx.attr.exports[0].android, + java = ctx.attr.exports[0].java, + providers = providers + [ + ctx.attr.exports[0][StarlarkAndroidResourcesInfo], + ctx.attr.exports[0][AndroidLibraryResourceClassJarProvider], + ctx.attr.exports[0][AndroidIdlInfo], + ctx.attr.exports[0][DataBindingV2Info], + ctx.attr.exports[0][JavaInfo], + ctx.attr.exports[0][ProguardSpecProvider], + ctx.attr.exports[0][AndroidProguardInfo], + ctx.attr.exports[0][AndroidNativeLibsInfo], + ctx.attr.exports[0][AndroidCcLinkParamsInfo], + ctx.attr.exports[0][AndroidIdeInfo], + ctx.attr.exports[0][InstrumentedFilesInfo], + ctx.attr.exports[0][Actions], + ctx.attr.exports[0][OutputGroupInfo], + ctx.attr.exports[0][DefaultInfo], + ], + ) + +android_library_sdk_transition = rule( + implementation = _android_library_sdk_transition_impl, + attrs = sdk_transition_attrs | {"aar": attr.output()}, + provides = [ + AndroidCcLinkParamsInfo, + AndroidIdeInfo, + AndroidIdlInfo, + AndroidLibraryResourceClassJarProvider, + AndroidNativeLibsInfo, + JavaInfo, + ], +) diff --git a/rules/android/rules.bzl b/rules/android/rules.bzl index 23c37074..43b794d5 100644 --- a/rules/android/rules.bzl +++ b/rules/android/rules.bzl @@ -15,7 +15,7 @@ """Starlark rules for building Android apps.""" load( - "@rules_android//rules:rules.bzl", + ":aar_import.bzl", _aar_import = "aar_import", ) load( diff --git a/rules/common/sdk_version.bzl b/rules/common/sdk_version.bzl index 7b853762..33f2f61c 100644 --- a/rules/common/sdk_version.bzl +++ b/rules/common/sdk_version.bzl @@ -17,18 +17,25 @@ load("//build/bazel/rules/common:api.bzl", "api") # Only scopes that are available in prebuilts (and "none") are listed # here for now, but the list should eventually match Soong's SdkKind # enum. -ALL_KINDS = [ - "public", - "system", - "test", - "system_server", - "module", - "core", - "none", +_KIND_PUBLIC = "public" +_KIND_SYSTEM = "system" +_KIND_TEST = "test" +_KIND_SYSTEM_SERVER = "system_server" +_KIND_MODULE = "module" +_KIND_CORE = "core" +_KIND_NONE = "none" +_ALL_KINDS = [ + _KIND_PUBLIC, + _KIND_SYSTEM, + _KIND_TEST, + _KIND_SYSTEM_SERVER, + _KIND_MODULE, + _KIND_CORE, + _KIND_NONE, ] # Starlark implementation of SdkSpecFrom at https://cs.android.com/android/platform/build/soong/+/master:android/sdk_version.go;l=248-299;drc=69f4218c4feaeca953237cd9e76a9a8cc423d3e3. -def sdk_spec_from(sdk_version): +def _sdk_spec_from(sdk_version): """Parses an sdk_version string into kind and api_level. Args: @@ -49,17 +56,29 @@ def sdk_spec_from(sdk_version): if sdk_version == "core_platform": fail("Only prebuilt SDK versions are available, sdk_version core_platform is not yet supported.") if sdk_version == "none": - return struct(kind = "none", api_level = api.NONE_API_LEVEL) + return struct(kind = _KIND_NONE, api_level = api.NONE_API_LEVEL) if type(sdk_version) != type(""): fail("sdk_version must be a string") sep_index = sdk_version.rfind("_") api_level_string = sdk_version if sep_index < 0 else sdk_version[sep_index + 1:] api_level = api.parse_api_level_from_version(api_level_string) - kind = "public" if sep_index == -1 else sdk_version[:sep_index] - if kind not in ALL_KINDS: + kind = _KIND_PUBLIC if sep_index == -1 else sdk_version[:sep_index] + if kind not in _ALL_KINDS: fail("kind %s parsed from sdk_version %s must be one of %s" % ( kind, sdk_version, - ",".join(ALL_KINDS), + ",".join(_ALL_KINDS), )) return struct(kind = kind, api_level = api_level) + +sdk_version = struct( + KIND_PUBLIC = _KIND_PUBLIC, + KIND_SYSTEM = _KIND_SYSTEM, + KIND_TEST = _KIND_TEST, + KIND_SYSTEM_SERVER = _KIND_SYSTEM_SERVER, + KIND_MODULE = _KIND_MODULE, + KIND_CORE = _KIND_CORE, + KIND_NONE = _KIND_NONE, + ALL_KINDS = _ALL_KINDS, + sdk_spec_from = _sdk_spec_from, +) diff --git a/rules/common/sdk_version_test.bzl b/rules/common/sdk_version_test.bzl index f751fe2a..b22c63d4 100644 --- a/rules/common/sdk_version_test.bzl +++ b/rules/common/sdk_version_test.bzl @@ -13,7 +13,7 @@ # limitations under the License. load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") -load("//build/bazel/rules/common:sdk_version.bzl", "sdk_spec_from") +load("//build/bazel/rules/common:sdk_version.bzl", "sdk_version") load("//build/bazel/rules/common:api.bzl", "api") # Warning: this is a *lot* of boilerplate to test just one function. @@ -22,7 +22,7 @@ load("//build/bazel/rules/common:api.bzl", "api") SdkSpec = provider() def _sdk_spec_from_tester_impl(ctx): - sdk_spec = sdk_spec_from(ctx.attr.sdk_version) + sdk_spec = sdk_version.sdk_spec_from(ctx.attr.sdk_version) return [SdkSpec(kind = sdk_spec.kind, api_level = sdk_spec.api_level)] sdk_spec_from_tester = rule( diff --git a/rules/java/BUILD b/rules/java/BUILD index edfc9f19..763713c9 100644 --- a/rules/java/BUILD +++ b/rules/java/BUILD @@ -23,6 +23,8 @@ load(":versions.bzl", "java_versions") load(":sdk_transition_test.bzl", "sdk_transition_test_suite") load(":host_for_device_test.bzl", "host_for_device_test_suite") load("@bazel_skylib//rules:common_settings.bzl", "string_setting") +load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "DEFAULT_JAVACOPTS", "default_java_toolchain") +load("@soong_injection//java_toolchain:constants.bzl", "constants") package( default_visibility = ["//visibility:public"], @@ -50,12 +52,12 @@ string_setting( [ config_setting( - name = java_versions.VERSION_TO_CONFIG_SETTING[java_version], + name = setting, flag_values = { "//build/bazel/rules/java:version": str(java_version), }, ) - for java_version in java_versions.VERSION_TO_CONFIG_SETTING.keys() + for java_version, setting in java_versions.VERSION_TO_CONFIG_SETTING.items() ] # There is no need for both host and device java version build settings in a @@ -75,10 +77,36 @@ string_setting( [ config_setting( - name = "host_" + java_versions.VERSION_TO_CONFIG_SETTING[java_version], + name = "host_" + setting, flag_values = { "//build/bazel/rules/java:host_version": str(java_version), }, ) - for java_version in java_versions.VERSION_TO_CONFIG_SETTING.keys() + for java_version, setting in java_versions.VERSION_TO_CONFIG_SETTING.items() ] + +java_version_select_dict = { + "host_" + setting: str(version) + for version, setting in java_versions.VERSION_TO_CONFIG_SETTING.items() +} | { + "//conditions:default": str(java_versions.get_version()), +} + +default_java_toolchain( + name = "jdk17_host_toolchain_java", + # TODO(b/218720643): Support switching between multiple JDKs. + java_runtime = "//prebuilts/jdk/jdk17:jdk17_runtime", + misc = DEFAULT_JAVACOPTS + constants.CommonJdkFlags, + source_version = select(java_version_select_dict), + target_version = select(java_version_select_dict), + toolchain_definition = False, +) + +toolchain( + name = "jdk17_host_toolchain_java_definition", + exec_compatible_with = ["//build/bazel/platforms/os:linux"], + target_compatible_with = ["//build/bazel/platforms/os:linux"], + target_settings = [], + toolchain = ":jdk17_host_toolchain_java", + toolchain_type = "@bazel_tools//tools/jdk:toolchain_type", +) diff --git a/rules/java/host_for_device.bzl b/rules/java/host_for_device.bzl index a5fea20c..9d7990a1 100644 --- a/rules/java/host_for_device.bzl +++ b/rules/java/host_for_device.bzl @@ -20,7 +20,7 @@ visibility([ ]) def _host_for_device_impl(ctx): - return [java_common.merge([d[JavaInfo] for d in ctx.attr.deps])] + return [java_common.merge([d[JavaInfo] for d in ctx.attr.exports])] java_host_for_device = rule( doc = """Rule to provide java libraries built with a host classpath in a device configuration. @@ -28,7 +28,9 @@ This is rarely necessary and restricted to a few allowed projects. """, implementation = _host_for_device_impl, attrs = { - "deps": attr.label_list( + # This attribute must have a specific name to let the DexArchiveAspect propagate + # through it. + "exports": attr.label_list( cfg = "exec", providers = [JavaInfo], doc = "List of targets whose contents will be visible to targets that depend on this target.", diff --git a/rules/java/host_for_device_test.bzl b/rules/java/host_for_device_test.bzl index cfc8812f..5585bad9 100644 --- a/rules/java/host_for_device_test.bzl +++ b/rules/java/host_for_device_test.bzl @@ -26,8 +26,8 @@ Platform = provider( ) def _host_for_device_tester_aspect_impl(target, ctx): - if ctx.rule.attr.deps and len(ctx.rule.attr.deps) > 0 and Platform in ctx.rule.attr.deps[0]: - return ctx.rule.attr.deps[0][Platform] + if ctx.rule.attr.exports and len(ctx.rule.attr.exports) > 0 and Platform in ctx.rule.attr.exports[0]: + return ctx.rule.attr.exports[0][Platform] return Platform( platform = ctx.fragments.platform.platform, host_platform = ctx.fragments.platform.host_platform, @@ -35,7 +35,7 @@ def _host_for_device_tester_aspect_impl(target, ctx): host_for_device_tester_aspect = aspect( implementation = _host_for_device_tester_aspect_impl, - attr_aspects = ["deps"], + attr_aspects = ["exports"], fragments = ["platform"], provides = [Platform], ) @@ -57,7 +57,7 @@ host_for_device_dep_runs_in_exec_config_test = analysistest.make( def test_host_for_device(name): java_host_for_device( name = name + "_parent", - deps = [name + "_child"], + exports = [name + "_child"], tags = ["manual"], ) java_import( diff --git a/rules/java/import.bzl b/rules/java/import.bzl new file mode 100644 index 00000000..6770c5f0 --- /dev/null +++ b/rules/java/import.bzl @@ -0,0 +1,67 @@ +# Copyright (C) 2023 The Android Open Source Project +# +# 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. + +"""Macro wrapping the java_import for bp2build. """ + +load("@rules_java//java:defs.bzl", _java_import = "java_import") +load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs") + +# TODO(b/277801336): document these attributes. +def java_import( + name = "", + jars = [], + deps = [], + tags = [], + target_compatible_with = [], + visibility = None, + **kwargs): + lib_name = name + "_private" + _java_import( + name = lib_name, + jars = jars, + deps = deps, + tags = tags + ["manual"], + target_compatible_with = target_compatible_with, + visibility = ["//visibility:private"], + **kwargs + ) + + java_import_sdk_transition( + name = name, + sdk_version = "none", + java_version = None, + exports = lib_name, + tags = tags, + target_compatible_with = target_compatible_with, + visibility = visibility, + ) + +# The list of providers to forward was determined using cquery on one +# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at +# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit +# test ensures that the wrapper's providers and the wrapped rule's do +# match. +def _java_import_sdk_transition_impl(ctx): + return [ + ctx.attr.exports[0][JavaInfo], + ctx.attr.exports[0][ProguardSpecProvider], + ctx.attr.exports[0][OutputGroupInfo], + ctx.attr.exports[0][DefaultInfo], + ] + +java_import_sdk_transition = rule( + implementation = _java_import_sdk_transition_impl, + attrs = sdk_transition_attrs, + provides = [JavaInfo], +) diff --git a/rules/java/java_aidl_library.bzl b/rules/java/java_aidl_library.bzl index d2dbfac0..94fd8c5c 100644 --- a/rules/java/java_aidl_library.bzl +++ b/rules/java/java_aidl_library.bzl @@ -13,6 +13,7 @@ # limitations under the License. load("//build/bazel/rules/aidl:aidl_library.bzl", "AidlGenInfo", "aidl_file_utils") +load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition") JavaAidlAspectInfo = provider("JavaAidlAspectInfo", fields = ["jars"]) @@ -20,7 +21,7 @@ def _java_aidl_gen_aspect_impl(target, ctx): aidl_gen_java_files = aidl_file_utils.generate_aidl_bindings(ctx, "java", target[AidlGenInfo]) java_deps = [ d[JavaInfo] - for d in ctx.rule.attr.deps + ctx.attr._sdk_dependency + for d in ctx.rule.attr.deps ] out_jar = ctx.actions.declare_file(target.label.name + "-aidl-gen.jar") java_info = java_common.compile( @@ -48,15 +49,6 @@ _java_aidl_gen_aspect = aspect( cfg = "exec", default = Label("//prebuilts/build-tools:linux-x86/bin/aidl"), ), - "_sdk_dependency": attr.label_list( - default = [ - # TODO(b/215230098) remove forced dependency on current public android.jar - "//prebuilts/sdk:system_current_android_sdk_java_import", - # TODO(b/229251008) remove hard-coded dependency on framework-connectivity - "//prebuilts/sdk:current_module_lib_framework_connectivity", - ], - providers = [JavaInfo], - ), }, toolchains = ["@bazel_tools//tools/jdk:toolchain_type"], fragments = ["java"], @@ -80,9 +72,19 @@ def _java_aidl_library_rule_impl(ctx): java_aidl_library = rule( implementation = _java_aidl_library_rule_impl, attrs = { + # This attribute's name lets the DexArchiveAspect propagate + # through it. It should be changed carefully. "deps": attr.label_list( providers = [AidlGenInfo], aspects = [_java_aidl_gen_aspect], + cfg = sdk_transition, + ), + "java_version": attr.string(), + "sdk_version": attr.string( + default = "system_current", + ), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", ), }, provides = [JavaInfo], diff --git a/rules/java/library.bzl b/rules/java/library.bzl index b273464d..f381b1c2 100644 --- a/rules/java/library.bzl +++ b/rules/java/library.bzl @@ -18,10 +18,63 @@ load( "@rules_java//java:defs.bzl", _java_library = "java_library", ) +load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs") -def java_library(name = "", srcs = [], deps = [], javacopts = [], **kwargs): - # Disable the error prone check of HashtableContains by default. See https://errorprone.info/bugpattern/HashtableContains - # HashtableContains error is reported when compiling //external/bouncycastle:bouncycastle-bcpkix-unbundled +# TODO(b/277801336): document these attributes. +def java_library( + name = "", + srcs = [], + deps = [], + javacopts = [], + sdk_version = None, + java_version = None, + tags = [], + target_compatible_with = [], + visibility = None, + **kwargs): + lib_name = name + "_private" + + # Disable the error prone check of HashtableContains by default. See https://errorprone.info/bugpattern/HashtableContains + # HashtableContains error is reported when compiling //external/bouncycastle:bouncycastle-bcpkix-unbundled opts = ["-Xep:HashtableContains:OFF"] + javacopts - _java_library(name = name, srcs = srcs, deps = deps, javacopts = opts, **kwargs) + _java_library( + name = lib_name, + srcs = srcs, + deps = deps, + javacopts = opts, + tags = tags + ["manual"], + target_compatible_with = target_compatible_with, + visibility = ["//visibility:private"], + **kwargs + ) + + java_library_sdk_transition( + name = name, + sdk_version = sdk_version, + java_version = java_version, + exports = lib_name, + tags = tags, + target_compatible_with = target_compatible_with, + visibility = ["//visibility:public"], + ) + +# The list of providers to forward was determined using cquery on one +# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at +# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit +# test ensures that the wrapper's providers and the wrapped rule's do +# match. +def _java_library_sdk_transition_impl(ctx): + return [ + ctx.attr.exports[0][JavaInfo], + ctx.attr.exports[0][InstrumentedFilesInfo], + ctx.attr.exports[0][ProguardSpecProvider], + ctx.attr.exports[0][OutputGroupInfo], + ctx.attr.exports[0][DefaultInfo], + ] + +java_library_sdk_transition = rule( + implementation = _java_library_sdk_transition_impl, + attrs = sdk_transition_attrs, + provides = [JavaInfo], +) diff --git a/rules/java/proto.bzl b/rules/java/proto.bzl index 16bb379c..68533d20 100644 --- a/rules/java/proto.bzl +++ b/rules/java/proto.bzl @@ -13,7 +13,7 @@ # limitations under the License. load("//build/bazel/rules:proto_file_utils.bzl", "proto_file_utils") -load(":library.bzl", "java_library") +load(":rules.bzl", "java_library") def _java_proto_sources_gen_rule_impl(ctx): out_flags = [] @@ -98,6 +98,7 @@ def _java_proto_library( plugin = None, out_format = None, proto_dep = None, + sdk_version = "core_current", **kwargs): proto_sources_name = name + "_proto_gen" @@ -118,6 +119,7 @@ def _java_proto_library( name = name, srcs = [proto_sources_name], deps = deps, + sdk_version = sdk_version, **kwargs ) diff --git a/rules/java/rules.bzl b/rules/java/rules.bzl index 881d44df..575321b2 100644 --- a/rules/java/rules.bzl +++ b/rules/java/rules.bzl @@ -17,7 +17,7 @@ load( _java_binary = "java_binary", ) load( - "@rules_java//java:defs.bzl", + "//build/bazel/rules/java:import.bzl", _java_import = "java_import", ) load( diff --git a/rules/java/sdk/BUILD.bazel b/rules/java/sdk/BUILD.bazel index f04685bd..b00ba819 100644 --- a/rules/java/sdk/BUILD.bazel +++ b/rules/java/sdk/BUILD.bazel @@ -17,16 +17,96 @@ package( ) load("@bazel_skylib//rules:common_settings.bzl", "int_setting", "string_setting") -load("//build/bazel/rules/common:sdk_version.bzl", "ALL_KINDS") +load("//build/bazel/rules/common:sdk_version.bzl", "sdk_version") load("//build/bazel/rules/common:api.bzl", "api") +load("//build/bazel/rules/java:versions.bzl", "java_versions") +load(":config_setting_names.bzl", "config_setting_names") +load("@bazel_skylib//lib:selects.bzl", "selects") +load("//prebuilts/sdk:utils.bzl", "prebuilt_sdk_utils") string_setting( name = "kind", - build_setting_default = "public", - values = ALL_KINDS, + build_setting_default = sdk_version.KIND_PUBLIC, + values = sdk_version.ALL_KINDS, ) int_setting( name = "api_level", build_setting_default = api.FUTURE_API_LEVEL, ) + +# The settings below are used to properly define a device java and android toolchain. + +# The SDK_NONE config setting maps to sdk_version = "none". In this configuration the java toolchain +# will provide nothing on the bootclasspath, not even the standard java.* libraries. +# The android toolchain is undefined in this configuration. +config_setting( + name = config_setting_names.SDK_NONE, + flag_values = { + "//build/bazel/rules/java/sdk:kind": sdk_version.KIND_NONE, + }, +) + +# Pre and Post Java 9 configs differ in how the bootclasspath is constructed and what arguments must +# be passed to javac. Pre Java 9, the SDK is passed as a whole to the --bootclasspath argument of +# javac. Post Java 9, the SDK is split between core libraries, passed using system modules and the +# --system javac argument, and the rest, added at the beginning of the classpath. +selects.config_setting_group( + name = config_setting_names.PRE_JAVA_9, + match_any = [ + "//build/bazel/rules/java:" + java_versions.VERSION_TO_CONFIG_SETTING[version] + for version in java_versions.VERSION_TO_CONFIG_SETTING.keys() + if version < 9 + ], +) + +selects.config_setting_group( + name = config_setting_names.POST_JAVA_9, + match_any = [ + "//build/bazel/rules/java:" + java_versions.VERSION_TO_CONFIG_SETTING[version] + for version in java_versions.VERSION_TO_CONFIG_SETTING.keys() + if version >= 9 + ], +) + +# Specific configuration at a given kind and api level will have the java and android toolchains +# pointed to the proper android.jar and framework.aidl files. +[ + config_setting( + name = config_setting_names.kind_api(kind, api_level), + flag_values = { + "//build/bazel/rules/java/sdk:kind": kind, + "//build/bazel/rules/java/sdk:api_level": str(api_level), + }, + ) + for api_level in prebuilt_sdk_utils.API_LEVELS + for kind in prebuilt_sdk_utils.available_kinds_for_api_level(api_level) +] + +# The bootclasspath is a function of sdk kind, api level, and whether building for pre or post java +# 9 sources. +[ + selects.config_setting_group( + name = config_setting_names.kind_api_pre_java_9(kind, api_level), + match_all = [ + config_setting_names.kind_api(kind, api_level), + config_setting_names.PRE_JAVA_9, + ], + ) + for api_level in prebuilt_sdk_utils.API_LEVELS + for kind in prebuilt_sdk_utils.available_kinds_for_api_level(api_level) + if java_versions.supports_pre_java_9(api_level) +] + +[ + selects.config_setting_group( + name = config_setting_names.kind_api_post_java_9(kind, api_level), + match_all = [ + config_setting_names.kind_api(kind, api_level), + config_setting_names.POST_JAVA_9, + ], + ) + for api_level in prebuilt_sdk_utils.API_LEVELS + for kind in prebuilt_sdk_utils.available_kinds_for_api_level(api_level) + if java_versions.supports_post_java_9(api_level) +] diff --git a/rules/java/sdk/config_setting_names.bzl b/rules/java/sdk/config_setting_names.bzl new file mode 100644 index 00000000..2150465f --- /dev/null +++ b/rules/java/sdk/config_setting_names.bzl @@ -0,0 +1,35 @@ +# Copyright (C) 2023 The Android Open Source Project +# +# 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. + +def _kind_api(kind, api_level): + return "config_setting_android_%s_%s" % (kind, api_level) + +def _kind_api_pre_java_9(kind, api_level): + return _kind_api(kind, api_level) + "_pre_java_9" + +def _kind_api_post_java_9(kind, api_level): + return _kind_api(kind, api_level) + "_post_java_9" + +_CONFIG_SETTING_SDK_NONE = "config_setting_sdk_none" +_CONFIG_SETTING_PRE_JAVA_9 = "config_setting_pre_java_9" +_CONFIG_SETTING_POST_JAVA_9 = "config_setting_post_java_9" + +config_setting_names = struct( + SDK_NONE = _CONFIG_SETTING_SDK_NONE, + PRE_JAVA_9 = _CONFIG_SETTING_PRE_JAVA_9, + POST_JAVA_9 = _CONFIG_SETTING_POST_JAVA_9, + kind_api = _kind_api, + kind_api_pre_java_9 = _kind_api_pre_java_9, + kind_api_post_java_9 = _kind_api_post_java_9, +) diff --git a/rules/java/sdk_transition.bzl b/rules/java/sdk_transition.bzl index efe41265..7f69d09d 100644 --- a/rules/java/sdk_transition.bzl +++ b/rules/java/sdk_transition.bzl @@ -13,7 +13,7 @@ # limitations under the License. load("//build/bazel/rules/java:versions.bzl", "java_versions") -load("//build/bazel/rules/common:sdk_version.bzl", "sdk_spec_from") +load("//build/bazel/rules/common:sdk_version.bzl", "sdk_version") load("//build/bazel/rules/common:api.bzl", "api") def _sdk_transition_impl(settings, attr): @@ -27,10 +27,10 @@ def _sdk_transition_impl(settings, attr): return { "//build/bazel/rules/java:version": default_java_version, "//build/bazel/rules/java:host_version": str(java_versions.get_version(attr.java_version)), - "//build/bazel/rules/java/sdk:kind": "none", + "//build/bazel/rules/java/sdk:kind": sdk_version.KIND_NONE, "//build/bazel/rules/java/sdk:api_level": api.NONE_API_LEVEL, } - sdk_spec = sdk_spec_from(attr.sdk_version) + sdk_spec = sdk_version.sdk_spec_from(attr.sdk_version) java_version = str(java_versions.get_version(attr.java_version, sdk_spec.api_level)) return { @@ -53,3 +53,16 @@ sdk_transition = transition( "//build/bazel/rules/java/sdk:api_level", ], ) + +sdk_transition_attrs = { + # This attribute must have a specific name to let the DexArchiveAspect propagate + # through it. + "exports": attr.label( + cfg = sdk_transition, + ), + "java_version": attr.string(), + "sdk_version": attr.string(), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), +} diff --git a/rules/java/sdk_transition_test.bzl b/rules/java/sdk_transition_test.bzl index 5c36ea45..6dd90441 100644 --- a/rules/java/sdk_transition_test.bzl +++ b/rules/java/sdk_transition_test.bzl @@ -27,8 +27,8 @@ SdkConfig = provider( ) def _sdk_transition_tester_impl(ctx): - if ctx.attr.deps and len(ctx.attr.deps) > 0 and SdkConfig in ctx.attr.deps[0]: - return ctx.attr.deps[0][SdkConfig] + if ctx.attr.exports and len(ctx.attr.exports) > 0 and SdkConfig in ctx.attr.exports[0]: + return ctx.attr.exports[0][SdkConfig] return SdkConfig( java_version = ctx.attr._java_version_config_setting[BuildSettingInfo].value, host_java_version = ctx.attr._host_java_version_config_setting[BuildSettingInfo].value, @@ -39,7 +39,7 @@ def _sdk_transition_tester_impl(ctx): sdk_transition_tester = rule( implementation = _sdk_transition_tester_impl, attrs = { - "deps": attr.label( + "exports": attr.label( cfg = sdk_transition, providers = [SdkConfig], ), @@ -126,7 +126,7 @@ def set_up_targets_under_test(name, java_version, sdk_version): name = name + "_parent", java_version = java_version, sdk_version = sdk_version, - deps = name + "_child", + exports = name + "_child", tags = ["manual"], ) sdk_transition_tester( diff --git a/rules/java/versions.bzl b/rules/java/versions.bzl index a449bfc4..acee980e 100644 --- a/rules/java/versions.bzl +++ b/rules/java/versions.bzl @@ -59,6 +59,18 @@ def _compatible_versions_for_api_level(api_level): ] return _ALL_VERSIONS +def _supports_pre_java_9(api_level): + return any([ + version < 9 + for version in _compatible_versions_for_api_level(api_level) + ]) + +def _supports_post_java_9(api_level): + return any([ + version >= 9 + for version in _compatible_versions_for_api_level(api_level) + ]) + _NORMALIZED_VERSIONS = { "1.7": 7, "7": 7, @@ -87,5 +99,6 @@ java_versions = struct( VERSION_TO_CONFIG_SETTING = _VERSION_TO_CONFIG_SETTING, compatible_versions_for_api_level = _compatible_versions_for_api_level, get_version = _get_version, - default_version = _default_version, + supports_pre_java_9 = _supports_pre_java_9, + supports_post_java_9 = _supports_post_java_9, ) diff --git a/rules/java/wrapper_test.sh b/rules/java/wrapper_test.sh new file mode 100644 index 00000000..abab4214 --- /dev/null +++ b/rules/java/wrapper_test.sh @@ -0,0 +1,38 @@ +#!/bin/bash -eux + +# Copyright (C) 2023 The Android Open Source Project +# +# 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. + +if [[ ! -d "build/bazel/ci" ]]; then + echo "Please run this script from TOP". + exit 1 +fi + +source "build/bazel/ci/build_with_bazel.sh" +source "build/bazel/ci/target_lists.sh" + +function test_wrapper_providers() { + for target in ${EXAMPLE_WRAPPER_TARGETS[@]}; do + private_providers="$(build/bazel/bin/bazel ${STARTUP_FLAGS[@]} \ + cquery ${FLAGS[@]} --config=android "${target}_private" \ + --starlark:expr="sorted(providers(target).keys())" --output=starlark|uniq)" + wrapper_providers="$(build/bazel/bin/bazel ${STARTUP_FLAGS[@]} \ + cquery ${FLAGS[@]} --config=android "${target}" \ + --starlark:expr="sorted(providers(target).keys())" --output=starlark|uniq)" + if [[ ! $(cmp -s <(echo "${private_providers}") <(echo "${wrapper_providers}")) ]]; then + echo "${target} and ${target}_private should have the same providers. Diff:" + diff <(echo "${private_providers}") <(echo "${wrapper_providers}") + fi + done +} diff --git a/rules/kotlin/kt_jvm_library.bzl b/rules/kotlin/kt_jvm_library.bzl index 84f4431f..c181fa9d 100644 --- a/rules/kotlin/kt_jvm_library.bzl +++ b/rules/kotlin/kt_jvm_library.bzl @@ -17,6 +17,7 @@ limitations under the License. load("@rules_kotlin//kotlin:compiler_opt.bzl", "kt_compiler_opt") load("@rules_kotlin//kotlin:jvm_library.bzl", _kt_jvm_library = "kt_jvm_library") load("//build/bazel/rules/java:rules.bzl", "java_import") +load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs") def _kotlin_resources_impl(ctx): output_file = ctx.actions.declare_file("kt_resources.jar") @@ -58,15 +59,20 @@ kotlin_resources = rule( }, ) +# TODO(b/277801336): document these attributes. def kt_jvm_library( name, deps = None, resources = None, resource_strip_prefix = None, kotlincflags = None, + java_version = None, + sdk_version = None, + tags = [], + target_compatible_with = [], + visibility = None, **kwargs): "Bazel macro wrapping for kt_jvm_library" - if resource_strip_prefix != None: java_import_name = name + "resources" kt_res_jar_name = name + "resources_jar" @@ -92,9 +98,43 @@ def kt_jvm_library( ) custom_kotlincopts = [":" + ktcopts_name] + lib_name = name + "_private" _kt_jvm_library( - name = name, + name = lib_name, deps = deps, custom_kotlincopts = custom_kotlincopts, + tags = tags + ["manual"], + target_compatible_with = target_compatible_with, + visibility = ["//visibility:private"], **kwargs ) + + kt_jvm_library_sdk_transition( + name = name, + sdk_version = sdk_version, + java_version = java_version, + exports = lib_name, + tags = tags, + target_compatible_with = target_compatible_with, + visibility = visibility, + ) + +# The list of providers to forward was determined using cquery on one +# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at +# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit +# test ensures that the wrapper's providers and the wrapped rule's do +# match. +def _kt_jvm_library_sdk_transition_impl(ctx): + return [ + ctx.attr.exports[0][JavaInfo], + ctx.attr.exports[0][InstrumentedFilesInfo], + ctx.attr.exports[0][ProguardSpecProvider], + ctx.attr.exports[0][OutputGroupInfo], + ctx.attr.exports[0][DefaultInfo], + ] + +kt_jvm_library_sdk_transition = rule( + implementation = _kt_jvm_library_sdk_transition_impl, + attrs = sdk_transition_attrs, + provides = [JavaInfo], +) |