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 15""" 16Contains logic for a transition that is applied to java-based rules which 17takes the sdk_version and java_version attributes and populates build settings 18based on their values. 19""" 20 21load("//build/bazel/rules/common:api.bzl", "api") 22load("//build/bazel/rules/common:sdk_version.bzl", "sdk_version") 23load("//build/bazel/rules/java:versions.bzl", "java_versions") 24 25_DEFAULT_API_DOMAIN = "system" # i.e. the platform variant 26 27def _validate_attrs(attr): 28 if hasattr(attr, "sdk_version") and hasattr(attr, "_sdk_version"): 29 fail("don't have both _sdk_version and sdk_version in attrs, it's confusing.") 30 if not hasattr(attr, "sdk_version") and not hasattr(attr, "_sdk_version"): 31 fail("must have one of _sdk_version or sdk_version attr.") 32 33def _sdk_transition_impl(settings, attr): 34 _validate_attrs(attr) 35 sdk_version_attr = ( 36 attr.sdk_version if hasattr(attr, "sdk_version") else attr._sdk_version 37 ) 38 java_version = attr.java_version if hasattr(attr, "java_version") else None 39 host_platform = settings["//command_line_option:host_platform"] 40 default_java_version = str(java_versions.get_version()) 41 42 # TODO: this condition should really be "platform is not a device". 43 # More details on why we're treating java version for non-device platforms differently at the 44 # definition of the //build/bazel/rules/java:host_version build setting. 45 if all([host_platform == platform for platform in settings["//command_line_option:platforms"]]): 46 return { 47 "//build/bazel/rules/java:version": default_java_version, 48 "//build/bazel/rules/java:host_version": str( 49 java_versions.get_version(java_version), 50 ), 51 "//build/bazel/rules/java/sdk:kind": sdk_version.KIND_NONE, 52 "//build/bazel/rules/java/sdk:api_level": api.NONE_API_LEVEL, 53 "//build/bazel/rules/apex:api_domain": _DEFAULT_API_DOMAIN, 54 } 55 sdk_spec = sdk_version.sdk_spec_from(sdk_version_attr) 56 final_java_version = str(java_versions.get_version( 57 java_version, 58 sdk_spec.api_level, 59 )) 60 61 ret = { 62 "//build/bazel/rules/java:host_version": default_java_version, 63 "//build/bazel/rules/java:version": final_java_version, 64 "//build/bazel/rules/java/sdk:kind": sdk_spec.kind, 65 "//build/bazel/rules/java/sdk:api_level": sdk_spec.api_level, 66 "//build/bazel/rules/apex:api_domain": _DEFAULT_API_DOMAIN, 67 } 68 69 # uses_sdk returns true if the app sets an sdk_version _except_ `core_platform` 70 # https://cs.android.com/android/_/android/platform/build/soong/+/main:java/app.go;l=253;bpv=1;bpt=0;drc=e12c083198403ec694af6c625aed11327eb2bf7f 71 uses_sdk = (sdk_spec != None) and (sdk_spec.kind != sdk_version.KIND_CORE_PLATFORM) 72 73 if uses_sdk: 74 # If the app is using an SDK, build it in the "unbundled_app" api domain build setting 75 # This ensures that its jni deps are building against the NDK 76 # TODO - b/299360988 - Handle jni_uses_sdk_apis, jni_uses_platform_apis 77 ret["//build/bazel/rules/apex:api_domain"] = "unbundled_app" 78 79 return ret 80 81sdk_transition = transition( 82 implementation = _sdk_transition_impl, 83 inputs = [ 84 "//command_line_option:host_platform", 85 "//command_line_option:platforms", 86 ], 87 outputs = [ 88 "//build/bazel/rules/java:version", 89 "//build/bazel/rules/java:host_version", 90 "//build/bazel/rules/java/sdk:kind", 91 "//build/bazel/rules/java/sdk:api_level", 92 "//build/bazel/rules/apex:api_domain", 93 ], 94) 95 96sdk_transition_attrs = { 97 # This attribute must have a specific name to let the DexArchiveAspect propagate 98 # through it. 99 "exports": attr.label( 100 cfg = sdk_transition, 101 ), 102 "java_version": attr.string(), 103 "sdk_version": attr.string(), 104 "_allowlist_function_transition": attr.label( 105 default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 106 ), 107} 108