xref: /aosp_15_r20/build/bazel/rules/apex/apex.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project
2*7594170eSAndroid Build Coastguard Worker#
3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*7594170eSAndroid Build Coastguard Worker#
7*7594170eSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*7594170eSAndroid Build Coastguard Worker#
9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*7594170eSAndroid Build Coastguard Worker# limitations under the License.
14*7594170eSAndroid Build Coastguard Worker
15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths")
16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
17*7594170eSAndroid Build Coastguard Workerload("@soong_injection//apex_toolchain:constants.bzl", "default_manifest_version")
18*7594170eSAndroid Build Coastguard Workerload("//build/bazel/platforms:platform_utils.bzl", "platforms")
19*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:build_fingerprint.bzl", "BuildFingerprintInfo")
20*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:common.bzl", "get_dep_targets")
21*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:metadata.bzl", "MetadataFileInfo")
22*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:prebuilt_file.bzl", "PrebuiltFileInfo")
23*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:sh_binary.bzl", "ShBinaryInfo")
24*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:toolchain_utils.bzl", "verify_toolchain_exists")
25*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/android:android_app_certificate.bzl", "AndroidAppCertificateInfo", "NoAndroidAppCertificateInfo", "android_app_certificate_with_default_cert")
26*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/android:manifest_fixer.bzl", "manifest_fixer")
27*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/apex:cc.bzl", "ApexCcInfo", "ApexCcMkInfo", "apex_cc_aspect")
28*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/apex:sdk_versions.bzl", "maybe_override_min_sdk_version")
29*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/apex:transition.bzl", "apex_transition", "shared_lib_transition_32", "shared_lib_transition_64")
30*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/cc:clang_tidy.bzl", "collect_deps_clang_tidy_info")
31*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/cc:stripped_cc_common.bzl", "CcUnstrippedInfo", "StrippedCcBinaryInfo")
32*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/common:api.bzl", "api")
33*7594170eSAndroid Build Coastguard Workerload(
34*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/license:license_aspect.bzl",
35*7594170eSAndroid Build Coastguard Worker    "RuleLicensedDependenciesInfo",
36*7594170eSAndroid Build Coastguard Worker    "license_aspect",
37*7594170eSAndroid Build Coastguard Worker    "license_map",
38*7594170eSAndroid Build Coastguard Worker    "license_map_notice_files",
39*7594170eSAndroid Build Coastguard Worker    "license_map_to_json",
40*7594170eSAndroid Build Coastguard Worker)
41*7594170eSAndroid Build Coastguard Workerload(":apex_available.bzl", "ApexAvailableInfo", "apex_available_aspect")
42*7594170eSAndroid Build Coastguard Workerload(":apex_deps_validation.bzl", "ApexDepsInfo", "apex_deps_validation_aspect", "validate_apex_deps")
43*7594170eSAndroid Build Coastguard Workerload(":apex_info.bzl", "ApexInfo", "ApexMkInfo")
44*7594170eSAndroid Build Coastguard Workerload(":apex_key.bzl", "ApexKeyInfo")
45*7594170eSAndroid Build Coastguard Workerload(":bundle.bzl", "apex_zip_files")
46*7594170eSAndroid Build Coastguard Worker
47*7594170eSAndroid Build Coastguard Workerdef _create_file_mapping(ctx):
48*7594170eSAndroid Build Coastguard Worker    """Create a file mapping for the APEX filesystem image.
49*7594170eSAndroid Build Coastguard Worker
50*7594170eSAndroid Build Coastguard Worker    This returns a Dict[File, str] where the dictionary keys are paths in the
51*7594170eSAndroid Build Coastguard Worker    apex staging dir / filesystem image, and the values are the files and other
52*7594170eSAndroid Build Coastguard Worker    metadata that should be installed there.
53*7594170eSAndroid Build Coastguard Worker
54*7594170eSAndroid Build Coastguard Worker    It also returns other data structures, such as:
55*7594170eSAndroid Build Coastguard Worker    - requires: libs that this apex depend on from other apex or the platform
56*7594170eSAndroid Build Coastguard Worker    - provides: libs that this apex provide to other apex or the platform
57*7594170eSAndroid Build Coastguard Worker    - make_modules_to_install: make module names of libs that needs to be installed onto the platform in a bundled build (LOCAL_REQUIRED_MODULES)
58*7594170eSAndroid Build Coastguard Worker    - make_files_info: metadata about this apex's payload to be used for other packaging steps.
59*7594170eSAndroid Build Coastguard Worker    """
60*7594170eSAndroid Build Coastguard Worker
61*7594170eSAndroid Build Coastguard Worker    # Dictionary mapping from paths in the apex to the files and associated metadata to be put there
62*7594170eSAndroid Build Coastguard Worker    file_mapping = {}
63*7594170eSAndroid Build Coastguard Worker    requires = {}
64*7594170eSAndroid Build Coastguard Worker    provides = {}
65*7594170eSAndroid Build Coastguard Worker    make_modules_to_install = {}
66*7594170eSAndroid Build Coastguard Worker    metadata_file_mapping = {}
67*7594170eSAndroid Build Coastguard Worker
68*7594170eSAndroid Build Coastguard Worker    # Generate a str -> str dictionary to define Make modules and variables for the
69*7594170eSAndroid Build Coastguard Worker    # packaging step in a mixed build. This is necessary as long as there are
70*7594170eSAndroid Build Coastguard Worker    # Make-derived actions that operate on bazel's outputs. If we move all Make
71*7594170eSAndroid Build Coastguard Worker    # packaging actions to Bazel, there's no need for this data flow.
72*7594170eSAndroid Build Coastguard Worker    make_files_info = {}
73*7594170eSAndroid Build Coastguard Worker
74*7594170eSAndroid Build Coastguard Worker    arch = platforms.get_target_arch(ctx.attr._platform_utils)
75*7594170eSAndroid Build Coastguard Worker    is_target_64_bit = platforms.get_target_bitness(ctx.attr._platform_utils) == 64
76*7594170eSAndroid Build Coastguard Worker
77*7594170eSAndroid Build Coastguard Worker    def add_file_mapping(install_dir, basename, bazel_file, klass, owner, arch = None, unstripped = None, metadata_file = None):
78*7594170eSAndroid Build Coastguard Worker        installed_path = paths.join(install_dir, basename)
79*7594170eSAndroid Build Coastguard Worker        if installed_path in file_mapping and file_mapping[installed_path] != bazel_file:
80*7594170eSAndroid Build Coastguard Worker            # TODO: we should figure this out and make it a failure
81*7594170eSAndroid Build Coastguard Worker            print("Warning: %s in this apex is already installed to %s, overwriting it with %s" %
82*7594170eSAndroid Build Coastguard Worker                  (file_mapping[installed_path].path, installed_path, bazel_file.path))
83*7594170eSAndroid Build Coastguard Worker        file_mapping[installed_path] = bazel_file
84*7594170eSAndroid Build Coastguard Worker        metadata_file_mapping[installed_path] = metadata_file
85*7594170eSAndroid Build Coastguard Worker
86*7594170eSAndroid Build Coastguard Worker        files_info = {
87*7594170eSAndroid Build Coastguard Worker            "built_file": bazel_file.path,
88*7594170eSAndroid Build Coastguard Worker            "class": klass,
89*7594170eSAndroid Build Coastguard Worker            "install_dir": install_dir,
90*7594170eSAndroid Build Coastguard Worker            "basename": basename,
91*7594170eSAndroid Build Coastguard Worker            "package": owner.package,
92*7594170eSAndroid Build Coastguard Worker            "make_module_name": owner.name,
93*7594170eSAndroid Build Coastguard Worker            "arch": arch,
94*7594170eSAndroid Build Coastguard Worker        }
95*7594170eSAndroid Build Coastguard Worker        if unstripped:
96*7594170eSAndroid Build Coastguard Worker            files_info["unstripped_built_file"] = unstripped.path
97*7594170eSAndroid Build Coastguard Worker        make_files_info[installed_path] = files_info
98*7594170eSAndroid Build Coastguard Worker
99*7594170eSAndroid Build Coastguard Worker    def _add_lib_files(directory, libs, arch):
100*7594170eSAndroid Build Coastguard Worker        for dep in libs:
101*7594170eSAndroid Build Coastguard Worker            apex_cc_info = dep[ApexCcInfo]
102*7594170eSAndroid Build Coastguard Worker            for lib in apex_cc_info.requires_native_libs.to_list():
103*7594170eSAndroid Build Coastguard Worker                requires[lib] = True
104*7594170eSAndroid Build Coastguard Worker            for lib in apex_cc_info.provides_native_libs.to_list():
105*7594170eSAndroid Build Coastguard Worker                provides[lib] = True
106*7594170eSAndroid Build Coastguard Worker            for lib_file in apex_cc_info.transitive_shared_libs.to_list():
107*7594170eSAndroid Build Coastguard Worker                stripped = lib_file.stripped
108*7594170eSAndroid Build Coastguard Worker                unstripped = lib_file.unstripped
109*7594170eSAndroid Build Coastguard Worker                add_file_mapping(
110*7594170eSAndroid Build Coastguard Worker                    directory,
111*7594170eSAndroid Build Coastguard Worker                    stripped.basename,
112*7594170eSAndroid Build Coastguard Worker                    stripped,
113*7594170eSAndroid Build Coastguard Worker                    "nativeSharedLib",
114*7594170eSAndroid Build Coastguard Worker                    lib_file.generating_rule_owner,
115*7594170eSAndroid Build Coastguard Worker                    arch = arch,
116*7594170eSAndroid Build Coastguard Worker                    unstripped = unstripped,
117*7594170eSAndroid Build Coastguard Worker                    metadata_file = lib_file.metadata_file,
118*7594170eSAndroid Build Coastguard Worker                )
119*7594170eSAndroid Build Coastguard Worker
120*7594170eSAndroid Build Coastguard Worker            # For bundled builds.
121*7594170eSAndroid Build Coastguard Worker            apex_cc_mk_info = dep[ApexCcMkInfo]
122*7594170eSAndroid Build Coastguard Worker            for mk_module in apex_cc_mk_info.make_modules_to_install.to_list():
123*7594170eSAndroid Build Coastguard Worker                make_modules_to_install[mk_module] = True
124*7594170eSAndroid Build Coastguard Worker
125*7594170eSAndroid Build Coastguard Worker    if is_target_64_bit:
126*7594170eSAndroid Build Coastguard Worker        _add_lib_files("lib64", ctx.attr.native_shared_libs_64, arch)
127*7594170eSAndroid Build Coastguard Worker
128*7594170eSAndroid Build Coastguard Worker        secondary_arch = platforms.get_target_secondary_arch(ctx.attr._platform_utils)
129*7594170eSAndroid Build Coastguard Worker        if secondary_arch:
130*7594170eSAndroid Build Coastguard Worker            _add_lib_files("lib", ctx.attr.native_shared_libs_32, secondary_arch)
131*7594170eSAndroid Build Coastguard Worker    else:
132*7594170eSAndroid Build Coastguard Worker        _add_lib_files("lib", ctx.attr.native_shared_libs_32, arch)
133*7594170eSAndroid Build Coastguard Worker
134*7594170eSAndroid Build Coastguard Worker    backing_libs = []
135*7594170eSAndroid Build Coastguard Worker    for lib in file_mapping.values():
136*7594170eSAndroid Build Coastguard Worker        if lib.basename not in backing_libs:
137*7594170eSAndroid Build Coastguard Worker            backing_libs.append(lib.basename)
138*7594170eSAndroid Build Coastguard Worker    backing_libs = sorted(backing_libs)
139*7594170eSAndroid Build Coastguard Worker
140*7594170eSAndroid Build Coastguard Worker    # Handle prebuilts
141*7594170eSAndroid Build Coastguard Worker    for dep in ctx.attr.prebuilts:
142*7594170eSAndroid Build Coastguard Worker        prebuilt_file_info = dep[PrebuiltFileInfo]
143*7594170eSAndroid Build Coastguard Worker        if prebuilt_file_info.filename:
144*7594170eSAndroid Build Coastguard Worker            filename = prebuilt_file_info.filename
145*7594170eSAndroid Build Coastguard Worker        else:
146*7594170eSAndroid Build Coastguard Worker            filename = dep.label.name
147*7594170eSAndroid Build Coastguard Worker        add_file_mapping(
148*7594170eSAndroid Build Coastguard Worker            prebuilt_file_info.dir,
149*7594170eSAndroid Build Coastguard Worker            filename,
150*7594170eSAndroid Build Coastguard Worker            prebuilt_file_info.src,
151*7594170eSAndroid Build Coastguard Worker            "etc",
152*7594170eSAndroid Build Coastguard Worker            dep.label,
153*7594170eSAndroid Build Coastguard Worker            arch = arch,
154*7594170eSAndroid Build Coastguard Worker            metadata_file = dep[MetadataFileInfo].metadata_file,
155*7594170eSAndroid Build Coastguard Worker        )
156*7594170eSAndroid Build Coastguard Worker
157*7594170eSAndroid Build Coastguard Worker    # Handle binaries
158*7594170eSAndroid Build Coastguard Worker    for dep in ctx.attr.binaries:
159*7594170eSAndroid Build Coastguard Worker        if ShBinaryInfo in dep:
160*7594170eSAndroid Build Coastguard Worker            # sh_binary requires special handling on directory/filename construction.
161*7594170eSAndroid Build Coastguard Worker            sh_binary_info = dep[ShBinaryInfo]
162*7594170eSAndroid Build Coastguard Worker            if sh_binary_info:
163*7594170eSAndroid Build Coastguard Worker                directory = "bin"
164*7594170eSAndroid Build Coastguard Worker                if sh_binary_info.sub_dir:
165*7594170eSAndroid Build Coastguard Worker                    directory = paths.join("bin", sh_binary_info.sub_dir)
166*7594170eSAndroid Build Coastguard Worker
167*7594170eSAndroid Build Coastguard Worker                filename = dep.label.name
168*7594170eSAndroid Build Coastguard Worker                if sh_binary_info.filename:
169*7594170eSAndroid Build Coastguard Worker                    filename = sh_binary_info.filename
170*7594170eSAndroid Build Coastguard Worker
171*7594170eSAndroid Build Coastguard Worker                add_file_mapping(
172*7594170eSAndroid Build Coastguard Worker                    directory,
173*7594170eSAndroid Build Coastguard Worker                    filename,
174*7594170eSAndroid Build Coastguard Worker                    dep[DefaultInfo].files_to_run.executable,
175*7594170eSAndroid Build Coastguard Worker                    "shBinary",
176*7594170eSAndroid Build Coastguard Worker                    dep.label,
177*7594170eSAndroid Build Coastguard Worker                    arch = arch,
178*7594170eSAndroid Build Coastguard Worker                    metadata_file = dep[MetadataFileInfo].metadata_file,
179*7594170eSAndroid Build Coastguard Worker                )
180*7594170eSAndroid Build Coastguard Worker        elif ApexCcInfo in dep:
181*7594170eSAndroid Build Coastguard Worker            # cc_binary just takes the final executable from the runfiles.
182*7594170eSAndroid Build Coastguard Worker            add_file_mapping(
183*7594170eSAndroid Build Coastguard Worker                "bin",
184*7594170eSAndroid Build Coastguard Worker                dep.label.name,
185*7594170eSAndroid Build Coastguard Worker                dep[DefaultInfo].files_to_run.executable,
186*7594170eSAndroid Build Coastguard Worker                "nativeExecutable",
187*7594170eSAndroid Build Coastguard Worker                dep.label,
188*7594170eSAndroid Build Coastguard Worker                arch,
189*7594170eSAndroid Build Coastguard Worker                unstripped = dep[CcUnstrippedInfo].unstripped[0].files.to_list()[0],
190*7594170eSAndroid Build Coastguard Worker                metadata_file = dep[MetadataFileInfo].metadata_file,
191*7594170eSAndroid Build Coastguard Worker            )
192*7594170eSAndroid Build Coastguard Worker
193*7594170eSAndroid Build Coastguard Worker            # Add transitive shared lib deps of apex binaries to the apex.
194*7594170eSAndroid Build Coastguard Worker            if is_target_64_bit:
195*7594170eSAndroid Build Coastguard Worker                _add_lib_files("lib64", [dep], arch)
196*7594170eSAndroid Build Coastguard Worker            else:
197*7594170eSAndroid Build Coastguard Worker                _add_lib_files("lib", [dep], arch)
198*7594170eSAndroid Build Coastguard Worker
199*7594170eSAndroid Build Coastguard Worker    return (
200*7594170eSAndroid Build Coastguard Worker        file_mapping,
201*7594170eSAndroid Build Coastguard Worker        sorted(requires.keys(), key = lambda x: x.name),  # sort on just the name of the target, not package
202*7594170eSAndroid Build Coastguard Worker        sorted(provides.keys(), key = lambda x: x.name),
203*7594170eSAndroid Build Coastguard Worker        backing_libs,
204*7594170eSAndroid Build Coastguard Worker        sorted(make_modules_to_install),
205*7594170eSAndroid Build Coastguard Worker        sorted(make_files_info.values(), key = lambda x: ":".join([x["package"], x["make_module_name"], x["arch"]])),
206*7594170eSAndroid Build Coastguard Worker        metadata_file_mapping,
207*7594170eSAndroid Build Coastguard Worker    )
208*7594170eSAndroid Build Coastguard Worker
209*7594170eSAndroid Build Coastguard Workerdef _add_so(label):
210*7594170eSAndroid Build Coastguard Worker    return label.name + ".so"
211*7594170eSAndroid Build Coastguard Worker
212*7594170eSAndroid Build Coastguard Workerdef _add_apex_manifest_information(
213*7594170eSAndroid Build Coastguard Worker        ctx,
214*7594170eSAndroid Build Coastguard Worker        apex_toolchain,
215*7594170eSAndroid Build Coastguard Worker        requires_native_libs,
216*7594170eSAndroid Build Coastguard Worker        provides_native_libs):
217*7594170eSAndroid Build Coastguard Worker    apex_manifest_json = ctx.file.manifest
218*7594170eSAndroid Build Coastguard Worker    apex_manifest_full_json = ctx.actions.declare_file(ctx.attr.name + "_apex_manifest_full.json")
219*7594170eSAndroid Build Coastguard Worker
220*7594170eSAndroid Build Coastguard Worker    args = ctx.actions.args()
221*7594170eSAndroid Build Coastguard Worker    args.add(apex_manifest_json)
222*7594170eSAndroid Build Coastguard Worker    args.add_all(["-a", "requireNativeLibs"])
223*7594170eSAndroid Build Coastguard Worker    args.add_all(requires_native_libs, map_each = _add_so)  # e.g. turn "//foo/bar:baz" to "baz.so"
224*7594170eSAndroid Build Coastguard Worker    args.add_all(["-a", "provideNativeLibs"])
225*7594170eSAndroid Build Coastguard Worker    args.add_all(provides_native_libs, map_each = _add_so)
226*7594170eSAndroid Build Coastguard Worker
227*7594170eSAndroid Build Coastguard Worker    manifest_version = default_manifest_version
228*7594170eSAndroid Build Coastguard Worker    if ctx.attr.variant_version != "":
229*7594170eSAndroid Build Coastguard Worker        manifest_version = manifest_version + int(ctx.attr.variant_version)
230*7594170eSAndroid Build Coastguard Worker    override_manifest_version = ctx.attr._override_apex_manifest_default_version[BuildSettingInfo].value
231*7594170eSAndroid Build Coastguard Worker    if override_manifest_version:
232*7594170eSAndroid Build Coastguard Worker        manifest_version = override_manifest_version
233*7594170eSAndroid Build Coastguard Worker    args.add_all(["-se", "version", "0", manifest_version])
234*7594170eSAndroid Build Coastguard Worker
235*7594170eSAndroid Build Coastguard Worker    # TODO: support other optional flags like -v name and -a jniLibs
236*7594170eSAndroid Build Coastguard Worker    args.add_all(["-o", apex_manifest_full_json])
237*7594170eSAndroid Build Coastguard Worker
238*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
239*7594170eSAndroid Build Coastguard Worker        inputs = [apex_manifest_json],
240*7594170eSAndroid Build Coastguard Worker        outputs = [apex_manifest_full_json],
241*7594170eSAndroid Build Coastguard Worker        executable = apex_toolchain.jsonmodify[DefaultInfo].files_to_run,
242*7594170eSAndroid Build Coastguard Worker        arguments = [args],
243*7594170eSAndroid Build Coastguard Worker        mnemonic = "ApexManifestModify",
244*7594170eSAndroid Build Coastguard Worker    )
245*7594170eSAndroid Build Coastguard Worker
246*7594170eSAndroid Build Coastguard Worker    return apex_manifest_full_json
247*7594170eSAndroid Build Coastguard Worker
248*7594170eSAndroid Build Coastguard Worker# conv_apex_manifest - Convert the JSON APEX manifest to protobuf, which is needed by apexer.
249*7594170eSAndroid Build Coastguard Workerdef _convert_apex_manifest_json_to_pb(ctx, apex_toolchain, apex_manifest_json):
250*7594170eSAndroid Build Coastguard Worker    apex_manifest_pb = ctx.actions.declare_file(ctx.attr.name + "_apex_manifest.pb")
251*7594170eSAndroid Build Coastguard Worker
252*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
253*7594170eSAndroid Build Coastguard Worker        outputs = [apex_manifest_pb],
254*7594170eSAndroid Build Coastguard Worker        inputs = [apex_manifest_json],
255*7594170eSAndroid Build Coastguard Worker        executable = apex_toolchain.conv_apex_manifest[DefaultInfo].files_to_run,
256*7594170eSAndroid Build Coastguard Worker        arguments = [
257*7594170eSAndroid Build Coastguard Worker            "proto",
258*7594170eSAndroid Build Coastguard Worker            apex_manifest_json.path,
259*7594170eSAndroid Build Coastguard Worker            "-o",
260*7594170eSAndroid Build Coastguard Worker            apex_manifest_pb.path,
261*7594170eSAndroid Build Coastguard Worker        ],
262*7594170eSAndroid Build Coastguard Worker        mnemonic = "ConvApexManifest",
263*7594170eSAndroid Build Coastguard Worker    )
264*7594170eSAndroid Build Coastguard Worker
265*7594170eSAndroid Build Coastguard Worker    return apex_manifest_pb
266*7594170eSAndroid Build Coastguard Worker
267*7594170eSAndroid Build Coastguard Workerdef _generate_canned_fs_config(ctx, filepaths):
268*7594170eSAndroid Build Coastguard Worker    """Generate filesystem config.
269*7594170eSAndroid Build Coastguard Worker
270*7594170eSAndroid Build Coastguard Worker    This encodes the filemode, uid, and gid of each file in the APEX,
271*7594170eSAndroid Build Coastguard Worker    including apex_manifest.json and apex_manifest.pb.
272*7594170eSAndroid Build Coastguard Worker    NOTE: every file must have an entry.
273*7594170eSAndroid Build Coastguard Worker    """
274*7594170eSAndroid Build Coastguard Worker
275*7594170eSAndroid Build Coastguard Worker    # Ensure all paths don't start with / and are normalized
276*7594170eSAndroid Build Coastguard Worker    filepaths = [paths.normalize(f).lstrip("/") for f in filepaths]
277*7594170eSAndroid Build Coastguard Worker
278*7594170eSAndroid Build Coastguard Worker    # Soong also sorts the config lines to be consistent with bazel
279*7594170eSAndroid Build Coastguard Worker    filepaths = sorted([f for f in filepaths if f])
280*7594170eSAndroid Build Coastguard Worker
281*7594170eSAndroid Build Coastguard Worker    # First, collect a set of all the directories in the apex
282*7594170eSAndroid Build Coastguard Worker    apex_subdirs_set = {}
283*7594170eSAndroid Build Coastguard Worker    for f in filepaths:
284*7594170eSAndroid Build Coastguard Worker        d = paths.dirname(f)
285*7594170eSAndroid Build Coastguard Worker        if d != "":  # The root dir is handled manually below
286*7594170eSAndroid Build Coastguard Worker            # Make sure all the parent dirs of the current subdir are in the set, too
287*7594170eSAndroid Build Coastguard Worker            dirs = d.split("/")
288*7594170eSAndroid Build Coastguard Worker            for i in range(1, len(dirs) + 1):
289*7594170eSAndroid Build Coastguard Worker                apex_subdirs_set["/".join(dirs[:i])] = True
290*7594170eSAndroid Build Coastguard Worker
291*7594170eSAndroid Build Coastguard Worker    config_lines = []
292*7594170eSAndroid Build Coastguard Worker    config_lines.append("/ 1000 1000 0755")
293*7594170eSAndroid Build Coastguard Worker    config_lines.append("/apex_manifest.json 1000 1000 0644")
294*7594170eSAndroid Build Coastguard Worker    config_lines.append("/apex_manifest.pb 1000 1000 0644")
295*7594170eSAndroid Build Coastguard Worker
296*7594170eSAndroid Build Coastguard Worker    # Readonly if not executable. filepaths is already sorted.
297*7594170eSAndroid Build Coastguard Worker    config_lines += ["/" + f + " 1000 1000 0644" for f in filepaths if not f.startswith("bin/")]
298*7594170eSAndroid Build Coastguard Worker
299*7594170eSAndroid Build Coastguard Worker    # Mark all binaries as executable. filepaths is already sorted.
300*7594170eSAndroid Build Coastguard Worker    config_lines += ["/" + f + " 0 2000 0755" for f in filepaths if f.startswith("bin/")]
301*7594170eSAndroid Build Coastguard Worker
302*7594170eSAndroid Build Coastguard Worker    # All directories have the same permission.
303*7594170eSAndroid Build Coastguard Worker    config_lines += ["/" + d + " 0 2000 0755" for d in sorted(apex_subdirs_set.keys())]
304*7594170eSAndroid Build Coastguard Worker
305*7594170eSAndroid Build Coastguard Worker    output = ctx.actions.declare_file(ctx.attr.name + "_canned_fs_config.txt")
306*7594170eSAndroid Build Coastguard Worker
307*7594170eSAndroid Build Coastguard Worker    config_lines = "\n".join(config_lines) + "\n"
308*7594170eSAndroid Build Coastguard Worker    ctx.actions.write(output, config_lines)
309*7594170eSAndroid Build Coastguard Worker
310*7594170eSAndroid Build Coastguard Worker    if ctx.attr.canned_fs_config:
311*7594170eSAndroid Build Coastguard Worker        # Append the custom fs config content to the existing file
312*7594170eSAndroid Build Coastguard Worker        combined_output = ctx.actions.declare_file(ctx.attr.name + "_combined_canned_fs_config.txt")
313*7594170eSAndroid Build Coastguard Worker        ctx.actions.run_shell(
314*7594170eSAndroid Build Coastguard Worker            inputs = [ctx.file.canned_fs_config, output],
315*7594170eSAndroid Build Coastguard Worker            outputs = [combined_output],
316*7594170eSAndroid Build Coastguard Worker            mnemonic = "AppendCustomFsConfig",
317*7594170eSAndroid Build Coastguard Worker            command = "cat {i} {canned_fs_config} > {o}".format(
318*7594170eSAndroid Build Coastguard Worker                i = output.path,
319*7594170eSAndroid Build Coastguard Worker                o = combined_output.path,
320*7594170eSAndroid Build Coastguard Worker                canned_fs_config = ctx.file.canned_fs_config.path,
321*7594170eSAndroid Build Coastguard Worker            ),
322*7594170eSAndroid Build Coastguard Worker        )
323*7594170eSAndroid Build Coastguard Worker        output = combined_output
324*7594170eSAndroid Build Coastguard Worker
325*7594170eSAndroid Build Coastguard Worker    return output
326*7594170eSAndroid Build Coastguard Worker
327*7594170eSAndroid Build Coastguard Worker# Append an entry for apex_manifest.pb to the file_contexts file for this APEX,
328*7594170eSAndroid Build Coastguard Worker# which is either from /system/sepolicy/apex/<apexname>-file_contexts (set in
329*7594170eSAndroid Build Coastguard Worker# the apex macro) or custom file_contexts attribute value of this APEX. This
330*7594170eSAndroid Build Coastguard Worker# ensures that the manifest file is correctly labeled as system_file.
331*7594170eSAndroid Build Coastguard Workerdef _generate_file_contexts(ctx):
332*7594170eSAndroid Build Coastguard Worker    file_contexts = ctx.actions.declare_file(ctx.attr.name + "-file_contexts")
333*7594170eSAndroid Build Coastguard Worker
334*7594170eSAndroid Build Coastguard Worker    ctx.actions.run_shell(
335*7594170eSAndroid Build Coastguard Worker        inputs = [ctx.file.file_contexts],
336*7594170eSAndroid Build Coastguard Worker        outputs = [file_contexts],
337*7594170eSAndroid Build Coastguard Worker        mnemonic = "GenerateApexFileContexts",
338*7594170eSAndroid Build Coastguard Worker        command = "cat {i} > {o} && echo >> {o} && echo /apex_manifest\\\\.pb u:object_r:system_file:s0 >> {o} && echo / u:object_r:system_file:s0 >> {o}"
339*7594170eSAndroid Build Coastguard Worker            .format(i = ctx.file.file_contexts.path, o = file_contexts.path),
340*7594170eSAndroid Build Coastguard Worker    )
341*7594170eSAndroid Build Coastguard Worker
342*7594170eSAndroid Build Coastguard Worker    return file_contexts
343*7594170eSAndroid Build Coastguard Worker
344*7594170eSAndroid Build Coastguard Workerdef _mark_manifest_as_test_only(ctx, apex_toolchain):
345*7594170eSAndroid Build Coastguard Worker    android_manifest = ctx.file.android_manifest
346*7594170eSAndroid Build Coastguard Worker    dir_name = android_manifest.dirname
347*7594170eSAndroid Build Coastguard Worker    base_name = android_manifest.basename
348*7594170eSAndroid Build Coastguard Worker    android_manifest_fixed = ctx.actions.declare_file(paths.join(dir_name, "manifest_fixer", base_name))
349*7594170eSAndroid Build Coastguard Worker    manifest_fixer.fix(
350*7594170eSAndroid Build Coastguard Worker        ctx,
351*7594170eSAndroid Build Coastguard Worker        manifest_fixer = apex_toolchain.manifest_fixer[DefaultInfo].files_to_run,
352*7594170eSAndroid Build Coastguard Worker        in_manifest = android_manifest,
353*7594170eSAndroid Build Coastguard Worker        out_manifest = android_manifest_fixed,
354*7594170eSAndroid Build Coastguard Worker        mnemonic = "MarkAndroidManifestTestOnly",
355*7594170eSAndroid Build Coastguard Worker        test_only = True,
356*7594170eSAndroid Build Coastguard Worker    )
357*7594170eSAndroid Build Coastguard Worker    return android_manifest_fixed
358*7594170eSAndroid Build Coastguard Worker
359*7594170eSAndroid Build Coastguard Worker# Generate <APEX>_backing.txt file which lists all libraries used by the APEX.
360*7594170eSAndroid Build Coastguard Workerdef _generate_apex_backing_file(ctx, backing_libs):
361*7594170eSAndroid Build Coastguard Worker    backing_file = ctx.actions.declare_file(ctx.attr.name + "_backing.txt")
362*7594170eSAndroid Build Coastguard Worker    ctx.actions.write(
363*7594170eSAndroid Build Coastguard Worker        output = backing_file,
364*7594170eSAndroid Build Coastguard Worker        content = " ".join(backing_libs) + "\n",
365*7594170eSAndroid Build Coastguard Worker    )
366*7594170eSAndroid Build Coastguard Worker    return backing_file
367*7594170eSAndroid Build Coastguard Worker
368*7594170eSAndroid Build Coastguard Worker# Generate installed-files.txt which lists all installed files by the APEX.
369*7594170eSAndroid Build Coastguard Workerdef _generate_installed_files_list(ctx, file_mapping):
370*7594170eSAndroid Build Coastguard Worker    installed_files = ctx.actions.declare_file(ctx.attr.name + "-installed-files.txt")
371*7594170eSAndroid Build Coastguard Worker    command = []
372*7594170eSAndroid Build Coastguard Worker    for device_path, bazel_file in file_mapping.items():
373*7594170eSAndroid Build Coastguard Worker        command.append("echo $(stat -L -c %%s %s) ./%s" % (bazel_file.path, device_path))
374*7594170eSAndroid Build Coastguard Worker    ctx.actions.run_shell(
375*7594170eSAndroid Build Coastguard Worker        inputs = file_mapping.values(),
376*7594170eSAndroid Build Coastguard Worker        outputs = [installed_files],
377*7594170eSAndroid Build Coastguard Worker        mnemonic = "GenerateApexInstalledFileList",
378*7594170eSAndroid Build Coastguard Worker        command = "(" + "; ".join(command) + ") | sort -nr > " + installed_files.path,
379*7594170eSAndroid Build Coastguard Worker    )
380*7594170eSAndroid Build Coastguard Worker    return installed_files
381*7594170eSAndroid Build Coastguard Worker
382*7594170eSAndroid Build Coastguard Workerdef _generate_notices(ctx, apex_toolchain):
383*7594170eSAndroid Build Coastguard Worker    licensees = license_map(ctx.attr.binaries + ctx.attr.prebuilts + ctx.attr.native_shared_libs_32 + ctx.attr.native_shared_libs_64)
384*7594170eSAndroid Build Coastguard Worker    licenses_file = ctx.actions.declare_file(ctx.attr.name + "_licenses.json")
385*7594170eSAndroid Build Coastguard Worker    ctx.actions.write(licenses_file, "[\n%s\n]\n" % ",\n".join(license_map_to_json(licensees)))
386*7594170eSAndroid Build Coastguard Worker
387*7594170eSAndroid Build Coastguard Worker    # Run HTML notice file generator.
388*7594170eSAndroid Build Coastguard Worker    notice_file = ctx.actions.declare_file(ctx.attr.name + "_notice_dir/NOTICE.html.gz")
389*7594170eSAndroid Build Coastguard Worker    notice_generator = apex_toolchain.notice_generator[DefaultInfo].files_to_run
390*7594170eSAndroid Build Coastguard Worker
391*7594170eSAndroid Build Coastguard Worker    args = ctx.actions.args()
392*7594170eSAndroid Build Coastguard Worker    args.add_all(["-o", notice_file, licenses_file])
393*7594170eSAndroid Build Coastguard Worker
394*7594170eSAndroid Build Coastguard Worker    # TODO(asmundak): should we extend it with license info for self
395*7594170eSAndroid Build Coastguard Worker    # (the case when APEX itself has applicable_licenses attribute)?
396*7594170eSAndroid Build Coastguard Worker    inputs = license_map_notice_files(licensees) + [licenses_file]
397*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
398*7594170eSAndroid Build Coastguard Worker        mnemonic = "GenerateNoticeFile",
399*7594170eSAndroid Build Coastguard Worker        inputs = inputs,
400*7594170eSAndroid Build Coastguard Worker        outputs = [notice_file],
401*7594170eSAndroid Build Coastguard Worker        executable = notice_generator,
402*7594170eSAndroid Build Coastguard Worker        tools = [notice_generator],
403*7594170eSAndroid Build Coastguard Worker        arguments = [args],
404*7594170eSAndroid Build Coastguard Worker    )
405*7594170eSAndroid Build Coastguard Worker    return notice_file
406*7594170eSAndroid Build Coastguard Worker
407*7594170eSAndroid Build Coastguard Workerdef _use_api_fingerprint(ctx):
408*7594170eSAndroid Build Coastguard Worker    if not ctx.attr._unbundled_build[BuildSettingInfo].value:
409*7594170eSAndroid Build Coastguard Worker        return False
410*7594170eSAndroid Build Coastguard Worker    if ctx.attr._always_use_prebuilt_sdks[BuildSettingInfo].value:
411*7594170eSAndroid Build Coastguard Worker        return False
412*7594170eSAndroid Build Coastguard Worker    if not ctx.attr._unbundled_build_target_sdk_with_api_fingerprint[BuildSettingInfo].value:
413*7594170eSAndroid Build Coastguard Worker        return False
414*7594170eSAndroid Build Coastguard Worker    return True
415*7594170eSAndroid Build Coastguard Worker
416*7594170eSAndroid Build Coastguard Worker# apexer - generate the APEX file.
417*7594170eSAndroid Build Coastguard Workerdef _run_apexer(ctx, apex_toolchain):
418*7594170eSAndroid Build Coastguard Worker    # Inputs
419*7594170eSAndroid Build Coastguard Worker    apex_key_info = ctx.attr.key[ApexKeyInfo]
420*7594170eSAndroid Build Coastguard Worker    privkey = apex_key_info.private_key
421*7594170eSAndroid Build Coastguard Worker    pubkey = apex_key_info.public_key
422*7594170eSAndroid Build Coastguard Worker    android_jar = apex_toolchain.android_jar
423*7594170eSAndroid Build Coastguard Worker
424*7594170eSAndroid Build Coastguard Worker    file_mapping, requires_native_libs, provides_native_libs, backing_libs, make_modules_to_install, make_files_info, metadata_file_mapping = _create_file_mapping(ctx)
425*7594170eSAndroid Build Coastguard Worker    canned_fs_config = _generate_canned_fs_config(ctx, file_mapping.keys())
426*7594170eSAndroid Build Coastguard Worker    file_contexts = _generate_file_contexts(ctx)
427*7594170eSAndroid Build Coastguard Worker    full_apex_manifest_json = _add_apex_manifest_information(ctx, apex_toolchain, requires_native_libs, provides_native_libs)
428*7594170eSAndroid Build Coastguard Worker    apex_manifest_pb = _convert_apex_manifest_json_to_pb(ctx, apex_toolchain, full_apex_manifest_json)
429*7594170eSAndroid Build Coastguard Worker    notices_file = _generate_notices(ctx, apex_toolchain)
430*7594170eSAndroid Build Coastguard Worker    api_fingerprint_file = None
431*7594170eSAndroid Build Coastguard Worker
432*7594170eSAndroid Build Coastguard Worker    staging_dir_builder_options_file = ctx.actions.declare_file(ctx.attr.name + "_staging_dir_builder_options.json")
433*7594170eSAndroid Build Coastguard Worker    ctx.actions.write(staging_dir_builder_options_file, json.encode({
434*7594170eSAndroid Build Coastguard Worker        "file_mapping": {k: v.path for k, v in file_mapping.items()},
435*7594170eSAndroid Build Coastguard Worker    }))
436*7594170eSAndroid Build Coastguard Worker
437*7594170eSAndroid Build Coastguard Worker    # Outputs
438*7594170eSAndroid Build Coastguard Worker    apex_output_file = ctx.actions.declare_file(ctx.attr.name + ".apex.unsigned")
439*7594170eSAndroid Build Coastguard Worker
440*7594170eSAndroid Build Coastguard Worker    apexer_files = apex_toolchain.apexer[DefaultInfo].files_to_run
441*7594170eSAndroid Build Coastguard Worker
442*7594170eSAndroid Build Coastguard Worker    # Arguments
443*7594170eSAndroid Build Coastguard Worker    command = [ctx.executable._staging_dir_builder.path, staging_dir_builder_options_file.path]
444*7594170eSAndroid Build Coastguard Worker
445*7594170eSAndroid Build Coastguard Worker    # start of apexer cmd
446*7594170eSAndroid Build Coastguard Worker    command.append(apexer_files.executable.path)
447*7594170eSAndroid Build Coastguard Worker
448*7594170eSAndroid Build Coastguard Worker    command.append("--force")
449*7594170eSAndroid Build Coastguard Worker    command.append("--include_build_info")
450*7594170eSAndroid Build Coastguard Worker    command.extend(["--canned_fs_config", canned_fs_config.path])
451*7594170eSAndroid Build Coastguard Worker    command.extend(["--manifest", apex_manifest_pb.path])
452*7594170eSAndroid Build Coastguard Worker    command.extend(["--file_contexts", file_contexts.path])
453*7594170eSAndroid Build Coastguard Worker    command.extend(["--key", privkey.path])
454*7594170eSAndroid Build Coastguard Worker    command.extend(["--pubkey", pubkey.path])
455*7594170eSAndroid Build Coastguard Worker    command.extend(["--payload_type", "image"])
456*7594170eSAndroid Build Coastguard Worker    command.extend(["--payload_fs_type", "ext4"])
457*7594170eSAndroid Build Coastguard Worker    command.extend(["--assets_dir", notices_file.dirname])
458*7594170eSAndroid Build Coastguard Worker
459*7594170eSAndroid Build Coastguard Worker    # Override the package name, if it's expicitly specified
460*7594170eSAndroid Build Coastguard Worker    if ctx.attr.package_name:
461*7594170eSAndroid Build Coastguard Worker        command.extend(["--override_apk_package_name", ctx.attr.package_name])
462*7594170eSAndroid Build Coastguard Worker    else:
463*7594170eSAndroid Build Coastguard Worker        override_package_name = _override_manifest_package_name(ctx)
464*7594170eSAndroid Build Coastguard Worker        if override_package_name:
465*7594170eSAndroid Build Coastguard Worker            command.extend(["--override_apk_package_name", override_package_name])
466*7594170eSAndroid Build Coastguard Worker
467*7594170eSAndroid Build Coastguard Worker    if ctx.attr.logging_parent:
468*7594170eSAndroid Build Coastguard Worker        command.extend(["--logging_parent", ctx.attr.logging_parent])
469*7594170eSAndroid Build Coastguard Worker
470*7594170eSAndroid Build Coastguard Worker    use_api_fingerprint = _use_api_fingerprint(ctx)
471*7594170eSAndroid Build Coastguard Worker
472*7594170eSAndroid Build Coastguard Worker    target_sdk_version = str(api.final_or_future(api.default_app_target_sdk()))
473*7594170eSAndroid Build Coastguard Worker    if use_api_fingerprint:
474*7594170eSAndroid Build Coastguard Worker        api_fingerprint_file = ctx.file._api_fingerprint_txt
475*7594170eSAndroid Build Coastguard Worker        sdk_version_suffix = ".$(cat {})".format(api_fingerprint_file.path)
476*7594170eSAndroid Build Coastguard Worker        target_sdk_version = ctx.attr._platform_sdk_codename[BuildSettingInfo].value + sdk_version_suffix
477*7594170eSAndroid Build Coastguard Worker
478*7594170eSAndroid Build Coastguard Worker    command.extend(["--target_sdk_version", target_sdk_version])
479*7594170eSAndroid Build Coastguard Worker
480*7594170eSAndroid Build Coastguard Worker    # TODO(b/215339575): This is a super rudimentary way to convert "current" to a numerical number.
481*7594170eSAndroid Build Coastguard Worker    # Generalize this to API level handling logic in a separate Starlark utility, preferably using
482*7594170eSAndroid Build Coastguard Worker    # API level maps dumped from api_levels.go
483*7594170eSAndroid Build Coastguard Worker    min_sdk_version = ctx.attr.min_sdk_version
484*7594170eSAndroid Build Coastguard Worker    if min_sdk_version == "current":
485*7594170eSAndroid Build Coastguard Worker        min_sdk_version = "10000"
486*7594170eSAndroid Build Coastguard Worker
487*7594170eSAndroid Build Coastguard Worker    override_min_sdk_version = ctx.attr._apex_global_min_sdk_version_override[BuildSettingInfo].value
488*7594170eSAndroid Build Coastguard Worker    min_sdk_version = str(maybe_override_min_sdk_version(min_sdk_version, override_min_sdk_version))
489*7594170eSAndroid Build Coastguard Worker
490*7594170eSAndroid Build Coastguard Worker    if min_sdk_version == "10000" and use_api_fingerprint:
491*7594170eSAndroid Build Coastguard Worker        min_sdk_version = ctx.attr._platform_sdk_codename[BuildSettingInfo].value + sdk_version_suffix
492*7594170eSAndroid Build Coastguard Worker        command.append(api_fingerprint_file.path)
493*7594170eSAndroid Build Coastguard Worker    command.extend(["--min_sdk_version", min_sdk_version])
494*7594170eSAndroid Build Coastguard Worker
495*7594170eSAndroid Build Coastguard Worker    # apexer needs the list of directories containing all auxilliary tools invoked during
496*7594170eSAndroid Build Coastguard Worker    # the creation of an apex
497*7594170eSAndroid Build Coastguard Worker    avbtool_files = apex_toolchain.avbtool[DefaultInfo].files_to_run
498*7594170eSAndroid Build Coastguard Worker    e2fsdroid_files = apex_toolchain.e2fsdroid[DefaultInfo].files_to_run
499*7594170eSAndroid Build Coastguard Worker    mke2fs_files = apex_toolchain.mke2fs[DefaultInfo].files_to_run
500*7594170eSAndroid Build Coastguard Worker    resize2fs_files = apex_toolchain.resize2fs[DefaultInfo].files_to_run
501*7594170eSAndroid Build Coastguard Worker    sefcontext_compile_files = apex_toolchain.sefcontext_compile[DefaultInfo].files_to_run
502*7594170eSAndroid Build Coastguard Worker    staging_dir_builder_files = ctx.attr._staging_dir_builder[DefaultInfo].files_to_run
503*7594170eSAndroid Build Coastguard Worker    apexer_tool_paths = [
504*7594170eSAndroid Build Coastguard Worker        apex_toolchain.aapt2.dirname,
505*7594170eSAndroid Build Coastguard Worker        apexer_files.executable.dirname,
506*7594170eSAndroid Build Coastguard Worker        avbtool_files.executable.dirname,
507*7594170eSAndroid Build Coastguard Worker        e2fsdroid_files.executable.dirname,
508*7594170eSAndroid Build Coastguard Worker        mke2fs_files.executable.dirname,
509*7594170eSAndroid Build Coastguard Worker        resize2fs_files.executable.dirname,
510*7594170eSAndroid Build Coastguard Worker        sefcontext_compile_files.executable.dirname,
511*7594170eSAndroid Build Coastguard Worker    ]
512*7594170eSAndroid Build Coastguard Worker
513*7594170eSAndroid Build Coastguard Worker    command.extend(["--apexer_tool_path", ":".join(apexer_tool_paths)])
514*7594170eSAndroid Build Coastguard Worker
515*7594170eSAndroid Build Coastguard Worker    android_manifest = ctx.file.android_manifest
516*7594170eSAndroid Build Coastguard Worker    if android_manifest != None:
517*7594170eSAndroid Build Coastguard Worker        if ctx.attr.testonly:
518*7594170eSAndroid Build Coastguard Worker            android_manifest = _mark_manifest_as_test_only(ctx, apex_toolchain)
519*7594170eSAndroid Build Coastguard Worker        command.extend(["--android_manifest", android_manifest.path])
520*7594170eSAndroid Build Coastguard Worker    elif ctx.attr.testonly:
521*7594170eSAndroid Build Coastguard Worker        command.append("--test_only")
522*7594170eSAndroid Build Coastguard Worker
523*7594170eSAndroid Build Coastguard Worker    command.append("STAGING_DIR_PLACEHOLDER")
524*7594170eSAndroid Build Coastguard Worker    command.append(apex_output_file.path)
525*7594170eSAndroid Build Coastguard Worker
526*7594170eSAndroid Build Coastguard Worker    inputs = [
527*7594170eSAndroid Build Coastguard Worker        ctx.executable._staging_dir_builder,
528*7594170eSAndroid Build Coastguard Worker        staging_dir_builder_options_file,
529*7594170eSAndroid Build Coastguard Worker        canned_fs_config,
530*7594170eSAndroid Build Coastguard Worker        apex_manifest_pb,
531*7594170eSAndroid Build Coastguard Worker        file_contexts,
532*7594170eSAndroid Build Coastguard Worker        notices_file,
533*7594170eSAndroid Build Coastguard Worker        privkey,
534*7594170eSAndroid Build Coastguard Worker        pubkey,
535*7594170eSAndroid Build Coastguard Worker        android_jar,
536*7594170eSAndroid Build Coastguard Worker    ] + file_mapping.values()
537*7594170eSAndroid Build Coastguard Worker    if use_api_fingerprint:
538*7594170eSAndroid Build Coastguard Worker        inputs.append(api_fingerprint_file)
539*7594170eSAndroid Build Coastguard Worker
540*7594170eSAndroid Build Coastguard Worker    if android_manifest != None:
541*7594170eSAndroid Build Coastguard Worker        inputs.append(android_manifest)
542*7594170eSAndroid Build Coastguard Worker
543*7594170eSAndroid Build Coastguard Worker    # This is run_shell instead of run because --target_sdk_version may
544*7594170eSAndroid Build Coastguard Worker    # use the API fingerprinting file contents using bash expansion,
545*7594170eSAndroid Build Coastguard Worker    # and only run_shell can support that by executing the whole command with
546*7594170eSAndroid Build Coastguard Worker    # /bin/bash -c. Regular run would quote the --target_sdk_version value with
547*7594170eSAndroid Build Coastguard Worker    # single quotes ('--target_sdk_version=ABC.$(cat version.txt)'), preventing
548*7594170eSAndroid Build Coastguard Worker    # bash expansion.
549*7594170eSAndroid Build Coastguard Worker    ctx.actions.run_shell(
550*7594170eSAndroid Build Coastguard Worker        inputs = inputs,
551*7594170eSAndroid Build Coastguard Worker        tools = [
552*7594170eSAndroid Build Coastguard Worker            apexer_files,
553*7594170eSAndroid Build Coastguard Worker            avbtool_files,
554*7594170eSAndroid Build Coastguard Worker            e2fsdroid_files,
555*7594170eSAndroid Build Coastguard Worker            mke2fs_files,
556*7594170eSAndroid Build Coastguard Worker            resize2fs_files,
557*7594170eSAndroid Build Coastguard Worker            sefcontext_compile_files,
558*7594170eSAndroid Build Coastguard Worker            apex_toolchain.aapt2,
559*7594170eSAndroid Build Coastguard Worker            staging_dir_builder_files,
560*7594170eSAndroid Build Coastguard Worker        ],
561*7594170eSAndroid Build Coastguard Worker        outputs = [apex_output_file],
562*7594170eSAndroid Build Coastguard Worker        command = " ".join(command),
563*7594170eSAndroid Build Coastguard Worker        mnemonic = "Apexer",
564*7594170eSAndroid Build Coastguard Worker    )
565*7594170eSAndroid Build Coastguard Worker    return struct(
566*7594170eSAndroid Build Coastguard Worker        unsigned_apex = apex_output_file,
567*7594170eSAndroid Build Coastguard Worker        requires_native_libs = requires_native_libs,
568*7594170eSAndroid Build Coastguard Worker        provides_native_libs = provides_native_libs,
569*7594170eSAndroid Build Coastguard Worker        backing_libs = _generate_apex_backing_file(ctx, backing_libs),
570*7594170eSAndroid Build Coastguard Worker        symbols_used_by_apex = _generate_symbols_used_by_apex(ctx, apex_toolchain, file_mapping),
571*7594170eSAndroid Build Coastguard Worker        java_symbols_used_by_apex = _generate_java_symbols_used_by_apex(ctx, apex_toolchain),
572*7594170eSAndroid Build Coastguard Worker        installed_files = _generate_installed_files_list(ctx, file_mapping),
573*7594170eSAndroid Build Coastguard Worker        make_modules_to_install = make_modules_to_install,
574*7594170eSAndroid Build Coastguard Worker        make_files_info = make_files_info,
575*7594170eSAndroid Build Coastguard Worker        file_mapping = file_mapping,
576*7594170eSAndroid Build Coastguard Worker        metadata_file_mapping = metadata_file_mapping,
577*7594170eSAndroid Build Coastguard Worker    )
578*7594170eSAndroid Build Coastguard Worker
579*7594170eSAndroid Build Coastguard Workerdef _run_signapk(ctx, unsigned_file, signed_file, private_key, public_key, mnemonic):
580*7594170eSAndroid Build Coastguard Worker    """Sign a file with signapk."""
581*7594170eSAndroid Build Coastguard Worker
582*7594170eSAndroid Build Coastguard Worker    # Arguments
583*7594170eSAndroid Build Coastguard Worker    args = ctx.actions.args()
584*7594170eSAndroid Build Coastguard Worker    args.add_all(["-a", 4096])
585*7594170eSAndroid Build Coastguard Worker    args.add_all(["--align-file-size"])
586*7594170eSAndroid Build Coastguard Worker    args.add_all([public_key, private_key])
587*7594170eSAndroid Build Coastguard Worker    args.add_all([unsigned_file, signed_file])
588*7594170eSAndroid Build Coastguard Worker
589*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
590*7594170eSAndroid Build Coastguard Worker        inputs = [
591*7594170eSAndroid Build Coastguard Worker            unsigned_file,
592*7594170eSAndroid Build Coastguard Worker            private_key,
593*7594170eSAndroid Build Coastguard Worker            public_key,
594*7594170eSAndroid Build Coastguard Worker            ctx.executable._signapk,
595*7594170eSAndroid Build Coastguard Worker        ],
596*7594170eSAndroid Build Coastguard Worker        outputs = [signed_file],
597*7594170eSAndroid Build Coastguard Worker        executable = ctx.executable._signapk,
598*7594170eSAndroid Build Coastguard Worker        arguments = [args],
599*7594170eSAndroid Build Coastguard Worker        mnemonic = mnemonic,
600*7594170eSAndroid Build Coastguard Worker    )
601*7594170eSAndroid Build Coastguard Worker
602*7594170eSAndroid Build Coastguard Worker    return signed_file
603*7594170eSAndroid Build Coastguard Worker
604*7594170eSAndroid Build Coastguard Worker# See also getOverrideManifestPackageName
605*7594170eSAndroid Build Coastguard Worker# https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/builder.go;l=1000;drc=241e738c7156d928e9a993b15993cb3297face45
606*7594170eSAndroid Build Coastguard Workerdef _override_manifest_package_name(ctx):
607*7594170eSAndroid Build Coastguard Worker    apex_name = ctx.attr.name
608*7594170eSAndroid Build Coastguard Worker    overrides = ctx.attr._manifest_package_name_overrides[BuildSettingInfo].value
609*7594170eSAndroid Build Coastguard Worker    if not overrides:
610*7594170eSAndroid Build Coastguard Worker        return None
611*7594170eSAndroid Build Coastguard Worker
612*7594170eSAndroid Build Coastguard Worker    matches = [o for o in overrides if o.split(":")[0] == apex_name]
613*7594170eSAndroid Build Coastguard Worker
614*7594170eSAndroid Build Coastguard Worker    if not matches:
615*7594170eSAndroid Build Coastguard Worker        return None
616*7594170eSAndroid Build Coastguard Worker
617*7594170eSAndroid Build Coastguard Worker    if len(matches) > 1:
618*7594170eSAndroid Build Coastguard Worker        fail("unexpected multiple manifest package overrides for %s, %s" % (apex_name, matches))
619*7594170eSAndroid Build Coastguard Worker
620*7594170eSAndroid Build Coastguard Worker    return matches[0].split(":")[1]
621*7594170eSAndroid Build Coastguard Worker
622*7594170eSAndroid Build Coastguard Worker# https://cs.android.com/android/platform/superproject/+/master:build/soong/android/config.go;drc=5ca657189aac546af0aafaba11bbc9c5d889eab3;l=1501
623*7594170eSAndroid Build Coastguard Worker# In Soong, we don't check whether the current apex is part of Unbundled_apps.
624*7594170eSAndroid Build Coastguard Worker# Hence, we might simplify the logic by just checking product_vars["Unbundled_build"]
625*7594170eSAndroid Build Coastguard Worker# TODO(b/271474456): Eventually we might default to unbundled mode in bazel-only mode
626*7594170eSAndroid Build Coastguard Worker# so that we don't need to check Unbundled_apps.
627*7594170eSAndroid Build Coastguard Workerdef _compression_enabled(ctx):
628*7594170eSAndroid Build Coastguard Worker    compressed_apex = ctx.attr._compressed_apex[BuildSettingInfo].value
629*7594170eSAndroid Build Coastguard Worker    unbundled_apps = ctx.attr._unbundled_build_apps[BuildSettingInfo].value
630*7594170eSAndroid Build Coastguard Worker
631*7594170eSAndroid Build Coastguard Worker    return compressed_apex and len(unbundled_apps) == 0
632*7594170eSAndroid Build Coastguard Worker
633*7594170eSAndroid Build Coastguard Worker# Compress a file with apex_compression_tool.
634*7594170eSAndroid Build Coastguard Workerdef _run_apex_compression_tool(ctx, apex_toolchain, input_file, output_file_name):
635*7594170eSAndroid Build Coastguard Worker    avbtool_files = apex_toolchain.avbtool[DefaultInfo].files_to_run
636*7594170eSAndroid Build Coastguard Worker    apex_compression_tool_files = apex_toolchain.apex_compression_tool[DefaultInfo].files_to_run
637*7594170eSAndroid Build Coastguard Worker
638*7594170eSAndroid Build Coastguard Worker    # Outputs
639*7594170eSAndroid Build Coastguard Worker    compressed_file = ctx.actions.declare_file(output_file_name)
640*7594170eSAndroid Build Coastguard Worker
641*7594170eSAndroid Build Coastguard Worker    # Arguments
642*7594170eSAndroid Build Coastguard Worker    args = ctx.actions.args()
643*7594170eSAndroid Build Coastguard Worker    args.add_all(["compress"])
644*7594170eSAndroid Build Coastguard Worker    tool_dirs = [apex_toolchain.soong_zip.dirname, avbtool_files.executable.dirname]
645*7594170eSAndroid Build Coastguard Worker    args.add_all(["--apex_compression_tool", ":".join(tool_dirs)])
646*7594170eSAndroid Build Coastguard Worker    args.add_all(["--input", input_file])
647*7594170eSAndroid Build Coastguard Worker    args.add_all(["--output", compressed_file])
648*7594170eSAndroid Build Coastguard Worker
649*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
650*7594170eSAndroid Build Coastguard Worker        inputs = [input_file],
651*7594170eSAndroid Build Coastguard Worker        tools = [
652*7594170eSAndroid Build Coastguard Worker            avbtool_files,
653*7594170eSAndroid Build Coastguard Worker            apex_compression_tool_files,
654*7594170eSAndroid Build Coastguard Worker            apex_toolchain.soong_zip,
655*7594170eSAndroid Build Coastguard Worker        ],
656*7594170eSAndroid Build Coastguard Worker        outputs = [compressed_file],
657*7594170eSAndroid Build Coastguard Worker        executable = apex_compression_tool_files,
658*7594170eSAndroid Build Coastguard Worker        arguments = [args],
659*7594170eSAndroid Build Coastguard Worker        mnemonic = "BazelApexCompressing",
660*7594170eSAndroid Build Coastguard Worker    )
661*7594170eSAndroid Build Coastguard Worker    return compressed_file
662*7594170eSAndroid Build Coastguard Worker
663*7594170eSAndroid Build Coastguard Worker# Generate <module>_using.txt, which contains a list of versioned NDK symbols
664*7594170eSAndroid Build Coastguard Worker# dynamically linked to by this APEX's contents. This is used for coverage
665*7594170eSAndroid Build Coastguard Worker# checks.
666*7594170eSAndroid Build Coastguard Workerdef _generate_symbols_used_by_apex(ctx, apex_toolchain, file_mapping):
667*7594170eSAndroid Build Coastguard Worker    staging_dir_builder_options_file = ctx.actions.declare_file(ctx.attr.name + "_generate_symbols_used_by_apex_staging_dir_builder_options.json")
668*7594170eSAndroid Build Coastguard Worker    ctx.actions.write(staging_dir_builder_options_file, json.encode({
669*7594170eSAndroid Build Coastguard Worker        "file_mapping": {k: v.path for k, v in file_mapping.items()},
670*7594170eSAndroid Build Coastguard Worker    }))
671*7594170eSAndroid Build Coastguard Worker    symbols_used_by_apex = ctx.actions.declare_file(ctx.attr.name + "_using.txt")
672*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
673*7594170eSAndroid Build Coastguard Worker        outputs = [symbols_used_by_apex],
674*7594170eSAndroid Build Coastguard Worker        inputs = [staging_dir_builder_options_file] + file_mapping.values(),
675*7594170eSAndroid Build Coastguard Worker        tools = [
676*7594170eSAndroid Build Coastguard Worker            apex_toolchain.readelf.files_to_run,
677*7594170eSAndroid Build Coastguard Worker            apex_toolchain.gen_ndk_usedby_apex.files_to_run,
678*7594170eSAndroid Build Coastguard Worker        ],
679*7594170eSAndroid Build Coastguard Worker        executable = ctx.executable._staging_dir_builder,
680*7594170eSAndroid Build Coastguard Worker        arguments = [
681*7594170eSAndroid Build Coastguard Worker            staging_dir_builder_options_file.path,
682*7594170eSAndroid Build Coastguard Worker            apex_toolchain.gen_ndk_usedby_apex.files_to_run.executable.path,
683*7594170eSAndroid Build Coastguard Worker            "STAGING_DIR_PLACEHOLDER",
684*7594170eSAndroid Build Coastguard Worker            apex_toolchain.readelf.files_to_run.executable.path,
685*7594170eSAndroid Build Coastguard Worker            symbols_used_by_apex.path,
686*7594170eSAndroid Build Coastguard Worker        ],
687*7594170eSAndroid Build Coastguard Worker        progress_message = "Generating dynamic NDK symbol list used by the %s apex" % ctx.attr.name,
688*7594170eSAndroid Build Coastguard Worker        mnemonic = "ApexUsingNDKSymbolsForCoverage",
689*7594170eSAndroid Build Coastguard Worker    )
690*7594170eSAndroid Build Coastguard Worker    return symbols_used_by_apex
691*7594170eSAndroid Build Coastguard Worker
692*7594170eSAndroid Build Coastguard Worker# Generate <module>_using.xml, which contains a list of java API metadata used
693*7594170eSAndroid Build Coastguard Worker# by this APEX's contents. This is used for coverage checks.
694*7594170eSAndroid Build Coastguard Worker#
695*7594170eSAndroid Build Coastguard Worker# TODO(b/257954111): Add JARs and APKs as inputs to this action when we start
696*7594170eSAndroid Build Coastguard Worker# building Java mainline modules.
697*7594170eSAndroid Build Coastguard Workerdef _generate_java_symbols_used_by_apex(ctx, apex_toolchain):
698*7594170eSAndroid Build Coastguard Worker    java_symbols_used_by_apex = ctx.actions.declare_file(ctx.attr.name + "_using.xml")
699*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
700*7594170eSAndroid Build Coastguard Worker        outputs = [java_symbols_used_by_apex],
701*7594170eSAndroid Build Coastguard Worker        inputs = [],
702*7594170eSAndroid Build Coastguard Worker        tools = [
703*7594170eSAndroid Build Coastguard Worker            apex_toolchain.dexdeps.files_to_run,
704*7594170eSAndroid Build Coastguard Worker            apex_toolchain.gen_java_usedby_apex.files_to_run,
705*7594170eSAndroid Build Coastguard Worker        ],
706*7594170eSAndroid Build Coastguard Worker        executable = apex_toolchain.gen_java_usedby_apex.files_to_run,
707*7594170eSAndroid Build Coastguard Worker        arguments = [
708*7594170eSAndroid Build Coastguard Worker            apex_toolchain.dexdeps.files_to_run.executable.path,
709*7594170eSAndroid Build Coastguard Worker            java_symbols_used_by_apex.path,
710*7594170eSAndroid Build Coastguard Worker        ],
711*7594170eSAndroid Build Coastguard Worker        progress_message = "Generating Java symbol list used by the %s apex" % ctx.attr.name,
712*7594170eSAndroid Build Coastguard Worker        mnemonic = "ApexUsingJavaSymbolsForCoverage",
713*7594170eSAndroid Build Coastguard Worker    )
714*7594170eSAndroid Build Coastguard Worker    return java_symbols_used_by_apex
715*7594170eSAndroid Build Coastguard Worker
716*7594170eSAndroid Build Coastguard Workerdef _validate_apex_deps(ctx):
717*7594170eSAndroid Build Coastguard Worker    transitive_deps = depset(
718*7594170eSAndroid Build Coastguard Worker        transitive = [
719*7594170eSAndroid Build Coastguard Worker            d[ApexDepsInfo].transitive_deps
720*7594170eSAndroid Build Coastguard Worker            for d in (
721*7594170eSAndroid Build Coastguard Worker                ctx.attr.native_shared_libs_32 +
722*7594170eSAndroid Build Coastguard Worker                ctx.attr.native_shared_libs_64 +
723*7594170eSAndroid Build Coastguard Worker                ctx.attr.binaries +
724*7594170eSAndroid Build Coastguard Worker                ctx.attr.prebuilts
725*7594170eSAndroid Build Coastguard Worker            )
726*7594170eSAndroid Build Coastguard Worker        ],
727*7594170eSAndroid Build Coastguard Worker    )
728*7594170eSAndroid Build Coastguard Worker    validation_files = []
729*7594170eSAndroid Build Coastguard Worker    if not ctx.attr._unsafe_disable_apex_allowed_deps_check[BuildSettingInfo].value:
730*7594170eSAndroid Build Coastguard Worker        validation_files.append(validate_apex_deps(ctx, transitive_deps, ctx.file.allowed_apex_deps_manifest))
731*7594170eSAndroid Build Coastguard Worker
732*7594170eSAndroid Build Coastguard Worker    transitive_unvalidated_targets = []
733*7594170eSAndroid Build Coastguard Worker    transitive_invalid_targets = []
734*7594170eSAndroid Build Coastguard Worker    for _, attr_deps in get_dep_targets(ctx.attr, predicate = lambda target: ApexAvailableInfo in target).items():
735*7594170eSAndroid Build Coastguard Worker        for dep in attr_deps:
736*7594170eSAndroid Build Coastguard Worker            transitive_unvalidated_targets.append(dep[ApexAvailableInfo].transitive_unvalidated_targets)
737*7594170eSAndroid Build Coastguard Worker            transitive_invalid_targets.append(dep[ApexAvailableInfo].transitive_invalid_targets)
738*7594170eSAndroid Build Coastguard Worker
739*7594170eSAndroid Build Coastguard Worker    invalid_targets = depset(transitive = transitive_invalid_targets).to_list()
740*7594170eSAndroid Build Coastguard Worker    if len(invalid_targets) > 0:
741*7594170eSAndroid Build Coastguard Worker        invalid_targets_msg = "\n    ".join([
742*7594170eSAndroid Build Coastguard Worker            "{label}; apex_available tags: {tags}".format(label = target.label, tags = list(apex_available_tags))
743*7594170eSAndroid Build Coastguard Worker            for target, apex_available_tags in invalid_targets
744*7594170eSAndroid Build Coastguard Worker        ])
745*7594170eSAndroid Build Coastguard Worker        msg = ("`{apex_name}` apex has transitive dependencies that do not include the apex in " +
746*7594170eSAndroid Build Coastguard Worker               "their apex_available tags:\n    {invalid_targets_msg}").format(
747*7594170eSAndroid Build Coastguard Worker            apex_name = ctx.label,
748*7594170eSAndroid Build Coastguard Worker            invalid_targets_msg = invalid_targets_msg,
749*7594170eSAndroid Build Coastguard Worker        )
750*7594170eSAndroid Build Coastguard Worker        fail(msg)
751*7594170eSAndroid Build Coastguard Worker
752*7594170eSAndroid Build Coastguard Worker    transitive_unvalidated_targets_output_file = ctx.actions.declare_file(ctx.attr.name + "_unvalidated_deps.txt")
753*7594170eSAndroid Build Coastguard Worker    ctx.actions.write(
754*7594170eSAndroid Build Coastguard Worker        transitive_unvalidated_targets_output_file,
755*7594170eSAndroid Build Coastguard Worker        "\n".join([
756*7594170eSAndroid Build Coastguard Worker            str(label) + ": " + str(reason)
757*7594170eSAndroid Build Coastguard Worker            for label, reason in depset(transitive = transitive_unvalidated_targets).to_list()
758*7594170eSAndroid Build Coastguard Worker        ]),
759*7594170eSAndroid Build Coastguard Worker    )
760*7594170eSAndroid Build Coastguard Worker    return transitive_deps, transitive_unvalidated_targets_output_file, validation_files
761*7594170eSAndroid Build Coastguard Worker
762*7594170eSAndroid Build Coastguard Workerdef _verify_updatability(ctx):
763*7594170eSAndroid Build Coastguard Worker    # TODO(b/274732759): Add these checks as more APEXes are converted to Bazel.
764*7594170eSAndroid Build Coastguard Worker    #
765*7594170eSAndroid Build Coastguard Worker    # Keep this in sync with build/soong/apex/apex.go#checkUpdatable.
766*7594170eSAndroid Build Coastguard Worker    #
767*7594170eSAndroid Build Coastguard Worker    # - Cannot use platform APIs.
768*7594170eSAndroid Build Coastguard Worker    # - Cannot use external VNDK libs.
769*7594170eSAndroid Build Coastguard Worker    # - Does not set future_updatable.
770*7594170eSAndroid Build Coastguard Worker
771*7594170eSAndroid Build Coastguard Worker    if not ctx.attr.min_sdk_version:
772*7594170eSAndroid Build Coastguard Worker        fail("updatable APEXes must set min_sdk_version.")
773*7594170eSAndroid Build Coastguard Worker
774*7594170eSAndroid Build Coastguard Workerdef _generate_sbom(ctx, file_mapping, metadata_file_mapping, apex_file):
775*7594170eSAndroid Build Coastguard Worker    apex_filename = paths.basename(apex_file.path)
776*7594170eSAndroid Build Coastguard Worker    sbom_metadata_csv = ctx.actions.declare_file(apex_filename + "-sbom-metadata.csv")
777*7594170eSAndroid Build Coastguard Worker    command = []
778*7594170eSAndroid Build Coastguard Worker    metadata_files = []
779*7594170eSAndroid Build Coastguard Worker    sbom_metadata_csv_columns = [
780*7594170eSAndroid Build Coastguard Worker        "installed_file",
781*7594170eSAndroid Build Coastguard Worker        "module_path",
782*7594170eSAndroid Build Coastguard Worker        "soong_module_type",
783*7594170eSAndroid Build Coastguard Worker        "is_prebuilt_make_module",
784*7594170eSAndroid Build Coastguard Worker        "product_copy_files",
785*7594170eSAndroid Build Coastguard Worker        "kernel_module_copy_files",
786*7594170eSAndroid Build Coastguard Worker        "is_platform_generated",
787*7594170eSAndroid Build Coastguard Worker        "build_output_path",
788*7594170eSAndroid Build Coastguard Worker        "static_libraries",
789*7594170eSAndroid Build Coastguard Worker        "whole_static_libraries",
790*7594170eSAndroid Build Coastguard Worker        "is_static_lib",
791*7594170eSAndroid Build Coastguard Worker    ]
792*7594170eSAndroid Build Coastguard Worker    command.append("echo " + ",".join(sbom_metadata_csv_columns))
793*7594170eSAndroid Build Coastguard Worker    command.append("echo %s,%s,,,,,,%s,,," % (apex_filename, ctx.label.package, apex_file.path))
794*7594170eSAndroid Build Coastguard Worker    for installed_file, bazel_output_file in file_mapping.items():
795*7594170eSAndroid Build Coastguard Worker        if metadata_file_mapping[installed_file]:
796*7594170eSAndroid Build Coastguard Worker            metadata_files.append(metadata_file_mapping[installed_file])
797*7594170eSAndroid Build Coastguard Worker        command.append("echo %s,%s,,,,,,%s,,," % (installed_file, paths.dirname(bazel_output_file.short_path), bazel_output_file.path))
798*7594170eSAndroid Build Coastguard Worker    ctx.actions.run_shell(
799*7594170eSAndroid Build Coastguard Worker        inputs = file_mapping.values(),
800*7594170eSAndroid Build Coastguard Worker        outputs = [sbom_metadata_csv],
801*7594170eSAndroid Build Coastguard Worker        mnemonic = "GenerateSBOMMetadata",
802*7594170eSAndroid Build Coastguard Worker        command = "(" + "; ".join(command) + ") > " + sbom_metadata_csv.path,
803*7594170eSAndroid Build Coastguard Worker    )
804*7594170eSAndroid Build Coastguard Worker
805*7594170eSAndroid Build Coastguard Worker    sbom_file = ctx.actions.declare_file(apex_filename + ".spdx.json")
806*7594170eSAndroid Build Coastguard Worker    sbom_fragment_file = ctx.actions.declare_file(apex_filename + "-fragment.spdx")
807*7594170eSAndroid Build Coastguard Worker    inputs = [
808*7594170eSAndroid Build Coastguard Worker        apex_file,
809*7594170eSAndroid Build Coastguard Worker        sbom_metadata_csv,
810*7594170eSAndroid Build Coastguard Worker        ctx.executable._generate_sbom,
811*7594170eSAndroid Build Coastguard Worker    ]
812*7594170eSAndroid Build Coastguard Worker    inputs += file_mapping.values()
813*7594170eSAndroid Build Coastguard Worker    inputs += metadata_files
814*7594170eSAndroid Build Coastguard Worker
815*7594170eSAndroid Build Coastguard Worker    build_fingerprint = ctx.attr._build_fingerprint[BuildFingerprintInfo].fingerprint_blank_build_number
816*7594170eSAndroid Build Coastguard Worker    ctx.actions.run(
817*7594170eSAndroid Build Coastguard Worker        inputs = inputs,
818*7594170eSAndroid Build Coastguard Worker        outputs = [sbom_file, sbom_fragment_file],
819*7594170eSAndroid Build Coastguard Worker        arguments = [
820*7594170eSAndroid Build Coastguard Worker            "--output_file",
821*7594170eSAndroid Build Coastguard Worker            sbom_file.path,
822*7594170eSAndroid Build Coastguard Worker            "--metadata",
823*7594170eSAndroid Build Coastguard Worker            sbom_metadata_csv.path,
824*7594170eSAndroid Build Coastguard Worker            "--build_version",
825*7594170eSAndroid Build Coastguard Worker            build_fingerprint,
826*7594170eSAndroid Build Coastguard Worker            "--product_mfr",
827*7594170eSAndroid Build Coastguard Worker            ctx.attr._product_manufacturer[BuildSettingInfo].value,
828*7594170eSAndroid Build Coastguard Worker            "--json",
829*7594170eSAndroid Build Coastguard Worker            "--unbundled_apex",
830*7594170eSAndroid Build Coastguard Worker        ],
831*7594170eSAndroid Build Coastguard Worker        mnemonic = "GenerateSBOM",
832*7594170eSAndroid Build Coastguard Worker        executable = ctx.executable._generate_sbom,
833*7594170eSAndroid Build Coastguard Worker    )
834*7594170eSAndroid Build Coastguard Worker    return [sbom_file, sbom_fragment_file]
835*7594170eSAndroid Build Coastguard Worker
836*7594170eSAndroid Build Coastguard Worker# See the APEX section in the README on how to use this rule.
837*7594170eSAndroid Build Coastguard Workerdef _apex_rule_impl(ctx):
838*7594170eSAndroid Build Coastguard Worker    verify_toolchain_exists(ctx, "//build/bazel/rules/apex:apex_toolchain_type")
839*7594170eSAndroid Build Coastguard Worker    if ctx.attr.updatable:
840*7594170eSAndroid Build Coastguard Worker        _verify_updatability(ctx)
841*7594170eSAndroid Build Coastguard Worker
842*7594170eSAndroid Build Coastguard Worker    apex_toolchain = ctx.toolchains["//build/bazel/rules/apex:apex_toolchain_type"].toolchain_info
843*7594170eSAndroid Build Coastguard Worker
844*7594170eSAndroid Build Coastguard Worker    apexer_outputs = _run_apexer(ctx, apex_toolchain)
845*7594170eSAndroid Build Coastguard Worker    unsigned_apex = apexer_outputs.unsigned_apex
846*7594170eSAndroid Build Coastguard Worker
847*7594170eSAndroid Build Coastguard Worker    if AndroidAppCertificateInfo in ctx.attr.certificate_override[0]:
848*7594170eSAndroid Build Coastguard Worker        apex_cert_info = ctx.attr.certificate_override[0][AndroidAppCertificateInfo]
849*7594170eSAndroid Build Coastguard Worker    else:
850*7594170eSAndroid Build Coastguard Worker        apex_cert_info = ctx.attr.certificate[0][AndroidAppCertificateInfo]
851*7594170eSAndroid Build Coastguard Worker
852*7594170eSAndroid Build Coastguard Worker    private_key = apex_cert_info.pk8
853*7594170eSAndroid Build Coastguard Worker    public_key = apex_cert_info.pem
854*7594170eSAndroid Build Coastguard Worker
855*7594170eSAndroid Build Coastguard Worker    signed_apex = ctx.actions.declare_file(ctx.attr.name + ".apex")
856*7594170eSAndroid Build Coastguard Worker    signed_capex = None
857*7594170eSAndroid Build Coastguard Worker
858*7594170eSAndroid Build Coastguard Worker    _run_signapk(ctx, unsigned_apex, signed_apex, private_key, public_key, "BazelApexSigning")
859*7594170eSAndroid Build Coastguard Worker
860*7594170eSAndroid Build Coastguard Worker    if ctx.attr.compressible and _compression_enabled(ctx):
861*7594170eSAndroid Build Coastguard Worker        compressed_apex_output_file = _run_apex_compression_tool(ctx, apex_toolchain, signed_apex, ctx.attr.name + ".capex.unsigned")
862*7594170eSAndroid Build Coastguard Worker        signed_capex = ctx.actions.declare_file(ctx.attr.name + ".capex")
863*7594170eSAndroid Build Coastguard Worker        _run_signapk(ctx, compressed_apex_output_file, signed_capex, private_key, public_key, "BazelCompressedApexSigning")
864*7594170eSAndroid Build Coastguard Worker
865*7594170eSAndroid Build Coastguard Worker    apex_key_info = ctx.attr.key[ApexKeyInfo]
866*7594170eSAndroid Build Coastguard Worker
867*7594170eSAndroid Build Coastguard Worker    arch = platforms.get_target_arch(ctx.attr._platform_utils)
868*7594170eSAndroid Build Coastguard Worker    zip_files = apex_zip_files(
869*7594170eSAndroid Build Coastguard Worker        actions = ctx.actions,
870*7594170eSAndroid Build Coastguard Worker        name = ctx.label.name,
871*7594170eSAndroid Build Coastguard Worker        tools = struct(
872*7594170eSAndroid Build Coastguard Worker            aapt2 = apex_toolchain.aapt2,
873*7594170eSAndroid Build Coastguard Worker            zip2zip = ctx.executable._zip2zip,
874*7594170eSAndroid Build Coastguard Worker            merge_zips = ctx.executable._merge_zips,
875*7594170eSAndroid Build Coastguard Worker            soong_zip = apex_toolchain.soong_zip,
876*7594170eSAndroid Build Coastguard Worker        ),
877*7594170eSAndroid Build Coastguard Worker        apex_file = signed_apex,
878*7594170eSAndroid Build Coastguard Worker        arch = arch,
879*7594170eSAndroid Build Coastguard Worker        secondary_arch = platforms.get_target_secondary_arch(ctx.attr._platform_utils),
880*7594170eSAndroid Build Coastguard Worker    )
881*7594170eSAndroid Build Coastguard Worker
882*7594170eSAndroid Build Coastguard Worker    transitive_apex_deps, transitive_unvalidated_targets_output_file, apex_deps_validation_files = _validate_apex_deps(ctx)
883*7594170eSAndroid Build Coastguard Worker
884*7594170eSAndroid Build Coastguard Worker    optional_output_groups = {}
885*7594170eSAndroid Build Coastguard Worker    if signed_capex:
886*7594170eSAndroid Build Coastguard Worker        optional_output_groups["signed_compressed_output"] = [signed_capex]
887*7594170eSAndroid Build Coastguard Worker
888*7594170eSAndroid Build Coastguard Worker    return [
889*7594170eSAndroid Build Coastguard Worker        DefaultInfo(files = depset([signed_apex])),
890*7594170eSAndroid Build Coastguard Worker        ApexInfo(
891*7594170eSAndroid Build Coastguard Worker            signed_output = signed_apex,
892*7594170eSAndroid Build Coastguard Worker            signed_compressed_output = signed_capex,
893*7594170eSAndroid Build Coastguard Worker            unsigned_output = unsigned_apex,
894*7594170eSAndroid Build Coastguard Worker            requires_native_libs = apexer_outputs.requires_native_libs,
895*7594170eSAndroid Build Coastguard Worker            provides_native_libs = apexer_outputs.provides_native_libs,
896*7594170eSAndroid Build Coastguard Worker            bundle_key_info = apex_key_info,
897*7594170eSAndroid Build Coastguard Worker            container_key_info = apex_cert_info,
898*7594170eSAndroid Build Coastguard Worker            package_name = ctx.attr.package_name,
899*7594170eSAndroid Build Coastguard Worker            backing_libs = apexer_outputs.backing_libs,
900*7594170eSAndroid Build Coastguard Worker            symbols_used_by_apex = apexer_outputs.symbols_used_by_apex,
901*7594170eSAndroid Build Coastguard Worker            installed_files = apexer_outputs.installed_files,
902*7594170eSAndroid Build Coastguard Worker            java_symbols_used_by_apex = apexer_outputs.java_symbols_used_by_apex,
903*7594170eSAndroid Build Coastguard Worker            base_file = zip_files.apex_only,
904*7594170eSAndroid Build Coastguard Worker            base_with_config_zip = zip_files.apex_with_config,
905*7594170eSAndroid Build Coastguard Worker        ),
906*7594170eSAndroid Build Coastguard Worker        OutputGroupInfo(
907*7594170eSAndroid Build Coastguard Worker            coverage_files = [apexer_outputs.symbols_used_by_apex],
908*7594170eSAndroid Build Coastguard Worker            java_coverage_files = [apexer_outputs.java_symbols_used_by_apex],
909*7594170eSAndroid Build Coastguard Worker            backing_libs = depset([apexer_outputs.backing_libs]),
910*7594170eSAndroid Build Coastguard Worker            installed_files = depset([apexer_outputs.installed_files]),
911*7594170eSAndroid Build Coastguard Worker            transitive_unvalidated_targets = depset([transitive_unvalidated_targets_output_file]),
912*7594170eSAndroid Build Coastguard Worker            apex_sbom = depset(_generate_sbom(ctx, apexer_outputs.file_mapping, apexer_outputs.metadata_file_mapping, signed_apex)),
913*7594170eSAndroid Build Coastguard Worker            capex_sbom = depset(_generate_sbom(ctx, apexer_outputs.file_mapping, apexer_outputs.metadata_file_mapping, signed_capex) if signed_capex else []),
914*7594170eSAndroid Build Coastguard Worker            _validation = apex_deps_validation_files,
915*7594170eSAndroid Build Coastguard Worker            **optional_output_groups
916*7594170eSAndroid Build Coastguard Worker        ),
917*7594170eSAndroid Build Coastguard Worker        ApexDepsInfo(transitive_deps = transitive_apex_deps),
918*7594170eSAndroid Build Coastguard Worker        ApexMkInfo(
919*7594170eSAndroid Build Coastguard Worker            make_modules_to_install = apexer_outputs.make_modules_to_install,
920*7594170eSAndroid Build Coastguard Worker            files_info = apexer_outputs.make_files_info,
921*7594170eSAndroid Build Coastguard Worker        ),
922*7594170eSAndroid Build Coastguard Worker        collect_deps_clang_tidy_info(ctx),
923*7594170eSAndroid Build Coastguard Worker    ]
924*7594170eSAndroid Build Coastguard Worker
925*7594170eSAndroid Build Coastguard Worker# These are the standard aspects that should be applied on all edges that
926*7594170eSAndroid Build Coastguard Worker# contribute to an APEX's payload.
927*7594170eSAndroid Build Coastguard WorkerSTANDARD_PAYLOAD_ASPECTS = [
928*7594170eSAndroid Build Coastguard Worker    license_aspect,
929*7594170eSAndroid Build Coastguard Worker    apex_available_aspect,
930*7594170eSAndroid Build Coastguard Worker    apex_deps_validation_aspect,
931*7594170eSAndroid Build Coastguard Worker]
932*7594170eSAndroid Build Coastguard Worker
933*7594170eSAndroid Build Coastguard Worker_apex = rule(
934*7594170eSAndroid Build Coastguard Worker    implementation = _apex_rule_impl,
935*7594170eSAndroid Build Coastguard Worker    attrs = {
936*7594170eSAndroid Build Coastguard Worker        # Attributes that configure the APEX container.
937*7594170eSAndroid Build Coastguard Worker        "manifest": attr.label(allow_single_file = [".json"]),
938*7594170eSAndroid Build Coastguard Worker        "android_manifest": attr.label(allow_single_file = [".xml"]),
939*7594170eSAndroid Build Coastguard Worker        "package_name": attr.string(),
940*7594170eSAndroid Build Coastguard Worker        "logging_parent": attr.string(),
941*7594170eSAndroid Build Coastguard Worker        "file_contexts": attr.label(allow_single_file = True, mandatory = True),
942*7594170eSAndroid Build Coastguard Worker        "canned_fs_config": attr.label(
943*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
944*7594170eSAndroid Build Coastguard Worker            doc = """Path to the canned fs config file for customizing file's
945*7594170eSAndroid Build Coastguard Workeruid/gid/mod/capabilities. The content of this file is appended to the
946*7594170eSAndroid Build Coastguard Workerdefault config, so that the custom entries are preferred.
947*7594170eSAndroid Build Coastguard Worker
948*7594170eSAndroid Build Coastguard WorkerThe format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where
949*7594170eSAndroid Build Coastguard Workerpath_or_glob is a path or glob pattern for a file or set of files, uid/gid
950*7594170eSAndroid Build Coastguard Workerare numerial values of user ID and group ID, mode is octal value for the
951*7594170eSAndroid Build Coastguard Workerfile mode, and cap is hexadecimal value for the capability.""",
952*7594170eSAndroid Build Coastguard Worker        ),
953*7594170eSAndroid Build Coastguard Worker        "key": attr.label(providers = [ApexKeyInfo], mandatory = True),
954*7594170eSAndroid Build Coastguard Worker        "certificate": attr.label(
955*7594170eSAndroid Build Coastguard Worker            providers = [AndroidAppCertificateInfo],
956*7594170eSAndroid Build Coastguard Worker            mandatory = True,
957*7594170eSAndroid Build Coastguard Worker            cfg = apex_transition,
958*7594170eSAndroid Build Coastguard Worker        ),
959*7594170eSAndroid Build Coastguard Worker        "certificate_override": attr.label(
960*7594170eSAndroid Build Coastguard Worker            providers = [[AndroidAppCertificateInfo], [NoAndroidAppCertificateInfo]],
961*7594170eSAndroid Build Coastguard Worker            mandatory = True,
962*7594170eSAndroid Build Coastguard Worker            cfg = apex_transition,
963*7594170eSAndroid Build Coastguard Worker        ),
964*7594170eSAndroid Build Coastguard Worker        "min_sdk_version": attr.string(
965*7594170eSAndroid Build Coastguard Worker            default = "current",
966*7594170eSAndroid Build Coastguard Worker            doc = """The minimum SDK version that this APEX must support at minimum. This is usually set to
967*7594170eSAndroid Build Coastguard Workerthe SDK version that the APEX was first introduced.
968*7594170eSAndroid Build Coastguard Worker
969*7594170eSAndroid Build Coastguard WorkerWhen not set, defaults to "10000" (or "current").""",
970*7594170eSAndroid Build Coastguard Worker        ),
971*7594170eSAndroid Build Coastguard Worker        "updatable": attr.bool(default = True, doc = """Whether this APEX is considered updatable or not.
972*7594170eSAndroid Build Coastguard Worker
973*7594170eSAndroid Build Coastguard WorkerWhen set to true, this will enforce additional rules for making sure that the
974*7594170eSAndroid Build Coastguard WorkerAPEX is truly updatable. To be updatable, min_sdk_version should be set as well."""),
975*7594170eSAndroid Build Coastguard Worker        "installable": attr.bool(default = True),
976*7594170eSAndroid Build Coastguard Worker        "compressible": attr.bool(default = False),
977*7594170eSAndroid Build Coastguard Worker        "base_apex_name": attr.string(
978*7594170eSAndroid Build Coastguard Worker            default = "",
979*7594170eSAndroid Build Coastguard Worker            doc = "The name of the base apex of this apex. For example, the AOSP variant of this apex.",
980*7594170eSAndroid Build Coastguard Worker        ),
981*7594170eSAndroid Build Coastguard Worker        "apex_available_name": attr.string(
982*7594170eSAndroid Build Coastguard Worker            default = "",
983*7594170eSAndroid Build Coastguard Worker            doc = "The name that dependencies can specify in their apex_available " +
984*7594170eSAndroid Build Coastguard Worker                  "properties to refer to this module. If not specified, this " +
985*7594170eSAndroid Build Coastguard Worker                  "defaults to Soong module name.",
986*7594170eSAndroid Build Coastguard Worker        ),
987*7594170eSAndroid Build Coastguard Worker        "variant_version": attr.string(
988*7594170eSAndroid Build Coastguard Worker            default = "",
989*7594170eSAndroid Build Coastguard Worker            doc = "Variant version of the mainline module. Must be an integer between 0-9",
990*7594170eSAndroid Build Coastguard Worker            values = [""] + [str(i) for i in range(10)],
991*7594170eSAndroid Build Coastguard Worker        ),
992*7594170eSAndroid Build Coastguard Worker
993*7594170eSAndroid Build Coastguard Worker        # Attributes that contribute to the payload.
994*7594170eSAndroid Build Coastguard Worker        "native_shared_libs_32": attr.label_list(
995*7594170eSAndroid Build Coastguard Worker            providers = [ApexCcInfo, ApexCcMkInfo, RuleLicensedDependenciesInfo],
996*7594170eSAndroid Build Coastguard Worker            aspects = STANDARD_PAYLOAD_ASPECTS + [apex_cc_aspect],
997*7594170eSAndroid Build Coastguard Worker            cfg = shared_lib_transition_32,
998*7594170eSAndroid Build Coastguard Worker            doc = "The libs compiled for 32-bit",
999*7594170eSAndroid Build Coastguard Worker        ),
1000*7594170eSAndroid Build Coastguard Worker        "native_shared_libs_64": attr.label_list(
1001*7594170eSAndroid Build Coastguard Worker            providers = [ApexCcInfo, ApexCcMkInfo, RuleLicensedDependenciesInfo],
1002*7594170eSAndroid Build Coastguard Worker            aspects = STANDARD_PAYLOAD_ASPECTS + [apex_cc_aspect],
1003*7594170eSAndroid Build Coastguard Worker            cfg = shared_lib_transition_64,
1004*7594170eSAndroid Build Coastguard Worker            doc = "The libs compiled for 64-bit",
1005*7594170eSAndroid Build Coastguard Worker        ),
1006*7594170eSAndroid Build Coastguard Worker        "binaries": attr.label_list(
1007*7594170eSAndroid Build Coastguard Worker            providers = [
1008*7594170eSAndroid Build Coastguard Worker                # The dependency must produce _all_ of the providers in _one_ of these lists.
1009*7594170eSAndroid Build Coastguard Worker                [ShBinaryInfo, RuleLicensedDependenciesInfo],  # sh_binary
1010*7594170eSAndroid Build Coastguard Worker                [StrippedCcBinaryInfo, CcInfo, ApexCcInfo, ApexCcMkInfo, RuleLicensedDependenciesInfo],  # cc_binary (stripped)
1011*7594170eSAndroid Build Coastguard Worker            ],
1012*7594170eSAndroid Build Coastguard Worker            cfg = apex_transition,
1013*7594170eSAndroid Build Coastguard Worker            aspects = STANDARD_PAYLOAD_ASPECTS + [apex_cc_aspect],
1014*7594170eSAndroid Build Coastguard Worker        ),
1015*7594170eSAndroid Build Coastguard Worker        "prebuilts": attr.label_list(
1016*7594170eSAndroid Build Coastguard Worker            providers = [PrebuiltFileInfo, RuleLicensedDependenciesInfo],
1017*7594170eSAndroid Build Coastguard Worker            cfg = apex_transition,
1018*7594170eSAndroid Build Coastguard Worker            aspects = STANDARD_PAYLOAD_ASPECTS,
1019*7594170eSAndroid Build Coastguard Worker        ),
1020*7594170eSAndroid Build Coastguard Worker
1021*7594170eSAndroid Build Coastguard Worker        # Required to use apex_transition. This is an acknowledgement to the risks of memory bloat when using transitions.
1022*7594170eSAndroid Build Coastguard Worker        "_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
1023*7594170eSAndroid Build Coastguard Worker
1024*7594170eSAndroid Build Coastguard Worker        # Tools that are not part of the apex_toolchain.
1025*7594170eSAndroid Build Coastguard Worker        "_staging_dir_builder": attr.label(
1026*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
1027*7594170eSAndroid Build Coastguard Worker            doc = "The staging dir builder to avoid the problem where symlinks are created inside apex image.",
1028*7594170eSAndroid Build Coastguard Worker            executable = True,
1029*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/rules:staging_dir_builder",
1030*7594170eSAndroid Build Coastguard Worker        ),
1031*7594170eSAndroid Build Coastguard Worker        "_signapk": attr.label(
1032*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
1033*7594170eSAndroid Build Coastguard Worker            doc = "The signapk tool.",
1034*7594170eSAndroid Build Coastguard Worker            executable = True,
1035*7594170eSAndroid Build Coastguard Worker            default = "//build/make/tools/signapk",
1036*7594170eSAndroid Build Coastguard Worker        ),
1037*7594170eSAndroid Build Coastguard Worker        "_zip2zip": attr.label(
1038*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
1039*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
1040*7594170eSAndroid Build Coastguard Worker            doc = "The tool zip2zip. Used to convert apex file to the expected directory structure.",
1041*7594170eSAndroid Build Coastguard Worker            default = "//build/soong/cmd/zip2zip:zip2zip",
1042*7594170eSAndroid Build Coastguard Worker            executable = True,
1043*7594170eSAndroid Build Coastguard Worker        ),
1044*7594170eSAndroid Build Coastguard Worker        "_merge_zips": attr.label(
1045*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
1046*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
1047*7594170eSAndroid Build Coastguard Worker            doc = "The tool merge_zips. Used to combine base zip and config file into a single zip for mixed build aab creation.",
1048*7594170eSAndroid Build Coastguard Worker            default = "//build/soong/cmd/merge_zips",
1049*7594170eSAndroid Build Coastguard Worker            executable = True,
1050*7594170eSAndroid Build Coastguard Worker        ),
1051*7594170eSAndroid Build Coastguard Worker        "_platform_utils": attr.label(
1052*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/platforms:platform_utils",
1053*7594170eSAndroid Build Coastguard Worker        ),
1054*7594170eSAndroid Build Coastguard Worker        "_build_fingerprint": attr.label(
1055*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/rules:build_fingerprint",
1056*7594170eSAndroid Build Coastguard Worker        ),
1057*7594170eSAndroid Build Coastguard Worker        "_generate_sbom": attr.label(
1058*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
1059*7594170eSAndroid Build Coastguard Worker            doc = "SBOM generation tool",
1060*7594170eSAndroid Build Coastguard Worker            executable = True,
1061*7594170eSAndroid Build Coastguard Worker            default = "//build/make/tools/sbom:generate-sbom",
1062*7594170eSAndroid Build Coastguard Worker        ),
1063*7594170eSAndroid Build Coastguard Worker
1064*7594170eSAndroid Build Coastguard Worker        # allowed deps check
1065*7594170eSAndroid Build Coastguard Worker        "_unsafe_disable_apex_allowed_deps_check": attr.label(
1066*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/rules/apex:unsafe_disable_apex_allowed_deps_check",
1067*7594170eSAndroid Build Coastguard Worker        ),
1068*7594170eSAndroid Build Coastguard Worker        "allowed_apex_deps_manifest": attr.label(
1069*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
1070*7594170eSAndroid Build Coastguard Worker            default = "//packages/modules/common/build:allowed_deps.txt",
1071*7594170eSAndroid Build Coastguard Worker        ),
1072*7594170eSAndroid Build Coastguard Worker
1073*7594170eSAndroid Build Coastguard Worker        # Build settings.
1074*7594170eSAndroid Build Coastguard Worker        "_always_use_prebuilt_sdks": attr.label(
1075*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:always_use_prebuilt_sdks",
1076*7594170eSAndroid Build Coastguard Worker        ),
1077*7594170eSAndroid Build Coastguard Worker        "_apex_global_min_sdk_version_override": attr.label(
1078*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:apex_global_min_sdk_version_override",
1079*7594170eSAndroid Build Coastguard Worker            doc = "If specified, override the min_sdk_version of this apex and in the transition and checks for dependencies.",
1080*7594170eSAndroid Build Coastguard Worker        ),
1081*7594170eSAndroid Build Coastguard Worker        "_compressed_apex": attr.label(
1082*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:compressed_apex",
1083*7594170eSAndroid Build Coastguard Worker        ),
1084*7594170eSAndroid Build Coastguard Worker        "_manifest_package_name_overrides": attr.label(
1085*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:manifest_package_name_overrides",
1086*7594170eSAndroid Build Coastguard Worker        ),
1087*7594170eSAndroid Build Coastguard Worker        "_override_apex_manifest_default_version": attr.label(
1088*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/rules/apex:override_apex_manifest_default_version",
1089*7594170eSAndroid Build Coastguard Worker            doc = "If specified, override 'version: 0' in apex_manifest.json with this value instead of the branch default. Non-zero versions will not be changed.",
1090*7594170eSAndroid Build Coastguard Worker        ),
1091*7594170eSAndroid Build Coastguard Worker        "_product_manufacturer": attr.label(
1092*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:product_manufacturer",
1093*7594170eSAndroid Build Coastguard Worker        ),
1094*7594170eSAndroid Build Coastguard Worker        "_unbundled_build_apps": attr.label(
1095*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:unbundled_build_apps",
1096*7594170eSAndroid Build Coastguard Worker        ),
1097*7594170eSAndroid Build Coastguard Worker        "_unbundled_build": attr.label(
1098*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:unbundled_build",
1099*7594170eSAndroid Build Coastguard Worker        ),
1100*7594170eSAndroid Build Coastguard Worker
1101*7594170eSAndroid Build Coastguard Worker        # Api_fingerprint
1102*7594170eSAndroid Build Coastguard Worker        "_unbundled_build_target_sdk_with_api_fingerprint": attr.label(
1103*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/rules/apex:unbundled_build_target_sdk_with_api_fingerprint",
1104*7594170eSAndroid Build Coastguard Worker        ),
1105*7594170eSAndroid Build Coastguard Worker        "_platform_sdk_codename": attr.label(
1106*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/rules/apex:platform_sdk_codename",
1107*7594170eSAndroid Build Coastguard Worker        ),
1108*7594170eSAndroid Build Coastguard Worker        "_api_fingerprint_txt": attr.label(
1109*7594170eSAndroid Build Coastguard Worker            default = "//frameworks/base/api:api_fingerprint",
1110*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
1111*7594170eSAndroid Build Coastguard Worker        ),
1112*7594170eSAndroid Build Coastguard Worker    },
1113*7594170eSAndroid Build Coastguard Worker    # The apex toolchain is not mandatory so that we don't get toolchain resolution errors even
1114*7594170eSAndroid Build Coastguard Worker    # when the apex is not compatible with the current target (via target_compatible_with).
1115*7594170eSAndroid Build Coastguard Worker    toolchains = [config_common.toolchain_type("//build/bazel/rules/apex:apex_toolchain_type", mandatory = False)],
1116*7594170eSAndroid Build Coastguard Worker    fragments = ["platform"],
1117*7594170eSAndroid Build Coastguard Worker)
1118*7594170eSAndroid Build Coastguard Worker
1119*7594170eSAndroid Build Coastguard Workerdef apex(
1120*7594170eSAndroid Build Coastguard Worker        name,
1121*7594170eSAndroid Build Coastguard Worker        manifest = "apex_manifest.json",
1122*7594170eSAndroid Build Coastguard Worker        android_manifest = None,
1123*7594170eSAndroid Build Coastguard Worker        file_contexts = None,
1124*7594170eSAndroid Build Coastguard Worker        key = None,
1125*7594170eSAndroid Build Coastguard Worker        certificate = None,
1126*7594170eSAndroid Build Coastguard Worker        certificate_name = None,
1127*7594170eSAndroid Build Coastguard Worker        min_sdk_version = None,
1128*7594170eSAndroid Build Coastguard Worker        updatable = True,
1129*7594170eSAndroid Build Coastguard Worker        installable = True,
1130*7594170eSAndroid Build Coastguard Worker        compressible = False,
1131*7594170eSAndroid Build Coastguard Worker        native_shared_libs_32 = [],
1132*7594170eSAndroid Build Coastguard Worker        native_shared_libs_64 = [],
1133*7594170eSAndroid Build Coastguard Worker        binaries = [],
1134*7594170eSAndroid Build Coastguard Worker        prebuilts = [],
1135*7594170eSAndroid Build Coastguard Worker        package_name = None,
1136*7594170eSAndroid Build Coastguard Worker        logging_parent = None,
1137*7594170eSAndroid Build Coastguard Worker        canned_fs_config = None,
1138*7594170eSAndroid Build Coastguard Worker        testonly = False,
1139*7594170eSAndroid Build Coastguard Worker        # TODO(b/255400736): tests are not fully supported yet.
1140*7594170eSAndroid Build Coastguard Worker        tests = [],
1141*7594170eSAndroid Build Coastguard Worker        target_compatible_with = [],
1142*7594170eSAndroid Build Coastguard Worker        **kwargs):
1143*7594170eSAndroid Build Coastguard Worker    "Bazel macro to correspond with the APEX bundle Soong module."
1144*7594170eSAndroid Build Coastguard Worker
1145*7594170eSAndroid Build Coastguard Worker    # If file_contexts is not specified, then use the default from //system/sepolicy/apex.
1146*7594170eSAndroid Build Coastguard Worker    # https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/builder.go;l=259-263;drc=b02043b84d86fe1007afef1ff012a2155172215c
1147*7594170eSAndroid Build Coastguard Worker    if file_contexts == None:
1148*7594170eSAndroid Build Coastguard Worker        file_contexts = "//system/sepolicy/apex:" + name + "-file_contexts"
1149*7594170eSAndroid Build Coastguard Worker
1150*7594170eSAndroid Build Coastguard Worker    if testonly:
1151*7594170eSAndroid Build Coastguard Worker        compressible = False
1152*7594170eSAndroid Build Coastguard Worker    elif tests:
1153*7594170eSAndroid Build Coastguard Worker        fail("Apex with tests attribute needs to be testonly.")
1154*7594170eSAndroid Build Coastguard Worker
1155*7594170eSAndroid Build Coastguard Worker    if certificate and certificate_name:
1156*7594170eSAndroid Build Coastguard Worker        fail("Cannot use both certificate_name and certificate attributes together. Use only one of them.")
1157*7594170eSAndroid Build Coastguard Worker    app_cert_name = name + "_app_certificate"
1158*7594170eSAndroid Build Coastguard Worker    if certificate_name:
1159*7594170eSAndroid Build Coastguard Worker        # use the name key in the default cert dir
1160*7594170eSAndroid Build Coastguard Worker        android_app_certificate_with_default_cert(
1161*7594170eSAndroid Build Coastguard Worker            name = app_cert_name,
1162*7594170eSAndroid Build Coastguard Worker            cert_name = certificate_name,
1163*7594170eSAndroid Build Coastguard Worker        )
1164*7594170eSAndroid Build Coastguard Worker        certificate_label = ":" + app_cert_name
1165*7594170eSAndroid Build Coastguard Worker    elif certificate:
1166*7594170eSAndroid Build Coastguard Worker        certificate_label = certificate
1167*7594170eSAndroid Build Coastguard Worker    else:
1168*7594170eSAndroid Build Coastguard Worker        # use the default testkey
1169*7594170eSAndroid Build Coastguard Worker        android_app_certificate_with_default_cert(name = app_cert_name)
1170*7594170eSAndroid Build Coastguard Worker        certificate_label = ":" + app_cert_name
1171*7594170eSAndroid Build Coastguard Worker
1172*7594170eSAndroid Build Coastguard Worker    target_compatible_with = select({
1173*7594170eSAndroid Build Coastguard Worker        "//build/bazel_common_rules/platforms/os:android": [],
1174*7594170eSAndroid Build Coastguard Worker        "//conditions:default": ["@platforms//:incompatible"],
1175*7594170eSAndroid Build Coastguard Worker    }) + target_compatible_with
1176*7594170eSAndroid Build Coastguard Worker
1177*7594170eSAndroid Build Coastguard Worker    # This flag will be set based on the value of PRODUCT_CERTIFICATE_OVERRIDES
1178*7594170eSAndroid Build Coastguard Worker    native.label_flag(
1179*7594170eSAndroid Build Coastguard Worker        name = name + "_certificate_override",
1180*7594170eSAndroid Build Coastguard Worker        build_setting_default = "//build/bazel/rules/android:no_android_app_certificate",
1181*7594170eSAndroid Build Coastguard Worker    )
1182*7594170eSAndroid Build Coastguard Worker
1183*7594170eSAndroid Build Coastguard Worker    _apex(
1184*7594170eSAndroid Build Coastguard Worker        name = name,
1185*7594170eSAndroid Build Coastguard Worker        manifest = manifest,
1186*7594170eSAndroid Build Coastguard Worker        android_manifest = android_manifest,
1187*7594170eSAndroid Build Coastguard Worker        file_contexts = file_contexts,
1188*7594170eSAndroid Build Coastguard Worker        key = key,
1189*7594170eSAndroid Build Coastguard Worker        certificate = certificate_label,
1190*7594170eSAndroid Build Coastguard Worker        certificate_override = ":" + name + "_certificate_override",
1191*7594170eSAndroid Build Coastguard Worker        min_sdk_version = min_sdk_version,
1192*7594170eSAndroid Build Coastguard Worker        updatable = updatable,
1193*7594170eSAndroid Build Coastguard Worker        installable = installable,
1194*7594170eSAndroid Build Coastguard Worker        compressible = compressible,
1195*7594170eSAndroid Build Coastguard Worker        native_shared_libs_32 = native_shared_libs_32,
1196*7594170eSAndroid Build Coastguard Worker        native_shared_libs_64 = native_shared_libs_64,
1197*7594170eSAndroid Build Coastguard Worker        binaries = binaries,
1198*7594170eSAndroid Build Coastguard Worker        prebuilts = prebuilts,
1199*7594170eSAndroid Build Coastguard Worker        package_name = package_name,
1200*7594170eSAndroid Build Coastguard Worker        logging_parent = logging_parent,
1201*7594170eSAndroid Build Coastguard Worker        canned_fs_config = canned_fs_config,
1202*7594170eSAndroid Build Coastguard Worker        testonly = testonly,
1203*7594170eSAndroid Build Coastguard Worker        target_compatible_with = target_compatible_with,
1204*7594170eSAndroid Build Coastguard Worker        **kwargs
1205*7594170eSAndroid Build Coastguard Worker    )
1206