• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2021 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"""
16Configuration transitions for APEX rules.
17
18Transitions are a Bazel mechanism to analyze/build dependencies in a different
19configuration (i.e. options and flags). The APEX transition is applied from a
20top level APEX rule to its dependencies via an outgoing edge, so that the
21dependencies can be built specially for APEXes (vs the platform).
22
23e.g. if an apex A depends on some target T, building T directly as a top level target
24will use a different configuration from building T indirectly as a dependency of A. The
25latter will contain APEX specific configuration settings that its rule or an aspect can
26use to create different actions or providers for APEXes specifically..
27
28The outgoing transitions are similar to ApexInfo propagation in Soong's
29top-down ApexInfoMutator:
30https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=948-962;drc=539d41b686758eeb86236c0e0dcf75478acb77f3
31"""
32
33load("@bazel_skylib//lib:collections.bzl", "collections")
34load("@bazel_skylib//lib:dicts.bzl", "dicts")
35load("//build/bazel/rules/apex:sdk_versions.bzl", "maybe_override_min_sdk_version")
36
37def _get_api_domain(apex_name, base_apex_name):
38    # AOSP and Google variants of apexes are part of the same API domain.
39    # Test apexes and source apexes are part of the same API domain.
40    # Override test apexes should return the api domain of the overriden test apex
41    # Return base_apex_name if it is not empty.
42    if base_apex_name:
43        # TODO (b/282058578): Deprecate this special handling.
44        # TODO: This does not handle special cases like test1_com.android.tzdata.
45        # This is fine for now since tzdata does not have native code.
46        return base_apex_name.lstrip("test_")
47
48    return apex_name
49
50def _create_apex_configuration(settings, attr, additional = {}):
51    min_sdk_version = maybe_override_min_sdk_version(
52        attr.min_sdk_version,
53        settings["//build/bazel/product_config:apex_global_min_sdk_version_override"],
54    )
55
56    apex_name = attr.name
57    if attr.apex_available_name != "":
58        apex_name = attr.apex_available_name
59
60    return dicts.add({
61        "//build/bazel/rules/apex:apex_name": apex_name,  # Name of the APEX
62        "//build/bazel/rules/apex:base_apex_name": attr.base_apex_name,  # Name of the base APEX, if exists
63        "//build/bazel/rules/apex:min_sdk_version": min_sdk_version,
64        "//build/bazel/rules/apex:within_apex": True,  # Building a APEX
65        "//build/bazel/rules/apex:api_domain": _get_api_domain(attr.name, attr.base_apex_name),
66    }, additional)
67
68def _impl(settings, attr):
69    # Perform a transition to apply APEX specific build settings on the
70    # destination target (i.e. an APEX dependency).
71
72    # At this point, the configurable attributes native_shared_libs_32 and
73    # native_shared_libs_64 are already resolved according to the lunch target
74    direct_deps = [str(dep) for dep in attr.native_shared_libs_32]
75    direct_deps += [str(dep) for dep in attr.native_shared_libs_64]
76    direct_deps += [str(dep) for dep in attr.binaries]
77
78    return _create_apex_configuration(settings, attr, {
79        "//build/bazel/rules/apex:apex_direct_deps": collections.uniq(sorted(direct_deps)),
80    })
81
82_TRANSITION_INPUTS = [
83    "//build/bazel/product_config:apex_global_min_sdk_version_override",
84]
85
86_TRANSITION_OUTPUTS = [
87    "//build/bazel/rules/apex:apex_name",
88    "//build/bazel/rules/apex:base_apex_name",
89    "//build/bazel/rules/apex:within_apex",
90    "//build/bazel/rules/apex:min_sdk_version",
91    "//build/bazel/rules/apex:apex_direct_deps",
92    "//build/bazel/rules/apex:api_domain",
93]
94
95apex_transition = transition(
96    implementation = _impl,
97    inputs = _TRANSITION_INPUTS,
98    outputs = _TRANSITION_OUTPUTS,
99)
100
101# The following table describes how target platform of shared_lib_transition_32 and shared_lib_transition_64
102# look like when building APEXes for different primary/secondary architecture.
103#
104# |---------------------------+----------------------------------------------------+----------------------------------------------------|
105# | Primary arch              | Platform for                                       | Platform for                                       |
106# |       /  Secondary arch   | 32b libs transition                                | 64b libs transition                                |
107# |---------------------------+----------------------------------------------------+----------------------------------------------------|
108# | 32bit / N/A               | android_target                                     | android_target                                     |
109# | (android_target is 32bit) |                                                    | (wrong target platform indicates the transition    |
110# |                           |                                                    | is not needed, and the 64bit libs are not included |
111# |                           |                                                    | in APEXes for 32bit devices, see                   |
112# |                           |                                                    | _create_file_mapping() in apex.bzl)                |
113# |---------------------------+----------------------------------------------------+----------------------------------------------------|
114# | 64bit / 32bit             | android_target_secondary                           | android_target                                     |
115# | (android_target is 64bit) |                                                    |                                                    |
116# |---------------------------+----------------------------------------------------+----------------------------------------------------|
117# | 64bit / N/A               | android_target                                     | android_target                                     |
118# | (android_target is 64bit) | (wrong target platform indicates the transition    |                                                    |
119# |                           | is not needed, and the 32bit libs are not included |                                                    |
120# |                           | in APEXes for 64bit ONLY devices, see              |                                                    |
121# |                           | _create_file_mapping() in apex.bzl)                |                                                    |
122# |---------------------------+----------------------------------------------------+----------------------------------------------------|
123
124def _impl_shared_lib_transition_32(settings, attr):
125    # Perform a transition to apply APEX specific build settings on the
126    # destination target (i.e. an APEX dependency).
127
128    direct_deps = [str(dep) for dep in attr.native_shared_libs_32]
129    direct_deps += [str(dep) for dep in attr.binaries]
130
131    old_platform = str(settings["//command_line_option:platforms"][0])
132
133    return _create_apex_configuration(settings, attr, {
134        "//build/bazel/rules/apex:apex_direct_deps": collections.uniq(sorted(direct_deps)),
135        "//command_line_option:platforms": old_platform + "_secondary",
136    })
137
138shared_lib_transition_32 = transition(
139    implementation = _impl_shared_lib_transition_32,
140    inputs = _TRANSITION_INPUTS + ["//command_line_option:platforms"],
141    outputs = _TRANSITION_OUTPUTS + ["//command_line_option:platforms"],
142)
143
144def _impl_shared_lib_transition_64(settings, attr):
145    # Perform a transition to apply APEX specific build settings on the
146    # destination target (i.e. an APEX dependency).
147
148    direct_deps = [str(dep) for dep in attr.native_shared_libs_64]
149    direct_deps += [str(dep) for dep in attr.binaries]
150
151    # For the 64 bit transition, we don't actually change the arch, because
152    # we only read the value of native_shared_libs_64 when the target
153    # is 64-bit already
154    return _create_apex_configuration(settings, attr, {
155        "//build/bazel/rules/apex:apex_direct_deps": collections.uniq(sorted(direct_deps)),
156    })
157
158shared_lib_transition_64 = transition(
159    implementation = _impl_shared_lib_transition_64,
160    inputs = _TRANSITION_INPUTS,
161    outputs = _TRANSITION_OUTPUTS,
162)
163