xref: /aosp_15_r20/prebuilts/sdk/toolchains.bzl (revision 344a7f5ef16c479e7a7f54ee6567a9d112f9e72b)
1# Copyright (C) 2023 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15load("//build/bazel/rules/java:bootclasspath.bzl", "bootclasspath")
16load("//build/bazel/rules/java:java_system_modules.bzl", "java_system_modules")
17load("//build/bazel/rules/java:import.bzl", "java_import")
18load("//build/bazel/rules/java:versions.bzl", "java_versions")
19load("//prebuilts/sdk:utils.bzl", "prebuilt_sdk_utils")
20load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "DEFAULT_JAVACOPTS", "default_java_toolchain")
21load("//build/bazel/rules/common:api.bzl", "api")
22load("//build/bazel/rules/common:sdk_version.bzl", "sdk_version")
23load("@soong_injection//java_toolchain:constants.bzl", "constants")
24load("//build/bazel/rules/java/sdk:config_setting_names.bzl", sdk_config_setting = "config_setting_names")
25load("//build/bazel/rules/java/errorprone:errorprone.bzl", "errorprone_global_flags")
26
27# //prebuilts/sdk/current is a package, but the numbered directories under //prebuilts/sdk/ are not.
28def _prebuilt_path_prefix(kind, api_level):
29    common_prefix = "//prebuilts/sdk"
30    if api_level == api.FUTURE_API_LEVEL:
31        return "%s/current:%s" % (common_prefix, prebuilt_sdk_utils.to_kind_dir(kind))
32    return "%s:%s/%s" % (common_prefix, api_level, prebuilt_sdk_utils.to_kind_dir(kind))
33
34def _core_system_module_name(kind, api_level):
35    return "%s_%s_core_system_module" % (kind, api_level)
36
37def _android_jar_import_name(kind, api_level):
38    return "%s_%s_android_jar" % (kind, api_level)
39
40def _android_jar_file_name(kind, api_level):
41    return "%s/android.jar" % _prebuilt_path_prefix(kind, api_level)
42
43_SDK_PACKAGE_PREFIX = "//build/bazel/rules/java/sdk:"
44_JAVA_PACKAGE_PREFIX = "//build/bazel/rules/java:"
45
46def prebuilts_toolchain(java_toolchain_name, android_sdk_toolchain_name):
47    """Creates a device java and android toolchain and their dependencies.
48
49    Defines all java_import, java_system_modules, and bootclasspath targets that enable building
50    java/android/kotlin targets against a prebuilt SDK. Defines config settings at the proper
51    granularity (based on java version and sdk version), and the mappings between config setting and
52    proper toolchain attributes.
53    """
54    java_version_select_dict = {
55        _JAVA_PACKAGE_PREFIX + setting: str(version)
56        for version, setting in java_versions.VERSION_TO_CONFIG_SETTING.items()
57    }
58
59    bootclasspath_select_dict = {
60        _SDK_PACKAGE_PREFIX + sdk_config_setting.SDK_NONE: [],
61    }
62
63    # android_jar_select_dict and framework_aidl_select_dict are only used by the android
64    # toolchain. We should never be in a situation where sdk_version = "none" and we're trying to
65    # build an android_* target, but:
66    #    1. a Bazel check enforces that every toolchain attribute resolves under every
67    #       configuration, and
68    #    2. the DexArchiveAspect can propagate to java_host_for_device dependencies, and
69    #       tries to access an android.jar from there (b/278596841).
70    # We should map "none" to an explicitly failing target to address 1, but until 2 is resolved,
71    # we point to the public current artifacts.
72    android_jar_select_dict = {
73        _SDK_PACKAGE_PREFIX + sdk_config_setting.SDK_NONE: _android_jar_file_name(
74            sdk_version.KIND_PUBLIC,
75            api.FUTURE_API_LEVEL,
76        ),  # ":failed_android.jar",
77    }
78    framework_aidl_select_dict = {
79        _SDK_PACKAGE_PREFIX + sdk_config_setting.SDK_NONE: "%s/framework.aidl" % (
80            _prebuilt_path_prefix(
81                prebuilt_sdk_utils.to_aidl_kind(sdk_version.KIND_PUBLIC, api.FUTURE_API_LEVEL),
82                api.FUTURE_API_LEVEL,
83            )
84        ),  # ":failed_framework.aidl",
85    }
86
87    for api_level in prebuilt_sdk_utils.API_LEVELS:
88        for kind in prebuilt_sdk_utils.available_core_kinds_for_api_level(api_level):
89            java_import(
90                name = "%s_%s_core_jar" % (kind, api_level),
91                jars = ["%s/core-for-system-modules.jar" % _prebuilt_path_prefix(kind, api_level)],
92            )
93            java_system_modules(
94                name = _core_system_module_name(kind, api_level),
95                deps = [":%s_%s_core_jar" % (kind, api_level)],
96            )
97        for kind in prebuilt_sdk_utils.available_kinds_for_api_level(api_level):
98            java_import(
99                name = _android_jar_import_name(kind, api_level),
100                jars = [_android_jar_file_name(kind, api_level)],
101            )
102            config_setting = _SDK_PACKAGE_PREFIX + sdk_config_setting.kind_api(kind, api_level)
103            android_jar_select_dict[config_setting] = _android_jar_file_name(
104                kind,
105                api_level,
106            )
107
108            framework_aidl_select_dict[config_setting] = "%s/framework.aidl" % (
109                _prebuilt_path_prefix(
110                    prebuilt_sdk_utils.to_aidl_kind(kind, api_level),
111                    api_level,
112                )
113            )
114
115            if java_versions.supports_pre_java_9(api_level):
116                config_setting = _SDK_PACKAGE_PREFIX + sdk_config_setting.kind_api_pre_java_9(kind, api_level)
117                bootclasspath_select_dict[config_setting] = [_gen_bootclasspath(
118                    pre_java_9 = True,
119                    kind = kind,
120                    api_level = api_level,
121                )]
122            if java_versions.supports_post_java_9(api_level):
123                config_setting = _SDK_PACKAGE_PREFIX + sdk_config_setting.kind_api_post_java_9(kind, api_level)
124                bootclasspath_select_dict[config_setting] = [_gen_bootclasspath(
125                    pre_java_9 = False,
126                    kind = kind,
127                    api_level = api_level,
128                )]
129
130    default_java_toolchain(
131        name = java_toolchain_name,
132        bootclasspath = select(bootclasspath_select_dict),
133        source_version = select(java_version_select_dict),
134        target_version = select(java_version_select_dict),
135        # TODO(b/218720643): Support switching between multiple JDKs.
136        java_runtime = "//prebuilts/jdk/jdk21:jdk21_runtime",
137        toolchain_definition = False,
138        misc = errorprone_global_flags + DEFAULT_JAVACOPTS + constants.CommonJdkFlags + select({
139            _SDK_PACKAGE_PREFIX + sdk_config_setting.SDK_NONE: ["--system=none"],
140            "//conditions:default": [],
141        }),
142    )
143
144    native.android_sdk(
145        name = android_sdk_toolchain_name,
146        aapt = "//prebuilts/sdk/tools:linux/bin/aapt",
147        aapt2 = "//prebuilts/sdk/tools:linux/bin/aapt2",
148        adb = ":fail",  # TODO: use system/core/adb ?
149        aidl = "//prebuilts/sdk/tools:linux/bin/aidl",
150        android_jar = select(android_jar_select_dict),
151        apksigner = ":apksigner",
152        dx = "//prebuilts/sdk/tools:dx",  # TODO: add D8
153        framework_aidl = select(framework_aidl_select_dict),
154        main_dex_classes = "//prebuilts/sdk/tools:mainDexClasses.rules",
155        main_dex_list_creator = ":fail",
156        proguard = ":fail",  # TODO: add R8
157        system = select({
158            key: bootclasspath_select_dict[key][0]
159            for key in bootclasspath_select_dict.keys()
160            if "none" not in key
161        } | {"//conditions:default": ":failed_bootclasspath"}),
162        shrinked_android_jar = select(android_jar_select_dict),
163        visibility = ["//visibility:public"],
164        zipalign = "//prebuilts/sdk/tools:linux/bin/zipalign",
165    )
166
167def _gen_bootclasspath(pre_java_9, kind, api_level):
168    bootclasspath_name = "toolchain_%s_java_9_android_%s_%s_bootclasspath" % ("pre" if pre_java_9 else "post", kind, api_level)
169    auxiliary = [_android_jar_import_name(kind, api_level)]
170    bootclasspath_attr = [_android_jar_import_name(kind, api_level), ":core_lambda_stubs"]
171    system = None
172    if pre_java_9:
173        auxiliary = auxiliary + [":core_lambda_stubs"]
174    else:
175        system = _core_system_module_name(prebuilt_sdk_utils.to_core_kind(kind, api_level), api_level)
176
177    bootclasspath(
178        name = bootclasspath_name,
179        auxiliary = auxiliary,
180        bootclasspath = bootclasspath_attr,
181        system = system,
182    )
183    return bootclasspath_name
184