blob: 2e2c2cbf828a56ef7dd5292d70239c6a5c9b20cb [file] [log] [blame]
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090015// package apex implements build rules for creating the APEX files which are container for
16// lower-level system components. See https://source.android.com/devices/tech/ota/apex
Jiyong Park48ca7dc2018-10-10 14:01:00 +090017package apex
18
19import (
20 "fmt"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090021 "path/filepath"
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +000022 "regexp"
Jiyong Parkab3ceb32018-10-10 14:05:29 +090023 "sort"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090024 "strings"
25
Yu Liu4c212ce2022-10-14 12:20:20 -070026 "android/soong/bazel/cquery"
27
Jiyong Park48ca7dc2018-10-10 14:01:00 +090028 "github.com/google/blueprint"
Alex Light778127a2019-02-27 14:19:50 -080029 "github.com/google/blueprint/bootstrap"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090030 "github.com/google/blueprint/proptools"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070031
32 "android/soong/android"
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -040033 "android/soong/bazel"
markchien2f59ec92020-09-02 16:23:38 +080034 "android/soong/bpf"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070035 "android/soong/cc"
36 prebuilt_etc "android/soong/etc"
Jiyong Park12a719c2021-01-07 15:31:24 +090037 "android/soong/filesystem"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070038 "android/soong/java"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090039 "android/soong/multitree"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070040 "android/soong/python"
Jiyong Park99644e92020-11-17 22:21:02 +090041 "android/soong/rust"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070042 "android/soong/sh"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090043)
44
Jiyong Park8e6d52f2020-11-19 14:37:47 +090045func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000046 registerApexBuildComponents(android.InitRegistrationContext)
47}
Jiyong Park8e6d52f2020-11-19 14:37:47 +090048
Paul Duffin667893c2021-03-09 22:34:13 +000049func registerApexBuildComponents(ctx android.RegistrationContext) {
50 ctx.RegisterModuleType("apex", BundleFactory)
Yu Liu4c212ce2022-10-14 12:20:20 -070051 ctx.RegisterModuleType("apex_test", TestApexBundleFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000052 ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
53 ctx.RegisterModuleType("apex_defaults", defaultsFactory)
54 ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
Wei Li1c66fc72022-05-09 23:59:14 -070055 ctx.RegisterModuleType("override_apex", OverrideApexFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000056 ctx.RegisterModuleType("apex_set", apexSetFactory)
57
Paul Duffin5dda3e32021-05-05 14:13:27 +010058 ctx.PreArchMutators(registerPreArchMutators)
Paul Duffin667893c2021-03-09 22:34:13 +000059 ctx.PreDepsMutators(RegisterPreDepsMutators)
60 ctx.PostDepsMutators(RegisterPostDepsMutators)
Jiyong Park8e6d52f2020-11-19 14:37:47 +090061}
62
Paul Duffin5dda3e32021-05-05 14:13:27 +010063func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
64 ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
65}
66
Jiyong Park8e6d52f2020-11-19 14:37:47 +090067func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
68 ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
69 ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
70}
71
72func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
Paul Duffin949abc02020-12-08 10:34:30 +000073 ctx.TopDown("apex_info", apexInfoMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090074 ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
75 ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
76 ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
Paul Duffin28bf7ee2021-05-12 16:41:35 +010077 // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
78 // it should create a platform variant.
79 ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090080 ctx.BottomUp("apex", apexMutator).Parallel()
81 ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
82 ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
Dennis Shene2ed70c2023-01-11 14:15:43 +000083 ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
Spandan Das66773252022-01-15 00:23:18 +000084 // Register after apex_info mutator so that it can use ApexVariationName
85 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090086}
87
88type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090089 // Json manifest file describing meta info of this APEX bundle. Refer to
90 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090091 Manifest *string `android:"path"`
92
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090093 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
94 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090095 AndroidManifest *string `android:"path"`
96
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090097 // Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
98 // device (/apex/<apex_name>). If unspecified, follows the name property.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090099 Apex_name *string
100
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900101 // Determines the file contexts file for setting the security contexts to files in this APEX
102 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
103 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900104 File_contexts *string `android:"path"`
105
Jiyong Park038e8522021-12-13 23:56:35 +0900106 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
107 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
108 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
109 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
110 // capability. If this property is not set, or a file is missing in the file, default config
111 // is used.
112 Canned_fs_config *string `android:"path"`
113
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900114 ApexNativeDependencies
115
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900116 Multilib apexMultilibProperties
117
Sundong Ahn80c04892021-11-23 00:57:19 +0000118 // List of sh binaries that are embedded inside this APEX bundle.
119 Sh_binaries []string
120
Paul Duffin3abc1742021-03-15 19:32:23 +0000121 // List of platform_compat_config files that are embedded inside this APEX bundle.
122 Compat_configs []string
123
Jiyong Park12a719c2021-01-07 15:31:24 +0900124 // List of filesystem images that are embedded inside this APEX bundle.
125 Filesystems []string
126
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900127 // The minimum SDK version that this APEX must support at minimum. This is usually set to
128 // the SDK version that the APEX was first introduced.
129 Min_sdk_version *string
130
131 // Whether this APEX is considered updatable or not. When set to true, this will enforce
132 // additional rules for making sure that the APEX is truly updatable. To be updatable,
133 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000134 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900135 Updatable *bool
136
Jiyong Parkf4020582021-11-29 12:37:10 +0900137 // Marks that this APEX is designed to be updatable in the future, although it's not
138 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
139 // updatable APEXes. Currently, this disables the size optimization, so that the size of
140 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
141 // false.
142 Future_updatable *bool
143
Jiyong Park1bc84122021-06-22 20:23:05 +0900144 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
145 // false`. Default is false.
146 Platform_apis *bool
147
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900148 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
149 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900150 Installable *bool
151
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900152 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
153 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
154 Use_vndk_as_stable *bool
155
Daniel Norman6cfb37af2021-11-16 20:28:29 +0000156 // Whether this is multi-installed APEX should skip installing symbol files.
157 // Multi-installed APEXes share the same apex_name and are installed at the same time.
158 // Default is false.
159 //
160 // Should be set to true for all multi-installed APEXes except the singular
161 // default version within the multi-installed group.
162 // Only the default version can install symbol files in $(PRODUCT_OUT}/apex,
163 // or else conflicting build rules may be created.
164 Multi_install_skip_symbol_files *bool
165
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900166 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
167 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
168 // container. When set to zip, contents are stored in a zip container directly. This type is
169 // mostly for host-side debugging. When set to both, the two types are both built. Default
170 // is 'image'.
171 Payload_type *string
172
Huang Jianan13cac632021-08-02 15:02:17 +0800173 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
174 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900175 Payload_fs_type *string
176
177 // For telling the APEX to ignore special handling for system libraries such as bionic.
178 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900179 Ignore_system_library_special_case *bool
180
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100181 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100182 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100183 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900184
185 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
186 // used in tests.
187 Test_only_unsigned_payload *bool
188
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000189 // Whenever apex should be compressed, regardless of product flag used. Should be only
190 // used in tests.
191 Test_only_force_compression *bool
192
Jooyung Han09c11ad2021-10-27 03:45:31 +0900193 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
194 // with the tool to sign payload contents.
195 Custom_sign_tool *string
196
Dennis Shenaf41bc12022-08-03 16:46:43 +0000197 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
198 // in a special way that include the digest of the lib file under /lib(64)?
199 Dynamic_common_lib_apex *bool
200
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100201 // Canonical name of this APEX bundle. Used to determine the path to the
202 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
203 // apex mutator variations. For override_apex modules, this is the name of the
204 // overridden base module.
205 ApexVariationName string `blueprint:"mutated"`
206
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900207 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900208
209 // List of sanitizer names that this APEX is enabled for
210 SanitizerNames []string `blueprint:"mutated"`
211
212 PreventInstall bool `blueprint:"mutated"`
213
214 HideFromMake bool `blueprint:"mutated"`
215
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900216 // Internal package method for this APEX. When payload_type is image, this can be either
217 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
218 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900219 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900220}
221
222type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900223 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900224 Native_shared_libs []string
225
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900226 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900227 Jni_libs []string
228
Colin Cross70572ed2022-11-02 13:14:20 -0700229 // List of rust dyn libraries that are embedded inside this APEX.
Jiyong Park99644e92020-11-17 22:21:02 +0900230 Rust_dyn_libs []string
231
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900232 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900233 Binaries []string
234
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900235 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900236 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900237
238 // List of filesystem images that are embedded inside this APEX bundle.
239 Filesystems []string
Colin Cross70572ed2022-11-02 13:14:20 -0700240
241 // List of native libraries to exclude from this APEX.
242 Exclude_native_shared_libs []string
243
244 // List of JNI libraries to exclude from this APEX.
245 Exclude_jni_libs []string
246
247 // List of rust dyn libraries to exclude from this APEX.
248 Exclude_rust_dyn_libs []string
249
250 // List of native executables to exclude from this APEX.
251 Exclude_binaries []string
252
253 // List of native tests to exclude from this APEX.
254 Exclude_tests []string
255
256 // List of filesystem images to exclude from this APEX bundle.
257 Exclude_filesystems []string
258}
259
260// Merge combines another ApexNativeDependencies into this one
261func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
262 a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
263 a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
264 a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
265 a.Binaries = append(a.Binaries, b.Binaries...)
266 a.Tests = append(a.Tests, b.Tests...)
267 a.Filesystems = append(a.Filesystems, b.Filesystems...)
268
269 a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
270 a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
271 a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
272 a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
273 a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
274 a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900275}
276
277type apexMultilibProperties struct {
278 // Native dependencies whose compile_multilib is "first"
279 First ApexNativeDependencies
280
281 // Native dependencies whose compile_multilib is "both"
282 Both ApexNativeDependencies
283
284 // Native dependencies whose compile_multilib is "prefer32"
285 Prefer32 ApexNativeDependencies
286
287 // Native dependencies whose compile_multilib is "32"
288 Lib32 ApexNativeDependencies
289
290 // Native dependencies whose compile_multilib is "64"
291 Lib64 ApexNativeDependencies
292}
293
294type apexTargetBundleProperties struct {
295 Target struct {
296 // Multilib properties only for android.
297 Android struct {
298 Multilib apexMultilibProperties
299 }
300
301 // Multilib properties only for host.
302 Host struct {
303 Multilib apexMultilibProperties
304 }
305
306 // Multilib properties only for host linux_bionic.
307 Linux_bionic struct {
308 Multilib apexMultilibProperties
309 }
310
311 // Multilib properties only for host linux_glibc.
312 Linux_glibc struct {
313 Multilib apexMultilibProperties
314 }
315 }
316}
317
Jiyong Park59140302020-12-14 18:44:04 +0900318type apexArchBundleProperties struct {
319 Arch struct {
320 Arm struct {
321 ApexNativeDependencies
322 }
323 Arm64 struct {
324 ApexNativeDependencies
325 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700326 Riscv64 struct {
327 ApexNativeDependencies
328 }
Jiyong Park59140302020-12-14 18:44:04 +0900329 X86 struct {
330 ApexNativeDependencies
331 }
332 X86_64 struct {
333 ApexNativeDependencies
334 }
335 }
336}
337
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900338// These properties can be used in override_apex to override the corresponding properties in the
339// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900340type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900341 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900342 Apps []string
343
Daniel Norman5a3ce132021-08-26 15:44:43 -0700344 // List of prebuilt files that are embedded inside this APEX bundle.
345 Prebuilts []string
346
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900347 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900348 Rros []string
349
markchien7c803b82021-08-26 22:10:06 +0800350 // List of BPF programs inside this APEX bundle.
351 Bpfs []string
352
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900353 // List of bootclasspath fragments that are embedded inside this APEX bundle.
354 Bootclasspath_fragments []string
355
356 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
357 Systemserverclasspath_fragments []string
358
359 // List of java libraries that are embedded inside this APEX bundle.
360 Java_libs []string
361
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900362 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
363 // Soong). This does not completely prevent installation of the overridden binaries, but if
364 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
365 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900366 Overrides []string
367
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900368 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900369 Logging_parent string
370
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900371 // Apex Container package name. Override value for attribute package:name in
372 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900373 Package_name string
374
375 // A txt file containing list of files that are allowed to be included in this APEX.
376 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700377
378 // Name of the apex_key module that provides the private key to sign this APEX bundle.
379 Key *string
380
381 // Specifies the certificate and the private key to sign the zip container of this APEX. If
382 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
383 // as the certificate and the private key, respectively. If this is ":module", then the
384 // certificate and the private key are provided from the android_app_certificate module
385 // named "module".
386 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400387
388 // Whether this APEX can be compressed or not. Setting this property to false means this
389 // APEX will never be compressed. When set to true, APEX will be compressed if other
390 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
391 // Default: false.
392 Compressible *bool
Dennis Shene2ed70c2023-01-11 14:15:43 +0000393
394 // Trim against a specific Dynamic Common Lib APEX
395 Trim_against *string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900396}
397
398type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900399 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900400 android.ModuleBase
401 android.DefaultableModuleBase
402 android.OverridableModuleBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400403 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900404 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900405
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900406 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900407 properties apexBundleProperties
408 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900409 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900410 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900411 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900412
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900413 ///////////////////////////////////////////////////////////////////////////////////////////
414 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900415
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900416 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800417 publicKeyFile android.Path
418 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900419
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900420 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800421 containerCertificateFile android.Path
422 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900423
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900424 // Flags for special variants of APEX
425 testApex bool
426 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900427
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900428 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
429 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900430 primaryApexType bool
431
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900432 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900433 suffix string
434
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900435 // File system type of apex_payload.img
436 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900437
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900438 // Whether to create symlink to the system file instead of having a file inside the apex or
439 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900440 linkToSystemLib bool
441
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900442 // List of files to be included in this APEX. This is filled in the first part of
443 // GenerateAndroidBuildActions.
444 filesInfo []apexFile
445
446 // List of other module names that should be installed when this APEX gets installed.
447 requiredDeps []string
448
449 ///////////////////////////////////////////////////////////////////////////////////////////
450 // Outputs (final and intermediates)
451
452 // Processed apex manifest in JSONson format (for Q)
453 manifestJsonOut android.WritablePath
454
455 // Processed apex manifest in PB format (for R+)
456 manifestPbOut android.WritablePath
457
458 // Processed file_contexts files
459 fileContexts android.WritablePath
460
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900461 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900462 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900463 outputFile android.WritablePath
464
Jooyung Hana6d36672022-02-24 13:58:07 +0900465 // The built uncompressed .apex file.
466 outputApexFile android.WritablePath
467
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900468 // The built APEX file in app bundle format. This file is not directly installed to the
469 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
470 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
471 // system) to be merged into a single app bundle file that Play accepts. See
472 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
473 bundleModuleFile android.WritablePath
474
Colin Cross6340ea52021-11-04 12:01:18 -0700475 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900476 installDir android.InstallPath
477
Colin Cross6340ea52021-11-04 12:01:18 -0700478 // Path where this APEX was installed.
479 installedFile android.InstallPath
480
481 // Installed locations of symlinks for backward compatibility.
482 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900483
484 // Text file having the list of individual files that are included in this APEX. Used for
485 // debugging purpose.
486 installedFilesFile android.WritablePath
487
488 // List of module names that this APEX is including (to be shown via *-deps-info target).
489 // Used for debugging purpose.
490 android.ApexBundleDepsInfo
491
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900492 // Optional list of lint report zip files for apexes that contain java or app modules
493 lintReports android.Paths
494
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900495 prebuiltFileToDelete string
sophiezc80a2b32020-11-12 16:39:19 +0000496
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000497 isCompressed bool
498
sophiezc80a2b32020-11-12 16:39:19 +0000499 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700500 nativeApisUsedByModuleFile android.ModuleOutPath
501 nativeApisBackedByModuleFile android.ModuleOutPath
502 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800503
504 // Collect the module directory for IDE info in java/jdeps.go.
505 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900506}
507
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900508// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900509type apexFileClass int
510
Jooyung Han72bd2f82019-10-23 16:46:38 +0900511const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900512 app apexFileClass = iota
513 appSet
514 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900515 goBinary
516 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900517 nativeExecutable
518 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900519 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900520 pyBinary
521 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900522)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900523
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900524// apexFile represents a file in an APEX bundle. This is created during the first half of
525// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
526// of the function, this is used to create commands that copies the files into a staging directory,
527// where they are packaged into the APEX file. This struct is also used for creating Make modules
528// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900529type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900530 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000531 builtFile android.Path
532 installDir string
533 customStem string
534 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900535
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900536 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
537 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
538 // suffix>]
539 androidMkModuleName string // becomes LOCAL_MODULE
540 class apexFileClass // becomes LOCAL_MODULE_CLASS
541 moduleDir string // becomes LOCAL_PATH
542 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
543 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
544 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
545 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900546
547 jacocoReportClassesFile android.Path // only for javalibs and apps
548 lintDepSets java.LintDepSets // only for javalibs and apps
549 certificate java.Certificate // only for apps
550 overriddenPackageName string // only for apps
551
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900552 transitiveDep bool
553 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900554
Jiyong Park57621b22021-01-20 20:33:11 +0900555 multilib string
556
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900557 // TODO(jiyong): remove this
558 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900559}
560
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900561// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900562func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
563 ret := apexFile{
564 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900565 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900566 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900567 class: class,
568 module: module,
569 }
570 if module != nil {
571 ret.moduleDir = ctx.OtherModuleDir(module)
572 ret.requiredModuleNames = module.RequiredModuleNames()
573 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
574 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900575 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900576 }
577 return ret
578}
579
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900580func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900581 return af.builtFile != nil && af.builtFile.String() != ""
582}
583
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900584// apexRelativePath returns the relative path of the given path from the install directory of this
585// apexFile.
586// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900587func (af *apexFile) apexRelativePath(path string) string {
588 return filepath.Join(af.installDir, path)
589}
590
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900591// path returns path of this apex file relative to the APEX root
592func (af *apexFile) path() string {
593 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900594}
595
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900596// stem returns the base filename of this apex file
597func (af *apexFile) stem() string {
598 if af.customStem != "" {
599 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900600 }
601 return af.builtFile.Base()
602}
603
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900604// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
605func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900606 var ret []string
607 for _, symlink := range af.symlinks {
608 ret = append(ret, af.apexRelativePath(symlink))
609 }
610 return ret
611}
612
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900613// availableToPlatform tests whether this apexFile is from a module that can be installed to the
614// platform.
615func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900616 if af.module == nil {
617 return false
618 }
619 if am, ok := af.module.(android.ApexModule); ok {
620 return am.AvailableFor(android.AvailableToPlatform)
621 }
622 return false
623}
624
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900625////////////////////////////////////////////////////////////////////////////////////////////////////
626// Mutators
627//
628// Brief description about mutators for APEX. The following three mutators are the most important
629// ones.
630//
631// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
632// to the (direct) dependencies of this APEX bundle.
633//
Paul Duffin949abc02020-12-08 10:34:30 +0000634// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900635// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
636// modules are marked as being included in the APEX via BuildForApex().
637//
Paul Duffin949abc02020-12-08 10:34:30 +0000638// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
639// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900640
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900641type dependencyTag struct {
642 blueprint.BaseDependencyTag
643 name string
644
645 // Determines if the dependent will be part of the APEX payload. Can be false for the
646 // dependencies to the signing key module, etc.
647 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000648
649 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
650 // replacement. This is needed because some prebuilt modules do not provide all the information
651 // needed by the apex.
652 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000653
654 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
655 // also be added as exported members of that SDK.
656 memberType android.SdkMemberType
657}
658
659func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
660 return d.memberType
661}
662
663func (d *dependencyTag) ExportMember() bool {
664 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900665}
666
Paul Duffin520917a2022-05-13 13:01:59 +0000667func (d *dependencyTag) String() string {
668 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
669}
670
671func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000672 return !d.sourceOnly
673}
674
675var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000676var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000677
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900678var (
Paul Duffin520917a2022-05-13 13:01:59 +0000679 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
680 bpfTag = &dependencyTag{name: "bpf", payload: true}
681 certificateTag = &dependencyTag{name: "certificate"}
Dennis Shene2ed70c2023-01-11 14:15:43 +0000682 dclaTag = &dependencyTag{name: "dcla"}
Paul Duffin520917a2022-05-13 13:01:59 +0000683 executableTag = &dependencyTag{name: "executable", payload: true}
684 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000685 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
686 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000687 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000688 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
689 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
690 keyTag = &dependencyTag{name: "key"}
691 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
692 rroTag = &dependencyTag{name: "rro", payload: true}
693 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
694 testForTag = &dependencyTag{name: "test for"}
695 testTag = &dependencyTag{name: "test", payload: true}
696 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900697)
698
699// TODO(jiyong): shorten this function signature
700func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900701 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900702 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900703 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900704
705 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900706 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900707 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
708 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900709 }
710
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900711 // Use *FarVariation* to be able to depend on modules having conflicting variations with
712 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
713 // 'arm' or 'arm64' for native shared libs.
Colin Cross70572ed2022-11-02 13:14:20 -0700714 ctx.AddFarVariationDependencies(binVariations, executableTag,
715 android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
716 ctx.AddFarVariationDependencies(binVariations, testTag,
717 android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
718 ctx.AddFarVariationDependencies(libVariations, jniLibTag,
719 android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
720 ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
721 android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
722 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
723 android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
724 ctx.AddFarVariationDependencies(target.Variations(), fsTag,
725 android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900726}
727
728func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900729 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900730 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
731 } else {
732 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
733 if ctx.Os().Bionic() {
734 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
735 } else {
736 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
737 }
738 }
739}
740
Jooyung Hand045ebc2022-12-06 15:23:57 +0900741// getImageVariationPair returns a pair for the image variation name as its
742// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
743// suffix indicates the vndk version when it's vendor or product.
744// getImageVariation can simply join the result of this function to get the
745// image variation name.
746func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900747 if a.vndkApex {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900748 return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900749 }
750
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900751 var prefix string
752 var vndkVersion string
753 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000754 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900755 prefix = cc.VendorVariationPrefix
756 vndkVersion = deviceConfig.VndkVersion()
757 } else if a.ProductSpecific() {
758 prefix = cc.ProductVariationPrefix
759 vndkVersion = deviceConfig.ProductVndkVersion()
760 }
761 }
762 if vndkVersion == "current" {
763 vndkVersion = deviceConfig.PlatformVndkVersion()
764 }
765 if vndkVersion != "" {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900766 return prefix, vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900767 }
768
Jooyung Hand045ebc2022-12-06 15:23:57 +0900769 return android.CoreVariation, "" // The usual case
770}
771
772// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
773// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
774func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
775 prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
776 return prefix + vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900777}
778
779func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900780 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
781 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
782 // each target os/architectures, appropriate dependencies are selected by their
783 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900784 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900785 imageVariation := a.getImageVariation(ctx)
786
787 a.combineProperties(ctx)
788
789 has32BitTarget := false
790 for _, target := range targets {
791 if target.Arch.ArchType.Multilib == "lib32" {
792 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000793 }
794 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900795 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900796 // Don't include artifacts for the host cross targets because there is no way for us
797 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900798 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900799 continue
800 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000801
Colin Cross70572ed2022-11-02 13:14:20 -0700802 var deps ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000803
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900804 // Add native modules targeting both ABIs. When multilib.* is omitted for
805 // native_shared_libs/jni_libs/tests, it implies multilib.both
Colin Cross70572ed2022-11-02 13:14:20 -0700806 deps.Merge(a.properties.Multilib.Both)
807 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900808 Native_shared_libs: a.properties.Native_shared_libs,
809 Tests: a.properties.Tests,
810 Jni_libs: a.properties.Jni_libs,
811 Binaries: nil,
812 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900813
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900814 // Add native modules targeting the first ABI When multilib.* is omitted for
815 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900816 isPrimaryAbi := i == 0
817 if isPrimaryAbi {
Colin Cross70572ed2022-11-02 13:14:20 -0700818 deps.Merge(a.properties.Multilib.First)
819 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900820 Native_shared_libs: nil,
821 Tests: nil,
822 Jni_libs: nil,
823 Binaries: a.properties.Binaries,
824 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900825 }
826
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900827 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900828 switch target.Arch.ArchType.Multilib {
829 case "lib32":
Colin Cross70572ed2022-11-02 13:14:20 -0700830 deps.Merge(a.properties.Multilib.Lib32)
831 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900832 case "lib64":
Colin Cross70572ed2022-11-02 13:14:20 -0700833 deps.Merge(a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900834 if !has32BitTarget {
Colin Cross70572ed2022-11-02 13:14:20 -0700835 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900836 }
837 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900838
Jiyong Park59140302020-12-14 18:44:04 +0900839 // Add native modules targeting a specific arch variant
840 switch target.Arch.ArchType {
841 case android.Arm:
Colin Cross70572ed2022-11-02 13:14:20 -0700842 deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900843 case android.Arm64:
Colin Cross70572ed2022-11-02 13:14:20 -0700844 deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700845 case android.Riscv64:
Colin Cross70572ed2022-11-02 13:14:20 -0700846 deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900847 case android.X86:
Colin Cross70572ed2022-11-02 13:14:20 -0700848 deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900849 case android.X86_64:
Colin Cross70572ed2022-11-02 13:14:20 -0700850 deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900851 default:
852 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
853 }
854
Colin Cross70572ed2022-11-02 13:14:20 -0700855 addDependenciesForNativeModules(ctx, deps, target, imageVariation)
Sundong Ahn80c04892021-11-23 00:57:19 +0000856 ctx.AddFarVariationDependencies([]blueprint.Variation{
857 {Mutator: "os", Variation: target.OsVariation()},
858 {Mutator: "arch", Variation: target.ArchVariation()},
859 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900860 }
861
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900862 // Common-arch dependencies come next
863 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900864 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000865 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100866}
867
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900868// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900869func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
870 if a.overridableProperties.Allowed_files != nil {
871 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100872 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900873
874 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
875 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800876 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900877 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900878 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
879 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
880 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700881 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
882 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
883 // regardless of the TARGET_PREFER_* setting. See b/144532908
884 arches := ctx.DeviceConfig().Arches()
885 if len(arches) != 0 {
886 archForPrebuiltEtc := arches[0]
887 for _, arch := range arches {
888 // Prefer 64-bit arch if there is any
889 if arch.ArchType.Multilib == "lib64" {
890 archForPrebuiltEtc = arch
891 break
892 }
893 }
894 ctx.AddFarVariationDependencies([]blueprint.Variation{
895 {Mutator: "os", Variation: ctx.Os().String()},
896 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
897 }, prebuiltTag, prebuilts...)
898 }
899 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700900
901 // Dependencies for signing
902 if String(a.overridableProperties.Key) == "" {
903 ctx.PropertyErrorf("key", "missing")
904 return
905 }
906 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
907
908 cert := android.SrcIsModule(a.getCertString(ctx))
909 if cert != "" {
910 ctx.AddDependency(ctx.Module(), certificateTag, cert)
911 // empty cert is not an error. Cert and private keys will be directly found under
912 // PRODUCT_DEFAULT_DEV_CERTIFICATE
913 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100914}
915
Dennis Shene2ed70c2023-01-11 14:15:43 +0000916func apexDCLADepsMutator(mctx android.BottomUpMutatorContext) {
917 if !mctx.Config().ApexTrimEnabled() {
918 return
919 }
920 if a, ok := mctx.Module().(*apexBundle); ok && a.overridableProperties.Trim_against != nil {
921 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
922 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(a.overridableProperties.Trim_against))
923 } else if o, ok := mctx.Module().(*OverrideApex); ok {
924 for _, p := range o.GetProperties() {
925 properties, ok := p.(*overridableProperties)
926 if !ok {
927 continue
928 }
929 if properties.Trim_against != nil {
930 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
931 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(properties.Trim_against))
932 }
933 }
934 }
935}
936
937type DCLAInfo struct {
938 ProvidedLibs []string
939}
940
941var DCLAInfoProvider = blueprint.NewMutatorProvider(DCLAInfo{}, "apex_info")
942
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900943type ApexBundleInfo struct {
944 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100945}
946
Paul Duffin949abc02020-12-08 10:34:30 +0000947var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900948
Paul Duffina7d6a892020-12-07 17:39:59 +0000949var _ ApexInfoMutator = (*apexBundle)(nil)
950
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100951func (a *apexBundle) ApexVariationName() string {
952 return a.properties.ApexVariationName
953}
954
Paul Duffina7d6a892020-12-07 17:39:59 +0000955// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900956// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
957// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
958// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
959// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000960//
961// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
962// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
963// The apexMutator uses that list to create module variants for the apexes to which it belongs.
964// The relationship between module variants and apexes is not one-to-one as variants will be
965// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000966func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900967
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900968 // The VNDK APEX is special. For the APEX, the membership is described in a very different
969 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
970 // libraries are self-identified by their vndk.enabled properties. There is no need to run
971 // this mutator for the APEX as nothing will be collected. So, let's return fast.
972 if a.vndkApex {
973 return
974 }
975
976 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
977 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
978 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
979 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
980 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900981 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
982 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900983 if proptools.Bool(a.properties.Use_vndk_as_stable) {
984 if !useVndk {
985 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
986 }
987 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
988 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
989 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
990 }
991 })
992 if mctx.Failed() {
993 return
994 }
Jooyung Handf78e212020-07-22 15:54:47 +0900995 }
996
Colin Cross56a83212020-09-15 18:30:11 -0700997 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900998 am, ok := child.(android.ApexModule)
999 if !ok || !am.CanHaveApexVariants() {
1000 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +09001001 }
Paul Duffin573989d2021-03-17 13:25:29 +00001002 depTag := mctx.OtherModuleDependencyTag(child)
1003
1004 // Check to see if the tag always requires that the child module has an apex variant for every
1005 // apex variant of the parent module. If it does not then it is still possible for something
1006 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
1007 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
1008 return true
1009 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001010 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +09001011 return false
1012 }
Jooyung Handf78e212020-07-22 15:54:47 +09001013 if excludeVndkLibs {
1014 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
1015 return false
1016 }
1017 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001018 // By default, all the transitive dependencies are collected, unless filtered out
1019 // above.
Colin Cross56a83212020-09-15 18:30:11 -07001020 return true
1021 }
1022
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001023 // Records whether a certain module is included in this apexBundle via direct dependency or
1024 // inndirect dependency.
1025 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -07001026 mctx.WalkDeps(func(child, parent android.Module) bool {
1027 if !continueApexDepsWalk(child, parent) {
1028 return false
1029 }
Jooyung Han698dd9f2020-07-22 15:17:19 +09001030 // If the parent is apexBundle, this child is directly depended.
1031 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001032 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -07001033 contents[depName] = contents[depName].Add(directDep)
1034 return true
1035 })
1036
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001037 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +09001038 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -07001039 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
1040 Contents: apexContents,
1041 })
1042
Jooyung Haned124c32021-01-26 11:43:46 +09001043 minSdkVersion := a.minSdkVersion(mctx)
1044 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
1045 if minSdkVersion.IsNone() {
1046 minSdkVersion = android.FutureApiLevel
1047 }
1048
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001049 // This is the main part of this mutator. Mark the collected dependencies that they need to
1050 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +09001051
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001052 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
1053 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -07001054 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001055 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +09001056 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -07001057 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +09001058 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001059 InApexVariants: []string{apexVariationName},
1060 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -07001061 ApexContents: []*android.ApexContents{apexContents},
1062 }
Colin Cross56a83212020-09-15 18:30:11 -07001063 mctx.WalkDeps(func(child, parent android.Module) bool {
1064 if !continueApexDepsWalk(child, parent) {
1065 return false
1066 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001067 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +09001068 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +09001069 })
Dennis Shene2ed70c2023-01-11 14:15:43 +00001070
1071 if a.dynamic_common_lib_apex() {
1072 mctx.SetProvider(DCLAInfoProvider, DCLAInfo{
1073 ProvidedLibs: a.properties.Native_shared_libs,
1074 })
1075 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001076}
1077
Paul Duffina7d6a892020-12-07 17:39:59 +00001078type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001079 // ApexVariationName returns the name of the APEX variation to use in the apex
1080 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
1081 ApexVariationName() string
1082
Paul Duffina7d6a892020-12-07 17:39:59 +00001083 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1084 // depended upon by an apex and which require an apex specific variant.
1085 ApexInfoMutator(android.TopDownMutatorContext)
1086}
1087
1088// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1089// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001090// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001091func apexInfoMutator(mctx android.TopDownMutatorContext) {
1092 if !mctx.Module().Enabled() {
1093 return
1094 }
1095
1096 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1097 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001098 }
Spandan Das42e89502022-05-06 22:12:55 +00001099 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001100}
1101
Spandan Das66773252022-01-15 00:23:18 +00001102// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1103// This check is enforced for updatable modules
1104func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1105 if !mctx.Module().Enabled() {
1106 return
1107 }
Spandan Das08c911f2022-01-21 22:07:26 +00001108 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001109 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001110 // b/208656169 Do not propagate strict updatability linting to libcore/
1111 // These libs are available on the classpath during compilation
1112 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1113 // Only skip libraries defined in libcore root, not subdirectories
1114 if mctx.OtherModuleDir(child) == "libcore" {
1115 // Do not traverse transitive deps of libcore/ libs
1116 return false
1117 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001118 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1119 return false
1120 }
Spandan Das66773252022-01-15 00:23:18 +00001121 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1122 lintable.SetStrictUpdatabilityLinting(true)
1123 }
1124 // visit transitive deps
1125 return true
1126 })
1127 }
1128}
1129
Spandan Das42e89502022-05-06 22:12:55 +00001130// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1131func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1132 if !mctx.Module().Enabled() {
1133 return
1134 }
1135 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1136 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1137 mctx.VisitDirectDeps(func(module android.Module) {
1138 // ignore android_test_app
1139 if app, ok := module.(*java.AndroidApp); ok {
1140 app.SetUpdatable(true)
1141 }
1142 })
1143 }
1144}
1145
Spandan Das08c911f2022-01-21 22:07:26 +00001146// TODO: b/215736885 Whittle the denylist
1147// Transitive deps of certain mainline modules baseline NewApi errors
1148// Skip these mainline modules for now
1149var (
1150 skipStrictUpdatabilityLintAllowlist = []string{
1151 "com.android.art",
1152 "com.android.art.debug",
1153 "com.android.conscrypt",
1154 "com.android.media",
1155 // test apexes
1156 "test_com.android.art",
1157 "test_com.android.conscrypt",
1158 "test_com.android.media",
1159 "test_jitzygote_com.android.art",
1160 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001161
1162 // TODO: b/215736885 Remove this list
1163 skipLintJavalibAllowlist = []string{
1164 "conscrypt.module.platform.api.stubs",
1165 "conscrypt.module.public.api.stubs",
1166 "conscrypt.module.public.api.stubs.system",
1167 "conscrypt.module.public.api.stubs.module_lib",
1168 "framework-media.stubs",
1169 "framework-media.stubs.system",
1170 "framework-media.stubs.module_lib",
1171 }
Spandan Das08c911f2022-01-21 22:07:26 +00001172)
1173
1174func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1175 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1176}
1177
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001178// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1179// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1180// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001181func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1182 if !mctx.Module().Enabled() {
1183 return
1184 }
1185 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001186 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1187 }
1188}
1189
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001190// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1191// the apex in order to retrieve its contents later.
1192// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001193func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1194 if !mctx.Module().Enabled() {
1195 return
1196 }
Colin Cross56a83212020-09-15 18:30:11 -07001197 if am, ok := mctx.Module().(android.ApexModule); ok {
1198 if testFor := am.TestFor(); len(testFor) > 0 {
1199 mctx.AddFarVariationDependencies([]blueprint.Variation{
1200 {Mutator: "os", Variation: am.Target().OsVariation()},
1201 {"arch", "common"},
1202 }, testForTag, testFor...)
1203 }
1204 }
1205}
1206
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001207// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001208func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1209 if !mctx.Module().Enabled() {
1210 return
1211 }
Colin Cross56a83212020-09-15 18:30:11 -07001212 if _, ok := mctx.Module().(android.ApexModule); ok {
1213 var contents []*android.ApexContents
1214 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1215 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1216 contents = append(contents, abInfo.Contents)
1217 }
1218 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1219 ApexContents: contents,
1220 })
Colin Crossaede88c2020-08-11 12:17:01 -07001221 }
1222}
1223
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001224// markPlatformAvailability marks whether or not a module can be available to platform. A module
1225// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1226// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1227// be) available to platform
1228// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001229func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1230 // Host and recovery are not considered as platform
1231 if mctx.Host() || mctx.Module().InstallInRecovery() {
1232 return
1233 }
1234
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001235 am, ok := mctx.Module().(android.ApexModule)
1236 if !ok {
1237 return
1238 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001239
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001240 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001241
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001242 // If any of the dep is not available to platform, this module is also considered as being
1243 // not available to platform even if it has "//apex_available:platform"
1244 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001245 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001246 // if the dependency crosses apex boundary, don't consider it
1247 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001248 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001249 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1250 availableToPlatform = false
1251 // TODO(b/154889534) trigger an error when 'am' has
1252 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001253 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001254 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001255
Paul Duffinb5769c12021-05-12 16:16:51 +01001256 // Exception 1: check to see if the module always requires it.
1257 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001258 availableToPlatform = true
1259 }
1260
1261 // Exception 2: bootstrap bionic libraries are also always available to platform
1262 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1263 availableToPlatform = true
1264 }
1265
1266 if !availableToPlatform {
1267 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001268 }
1269}
1270
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001271// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001272// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001273func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001274 if !mctx.Module().Enabled() {
1275 return
1276 }
Colin Cross56a83212020-09-15 18:30:11 -07001277
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001278 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001279 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001280 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001281 return
1282 }
1283
1284 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001285 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1286 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001287 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001288 if strings.HasPrefix(apexBundleName, "com.android.art") {
1289 // Create an alias from the platform variant. This is done to make
1290 // test_for dependencies work for modules that are split by the APEX
1291 // mutator, since test_for dependencies always go to the platform variant.
1292 // This doesn't happen for normal APEXes that are disjunct, so only do
1293 // this for the overlapping ART APEXes.
1294 // TODO(b/183882457): Remove this if the test_for functionality is
1295 // refactored to depend on the proper APEX variants instead of platform.
1296 mctx.CreateAliasVariation("", apexBundleName)
1297 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001298 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1299 apexBundleName := o.GetOverriddenModuleName()
1300 if apexBundleName == "" {
1301 mctx.ModuleErrorf("base property is not set")
1302 return
1303 }
1304 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001305 if strings.HasPrefix(apexBundleName, "com.android.art") {
1306 // TODO(b/183882457): See note for CreateAliasVariation above.
1307 mctx.CreateAliasVariation("", apexBundleName)
1308 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001309 }
1310}
Sundong Ahne9b55722019-09-06 17:37:42 +09001311
Paul Duffin6717d882021-06-15 19:09:41 +01001312// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1313// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001314func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001315 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001316 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001317 return !a.vndkApex
1318 }
1319
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001320 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001321}
1322
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001323// See android.UpdateDirectlyInAnyApex
1324// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001325func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1326 if !mctx.Module().Enabled() {
1327 return
1328 }
1329 if am, ok := mctx.Module().(android.ApexModule); ok {
1330 android.UpdateDirectlyInAnyApex(mctx, am)
1331 }
1332}
1333
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001334// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001335type apexPackaging int
1336
1337const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001338 // imageApex is a packaging method where contents are included in a filesystem image which
1339 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001340 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001341
1342 // zipApex is a packaging method where contents are directly included in the zip container.
1343 // This is used for host-side testing - because the contents are easily accessible by
1344 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001345 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001346
1347 // flattendApex is a packaging method where contents are not included in the APEX file, but
1348 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1349 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001350 flattenedApex
1351)
1352
1353const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001354 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001355 imageApexSuffix = ".apex"
1356 imageCapexSuffix = ".capex"
1357 zipApexSuffix = ".zipapex"
1358 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001359
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001360 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001361 imageApexType = "image"
1362 zipApexType = "zip"
1363 flattenedApexType = "flattened"
1364
Dan Willemsen47e1a752021-10-16 18:36:13 -07001365 ext4FsType = "ext4"
1366 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001367 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001368)
1369
1370// The suffix for the output "file", not the module
1371func (a apexPackaging) suffix() string {
1372 switch a {
1373 case imageApex:
1374 return imageApexSuffix
1375 case zipApex:
1376 return zipApexSuffix
1377 default:
1378 panic(fmt.Errorf("unknown APEX type %d", a))
1379 }
1380}
1381
1382func (a apexPackaging) name() string {
1383 switch a {
1384 case imageApex:
1385 return imageApexType
1386 case zipApex:
1387 return zipApexType
1388 default:
1389 panic(fmt.Errorf("unknown APEX type %d", a))
1390 }
1391}
1392
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001393// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1394// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001395func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001396 if !mctx.Module().Enabled() {
1397 return
1398 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001399 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001400 var variants []string
1401 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1402 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001403 // This is the normal case. Note that both image and flattend APEXes are
1404 // created. The image type is installed to the system partition, while the
1405 // flattened APEX is (optionally) installed to the system_ext partition.
1406 // This is mostly for GSI which has to support wide range of devices. If GSI
1407 // is installed on a newer (APEX-capable) device, the image APEX in the
1408 // system will be used. However, if the same GSI is installed on an old
1409 // device which can't support image APEX, the flattened APEX in the
1410 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001411 variants = append(variants, imageApexType, flattenedApexType)
1412 case "zip":
1413 variants = append(variants, zipApexType)
1414 case "both":
1415 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1416 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001417 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001418 return
1419 }
1420
1421 modules := mctx.CreateLocalVariations(variants...)
1422
1423 for i, v := range variants {
1424 switch v {
1425 case imageApexType:
1426 modules[i].(*apexBundle).properties.ApexType = imageApex
1427 case zipApexType:
1428 modules[i].(*apexBundle).properties.ApexType = zipApex
1429 case flattenedApexType:
1430 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001431 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001432 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001433 modules[i].(*apexBundle).MakeAsSystemExt()
1434 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001435 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001436 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001437 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001438 // payload_type is forcibly overridden to "image"
1439 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001440 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001441 }
1442}
1443
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001444var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001445
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001446// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001447func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001448 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001449 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001450 return true
1451}
1452
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001453var _ android.OutputFileProducer = (*apexBundle)(nil)
1454
1455// Implements android.OutputFileProducer
1456func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1457 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001458 case "", android.DefaultDistTag:
1459 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001460 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001461 case imageApexSuffix:
1462 // uncompressed one
1463 if a.outputApexFile != nil {
1464 return android.Paths{a.outputApexFile}, nil
1465 }
1466 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001467 default:
1468 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1469 }
1470}
1471
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001472var _ multitree.Exportable = (*apexBundle)(nil)
1473
1474func (a *apexBundle) Exportable() bool {
1475 if a.properties.ApexType == flattenedApex {
1476 return false
1477 }
1478 return true
1479}
1480
1481func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1482 ret := make(map[string]android.Paths)
1483 ret["apex"] = android.Paths{a.outputFile}
1484 return ret
1485}
1486
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001487var _ cc.Coverage = (*apexBundle)(nil)
1488
1489// Implements cc.Coverage
1490func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1491 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1492}
1493
1494// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001495func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001496 a.properties.PreventInstall = true
1497}
1498
1499// Implements cc.Coverage
1500func (a *apexBundle) HideFromMake() {
1501 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001502 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1503 // TODO(ccross): untangle these
1504 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001505}
1506
1507// Implements cc.Coverage
1508func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1509 a.properties.IsCoverageVariant = coverage
1510}
1511
1512// Implements cc.Coverage
1513func (a *apexBundle) EnableCoverageIfNeeded() {}
1514
1515var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1516
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001517// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001518func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001519 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001520}
1521
Jiyong Parkf4020582021-11-29 12:37:10 +09001522func (a *apexBundle) FutureUpdatable() bool {
1523 return proptools.BoolDefault(a.properties.Future_updatable, false)
1524}
1525
Jiyong Park1bc84122021-06-22 20:23:05 +09001526func (a *apexBundle) UsePlatformApis() bool {
1527 return proptools.BoolDefault(a.properties.Platform_apis, false)
1528}
1529
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001530// getCertString returns the name of the cert that should be used to sign this APEX. This is
1531// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001532func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001533 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001534 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1535 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1536 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001537 if a.vndkApex {
1538 moduleName = vndkApexName
1539 }
1540 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001541 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001542 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001543 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001544 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001545}
1546
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001547// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001548func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001549 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001550}
1551
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001552// See the generate_hashtree property
1553func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001554 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001555}
1556
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001557// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001558func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1559 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1560}
1561
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001562// See the test_only_force_compression property
1563func (a *apexBundle) testOnlyShouldForceCompression() bool {
1564 return proptools.Bool(a.properties.Test_only_force_compression)
1565}
1566
Dennis Shenaf41bc12022-08-03 16:46:43 +00001567// See the dynamic_common_lib_apex property
1568func (a *apexBundle) dynamic_common_lib_apex() bool {
1569 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1570}
1571
Dennis Shene2ed70c2023-01-11 14:15:43 +00001572// See the list of libs to trim
1573func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string {
1574 dclaModules := ctx.GetDirectDepsWithTag(dclaTag)
1575 if len(dclaModules) > 1 {
1576 panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules)))
1577 }
1578 if len(dclaModules) > 0 {
1579 DCLAInfo := ctx.OtherModuleProvider(dclaModules[0], DCLAInfoProvider).(DCLAInfo)
1580 return DCLAInfo.ProvidedLibs
1581 }
1582 return []string{}
1583}
1584
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001585// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1586// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1587// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001588
Jiyong Parkf97782b2019-02-13 20:28:58 +09001589func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1590 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1591 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1592 }
1593}
1594
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001595func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001596 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1597 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001598 }
1599
1600 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001601 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001602 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001603 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001604 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001605 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001606 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001607 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001608 }
1609 }
1610 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001611}
1612
Jooyung Han8ce8db92020-05-15 19:05:05 +09001613func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001614 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1615 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001616 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001617 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001618 for _, target := range ctx.MultiTargets() {
1619 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001620 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001621 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001622 Tests: nil,
1623 Jni_libs: nil,
1624 Binaries: nil,
1625 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001626 break
1627 }
1628 }
1629 }
1630}
1631
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001632// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1633// returned apexFile saves information about the Soong module that will be used for creating the
1634// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001635func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001636 // Decide the APEX-local directory by the multilib of the library In the future, we may
1637 // query this to the module.
1638 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001639 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001640 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001641 case "lib32":
1642 dirInApex = "lib"
1643 case "lib64":
1644 dirInApex = "lib64"
1645 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001646 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001647 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001648 }
Jooyung Han35155c42020-02-06 17:33:20 +09001649 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001650 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001651 // Special case for Bionic libs and other libs installed with them. This is to
1652 // prevent those libs from being included in the search path
1653 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1654 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1655 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1656 // will be loaded into the default linker namespace (aka "platform" namespace). If
1657 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1658 // be loaded again into the runtime linker namespace, which will result in double
1659 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001660 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001661 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001662
Colin Cross1d487152022-10-03 19:14:46 -07001663 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001664 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1665 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001666}
1667
Jiyong Park1833cef2019-12-13 13:28:36 +09001668func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001669 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001670 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001671 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001672 }
Jooyung Han35155c42020-02-06 17:33:20 +09001673 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001674 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001675 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1676 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001677 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001678 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001679 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001680}
1681
Jiyong Park99644e92020-11-17 22:21:02 +09001682func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1683 dirInApex := "bin"
1684 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1685 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1686 }
Colin Cross1d487152022-10-03 19:14:46 -07001687 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001688 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1689 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1690 return af
1691}
1692
1693func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1694 // Decide the APEX-local directory by the multilib of the library
1695 // In the future, we may query this to the module.
1696 var dirInApex string
1697 switch rustm.Arch().ArchType.Multilib {
1698 case "lib32":
1699 dirInApex = "lib"
1700 case "lib64":
1701 dirInApex = "lib64"
1702 }
1703 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1704 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1705 }
Colin Cross1d487152022-10-03 19:14:46 -07001706 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001707 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1708 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1709}
1710
Jiyong Park1833cef2019-12-13 13:28:36 +09001711func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001712 dirInApex := "bin"
1713 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001714 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001715}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001716
Jiyong Park1833cef2019-12-13 13:28:36 +09001717func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001718 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001719 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001720 // NB: Since go binaries are static we don't need the module for anything here, which is
1721 // good since the go tool is a blueprint.Module not an android.Module like we would
1722 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001723 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001724}
1725
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001726func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001727 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001728 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1729 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1730 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001731 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001732 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001733 af.symlinks = sh.Symlinks()
1734 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001735}
1736
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001737func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001738 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001739 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001740 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001741}
1742
atrost6e126252020-01-27 17:01:16 +00001743func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1744 dirInApex := filepath.Join("etc", config.SubDir())
1745 fileToCopy := config.CompatConfig()
1746 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1747}
1748
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001749// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1750// way.
1751type javaModule interface {
1752 android.Module
1753 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001754 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001755 JacocoReportClassesFile() android.Path
1756 LintDepSets() java.LintDepSets
1757 Stem() string
1758}
1759
1760var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001761var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001762var _ javaModule = (*java.SdkLibrary)(nil)
1763var _ javaModule = (*java.DexImport)(nil)
1764var _ javaModule = (*java.SdkLibraryImport)(nil)
1765
Paul Duffin190fdef2021-04-26 10:33:59 +01001766// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001767func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001768 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001769}
1770
1771// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1772func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001773 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001774 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001775 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1776 af.lintDepSets = module.LintDepSets()
1777 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001778 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1779 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1780 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1781 }
1782 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001783 return af
1784}
1785
1786// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1787// the same way.
1788type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001789 android.Module
1790 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001791 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001792 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001793 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001794 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001795 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001796 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001797}
1798
1799var _ androidApp = (*java.AndroidApp)(nil)
1800var _ androidApp = (*java.AndroidAppImport)(nil)
1801
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001802func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1803 buildId := ctx.Config().BuildId()
1804
1805 // The build ID is used as a suffix for a filename, so ensure that
1806 // the set of characters being used are sanitized.
1807 // - any word character: [a-zA-Z0-9_]
1808 // - dots: .
1809 // - dashes: -
1810 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1811 if !validRegex.MatchString(buildId) {
1812 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1813 }
1814 return buildId
1815}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001816
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001817func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001818 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001819 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001820 appDir = "priv-app"
1821 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001822
1823 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1824 // so that PackageManager correctly invalidates the existing installed apk
1825 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001826 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001827 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001828
Yo Chiange8128052020-07-23 20:09:18 +08001829 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001830 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001831 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001832 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001833
1834 if app, ok := aapp.(interface {
1835 OverriddenManifestPackageName() string
1836 }); ok {
1837 af.overriddenPackageName = app.OverriddenManifestPackageName()
1838 }
Jiyong Park618922e2020-01-08 13:35:43 +09001839 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001840}
1841
Jiyong Park69aeba92020-04-24 21:16:36 +09001842func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1843 rroDir := "overlay"
1844 dirInApex := filepath.Join(rroDir, rro.Theme())
1845 fileToCopy := rro.OutputFile()
1846 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1847 af.certificate = rro.Certificate()
1848
1849 if a, ok := rro.(interface {
1850 OverriddenManifestPackageName() string
1851 }); ok {
1852 af.overriddenPackageName = a.OverriddenManifestPackageName()
1853 }
1854 return af
1855}
1856
Ken Chenfad7f9d2021-11-10 22:02:57 +08001857func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1858 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001859 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1860}
1861
Jiyong Park12a719c2021-01-07 15:31:24 +09001862func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1863 dirInApex := filepath.Join("etc", "fs")
1864 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1865}
1866
Paul Duffin064b70c2020-11-02 17:32:38 +00001867// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001868// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1869// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1870// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001871func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001872 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001873 am, ok := child.(android.ApexModule)
1874 if !ok || !am.CanHaveApexVariants() {
1875 return false
1876 }
1877
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001878 // Filter-out unwanted depedendencies
1879 depTag := ctx.OtherModuleDependencyTag(child)
1880 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1881 return false
1882 }
Paul Duffin520917a2022-05-13 13:01:59 +00001883 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001884 return false
1885 }
1886
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001887 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001888 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001889
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001890 // Visit actually
1891 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001892 })
1893}
1894
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001895// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1896type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001897
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001898const (
1899 ext4 fsType = iota
1900 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001901 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001902)
Artur Satayev849f8442020-04-28 14:57:42 +01001903
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001904func (f fsType) string() string {
1905 switch f {
1906 case ext4:
1907 return ext4FsType
1908 case f2fs:
1909 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001910 case erofs:
1911 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001912 default:
1913 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001914 }
1915}
1916
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001917var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1918
1919func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1920 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1921}
1922
1923func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1924 bazelCtx := ctx.Config().BazelContext
1925 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1926}
1927
Jingwen Chen889f2f22022-12-16 08:16:01 +00001928// GetBazelLabel returns the bazel label of this apexBundle, or the label of the
1929// override_apex module overriding this apexBundle. An apexBundle can be
1930// overridden by different override_apex modules (e.g. Google or Go variants),
1931// which is handled by the overrides mutators.
1932func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string {
1933 if _, ok := ctx.Module().(android.OverridableModule); ok {
1934 return android.MaybeBp2buildLabelOfOverridingModule(ctx)
1935 }
1936 return a.BazelModuleBase.GetBazelLabel(ctx, a)
1937}
1938
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001939func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1940 if !a.commonBuildActions(ctx) {
1941 return
1942 }
1943
1944 a.setApexTypeAndSuffix(ctx)
1945 a.setPayloadFsType(ctx)
1946 a.setSystemLibLink(ctx)
1947
1948 if a.properties.ApexType != zipApex {
1949 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1950 }
1951
1952 bazelCtx := ctx.Config().BazelContext
1953 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1954 if err != nil {
1955 ctx.ModuleErrorf(err.Error())
1956 return
1957 }
1958 a.installDir = android.PathForModuleInstall(ctx, "apex")
1959 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1960 a.outputFile = a.outputApexFile
1961 a.setCompression(ctx)
1962
Liz Kammer0e255ef2022-11-04 16:07:04 -04001963 // TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
1964 // interface if these were set in a provider rather than the module itself
Wei Li32dcdf92022-10-26 22:30:48 -07001965 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1966 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1967 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1968 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Liz Kammer0e255ef2022-11-04 16:07:04 -04001969
Vinh Tranb6803a52022-12-14 11:34:54 -05001970 // Ensure ApexInfo.RequiresLibs are installed as part of a bundle build
1971 for _, bazelLabel := range outputs.RequiresLibs {
1972 // convert Bazel label back to Soong module name
1973 a.requiredDeps = append(a.requiredDeps, android.ModuleFromBazelLabel(bazelLabel))
1974 }
1975
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001976 apexType := a.properties.ApexType
1977 switch apexType {
1978 case imageApex:
Liz Kammer303978d2022-11-04 16:12:43 -04001979 a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001980 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
Wei Licc73a052022-11-07 14:25:34 -08001981 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001982 // TODO(b/239084755): Generate the java api using.xml file from Bazel.
Jingwen Chen1ec77852022-11-07 14:36:12 +00001983 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
Wei Li78c07de2022-11-08 16:01:05 -08001984 a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001985 installSuffix := imageApexSuffix
1986 if a.isCompressed {
1987 installSuffix = imageCapexSuffix
1988 }
1989 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1990 a.compatSymlinks.Paths()...)
1991 default:
1992 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1993 }
1994
1995 /*
1996 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1997 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1998 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1999 To find out what Soong build puts there, run:
2000 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2001 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
2002 return a.depVisitor(&vctx, ctx, child, parent)
2003 })
2004 vctx.normalizeFileInfo()
2005 */
2006
2007}
2008
2009func (a *apexBundle) setCompression(ctx android.ModuleContext) {
2010 if a.properties.ApexType != imageApex {
2011 a.isCompressed = false
2012 } else if a.testOnlyShouldForceCompression() {
2013 a.isCompressed = true
2014 } else {
2015 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
2016 }
2017}
2018
2019func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
2020 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
2021 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
2022 // the same library in the system partition, thus effectively sharing the same libraries
2023 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
2024 // in the APEX.
2025 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
2026
2027 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
2028 // So we can't link them to /system/lib libs which are core variants.
2029 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2030 a.linkToSystemLib = false
2031 }
2032
2033 forced := ctx.Config().ForceApexSymlinkOptimization()
2034 updatable := a.Updatable() || a.FutureUpdatable()
2035
2036 // We don't need the optimization for updatable APEXes, as it might give false signal
2037 // to the system health when the APEXes are still bundled (b/149805758).
2038 if !forced && updatable && a.properties.ApexType == imageApex {
2039 a.linkToSystemLib = false
2040 }
2041
2042 // We also don't want the optimization for host APEXes, because it doesn't make sense.
2043 if ctx.Host() {
2044 a.linkToSystemLib = false
2045 }
2046}
2047
2048func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
2049 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
2050 case ext4FsType:
2051 a.payloadFsType = ext4
2052 case f2fsFsType:
2053 a.payloadFsType = f2fs
2054 case erofsFsType:
2055 a.payloadFsType = erofs
2056 default:
2057 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
2058 }
2059}
2060
2061func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
2062 // Set suffix and primaryApexType depending on the ApexType
2063 buildFlattenedAsDefault := ctx.Config().FlattenApex()
2064 switch a.properties.ApexType {
2065 case imageApex:
2066 if buildFlattenedAsDefault {
2067 a.suffix = imageApexSuffix
2068 } else {
2069 a.suffix = ""
2070 a.primaryApexType = true
2071
2072 if ctx.Config().InstallExtraFlattenedApexes() {
2073 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
2074 }
2075 }
2076 case zipApex:
2077 if proptools.String(a.properties.Payload_type) == "zip" {
2078 a.suffix = ""
2079 a.primaryApexType = true
2080 } else {
2081 a.suffix = zipApexSuffix
2082 }
2083 case flattenedApex:
2084 if buildFlattenedAsDefault {
2085 a.suffix = ""
2086 a.primaryApexType = true
2087 } else {
2088 a.suffix = flattenedSuffix
2089 }
2090 }
2091}
2092
2093func (a apexBundle) isCompressable() bool {
2094 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
2095}
2096
2097func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
2098 a.checkApexAvailability(ctx)
2099 a.checkUpdatable(ctx)
2100 a.CheckMinSdkVersion(ctx)
2101 a.checkStaticLinkingToStubLibraries(ctx)
2102 a.checkStaticExecutables(ctx)
2103 if len(a.properties.Tests) > 0 && !a.testApex {
2104 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
2105 return false
2106 }
2107 return true
2108}
2109
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002110type visitorContext struct {
2111 // all the files that will be included in this APEX
2112 filesInfo []apexFile
2113
2114 // native lib dependencies
2115 provideNativeLibs []string
2116 requireNativeLibs []string
2117
2118 handleSpecialLibs bool
Jooyung Han862c0d62022-12-21 10:15:37 +09002119
2120 // if true, raise error on duplicate apexFile
2121 checkDuplicate bool
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002122}
2123
Jooyung Han862c0d62022-12-21 10:15:37 +09002124func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002125 encountered := make(map[string]apexFile)
2126 for _, f := range vctx.filesInfo {
2127 dest := filepath.Join(f.installDir, f.builtFile.Base())
2128 if e, ok := encountered[dest]; !ok {
2129 encountered[dest] = f
2130 } else {
Jooyung Han862c0d62022-12-21 10:15:37 +09002131 if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
2132 mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
2133 dest, e.builtFile, f.builtFile)
2134 return
2135 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002136 // If a module is directly included and also transitively depended on
2137 // consider it as directly included.
2138 e.transitiveDep = e.transitiveDep && f.transitiveDep
2139 encountered[dest] = e
2140 }
2141 }
2142 vctx.filesInfo = vctx.filesInfo[:0]
2143 for _, v := range encountered {
2144 vctx.filesInfo = append(vctx.filesInfo, v)
2145 }
2146 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2147 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2148 // changes.
2149 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2150 })
2151}
2152
2153func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2154 depTag := ctx.OtherModuleDependencyTag(child)
2155 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2156 return false
2157 }
2158 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2159 return false
2160 }
2161 depName := ctx.OtherModuleName(child)
2162 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2163 switch depTag {
2164 case sharedLibTag, jniLibTag:
2165 isJniLib := depTag == jniLibTag
2166 switch ch := child.(type) {
2167 case *cc.Module:
2168 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2169 fi.isJniLib = isJniLib
2170 vctx.filesInfo = append(vctx.filesInfo, fi)
2171 // Collect the list of stub-providing libs except:
2172 // - VNDK libs are only for vendors
2173 // - bootstrap bionic libs are treated as provided by system
2174 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2175 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2176 }
2177 return true // track transitive dependencies
2178 case *rust.Module:
2179 fi := apexFileForRustLibrary(ctx, ch)
2180 fi.isJniLib = isJniLib
2181 vctx.filesInfo = append(vctx.filesInfo, fi)
2182 return true // track transitive dependencies
2183 default:
2184 propertyName := "native_shared_libs"
2185 if isJniLib {
2186 propertyName = "jni_libs"
2187 }
2188 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2189 }
2190 case executableTag:
2191 switch ch := child.(type) {
2192 case *cc.Module:
2193 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2194 return true // track transitive dependencies
2195 case *python.Module:
2196 if ch.HostToolPath().Valid() {
2197 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2198 }
2199 case bootstrap.GoBinaryTool:
2200 if a.Host() {
2201 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2202 }
2203 case *rust.Module:
2204 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2205 return true // track transitive dependencies
2206 default:
2207 ctx.PropertyErrorf("binaries",
2208 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2209 }
2210 case shBinaryTag:
2211 if csh, ok := child.(*sh.ShBinary); ok {
2212 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2213 } else {
2214 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2215 }
2216 case bcpfTag:
2217 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2218 if !ok {
2219 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2220 return false
2221 }
2222
2223 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2224 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2225 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2226 }
2227 return true
2228 case sscpfTag:
2229 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2230 ctx.PropertyErrorf("systemserverclasspath_fragments",
2231 "%q is not a systemserverclasspath_fragment module", depName)
2232 return false
2233 }
2234 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2235 vctx.filesInfo = append(vctx.filesInfo, *af)
2236 }
2237 return true
2238 case javaLibTag:
2239 switch child.(type) {
2240 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2241 af := apexFileForJavaModule(ctx, child.(javaModule))
2242 if !af.ok() {
2243 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2244 return false
2245 }
2246 vctx.filesInfo = append(vctx.filesInfo, af)
2247 return true // track transitive dependencies
2248 default:
2249 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2250 }
2251 case androidAppTag:
2252 switch ap := child.(type) {
2253 case *java.AndroidApp:
2254 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2255 return true // track transitive dependencies
2256 case *java.AndroidAppImport:
2257 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2258 case *java.AndroidTestHelperApp:
2259 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2260 case *java.AndroidAppSet:
2261 appDir := "app"
2262 if ap.Privileged() {
2263 appDir = "priv-app"
2264 }
2265 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2266 // suffixed so that PackageManager correctly invalidates the
2267 // existing installed apk in favour of the new APK-in-APEX.
2268 // See bugs for more information.
2269 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2270 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2271 af.certificate = java.PresignedCertificate
2272 vctx.filesInfo = append(vctx.filesInfo, af)
2273 default:
2274 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2275 }
2276 case rroTag:
2277 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2278 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2279 } else {
2280 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2281 }
2282 case bpfTag:
2283 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2284 filesToCopy, _ := bpfProgram.OutputFiles("")
2285 apex_sub_dir := bpfProgram.SubDir()
2286 for _, bpfFile := range filesToCopy {
2287 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2288 }
2289 } else {
2290 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2291 }
2292 case fsTag:
2293 if fs, ok := child.(filesystem.Filesystem); ok {
2294 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2295 } else {
2296 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2297 }
2298 case prebuiltTag:
2299 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2300 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2301 } else {
2302 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2303 }
2304 case compatConfigTag:
2305 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2306 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2307 } else {
2308 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2309 }
2310 case testTag:
2311 if ccTest, ok := child.(*cc.Module); ok {
2312 if ccTest.IsTestPerSrcAllTestsVariation() {
2313 // Multiple-output test module (where `test_per_src: true`).
2314 //
2315 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2316 // We do not add this variation to `filesInfo`, as it has no output;
2317 // however, we do add the other variations of this module as indirect
2318 // dependencies (see below).
2319 } else {
2320 // Single-output test module (where `test_per_src: false`).
2321 af := apexFileForExecutable(ctx, ccTest)
2322 af.class = nativeTest
2323 vctx.filesInfo = append(vctx.filesInfo, af)
2324 }
2325 return true // track transitive dependencies
2326 } else {
2327 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2328 }
2329 case keyTag:
2330 if key, ok := child.(*apexKey); ok {
2331 a.privateKeyFile = key.privateKeyFile
2332 a.publicKeyFile = key.publicKeyFile
2333 } else {
2334 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2335 }
2336 case certificateTag:
2337 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2338 a.containerCertificateFile = dep.Certificate.Pem
2339 a.containerPrivateKeyFile = dep.Certificate.Key
2340 } else {
2341 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2342 }
2343 case android.PrebuiltDepTag:
2344 // If the prebuilt is force disabled, remember to delete the prebuilt file
2345 // that might have been installed in the previous builds
2346 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2347 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2348 }
2349 }
2350 return false
2351 }
2352
2353 if a.vndkApex {
2354 return false
2355 }
2356
2357 // indirect dependencies
2358 am, ok := child.(android.ApexModule)
2359 if !ok {
2360 return false
2361 }
2362 // We cannot use a switch statement on `depTag` here as the checked
2363 // tags used below are private (e.g. `cc.sharedDepTag`).
2364 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2365 if ch, ok := child.(*cc.Module); ok {
2366 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2367 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2368 return false
2369 }
2370 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2371 af.transitiveDep = true
2372
2373 // Always track transitive dependencies for host.
2374 if a.Host() {
2375 vctx.filesInfo = append(vctx.filesInfo, af)
2376 return true
2377 }
2378
2379 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2380 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2381 // If the dependency is a stubs lib, don't include it in this APEX,
2382 // but make sure that the lib is installed on the device.
2383 // In case no APEX is having the lib, the lib is installed to the system
2384 // partition.
2385 //
2386 // Always include if we are a host-apex however since those won't have any
2387 // system libraries.
Alan Stokes73feba32022-11-14 12:21:24 +00002388 if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002389 // we need a module name for Make
2390 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2391 if !android.InList(name, a.requiredDeps) {
2392 a.requiredDeps = append(a.requiredDeps, name)
2393 }
2394 }
2395 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2396 // Don't track further
2397 return false
2398 }
2399
2400 // If the dep is not considered to be in the same
2401 // apex, don't add it to filesInfo so that it is not
2402 // included in this APEX.
2403 // TODO(jiyong): move this to at the top of the
2404 // else-if clause for the indirect dependencies.
2405 // Currently, that's impossible because we would
2406 // like to record requiredNativeLibs even when
2407 // DepIsInSameAPex is false. We also shouldn't do
2408 // this for host.
2409 //
2410 // TODO(jiyong): explain why the same module is passed in twice.
2411 // Switching the first am to parent breaks lots of tests.
2412 if !android.IsDepInSameApex(ctx, am, am) {
2413 return false
2414 }
2415
2416 vctx.filesInfo = append(vctx.filesInfo, af)
2417 return true // track transitive dependencies
2418 } else if rm, ok := child.(*rust.Module); ok {
2419 af := apexFileForRustLibrary(ctx, rm)
2420 af.transitiveDep = true
2421 vctx.filesInfo = append(vctx.filesInfo, af)
2422 return true // track transitive dependencies
2423 }
2424 } else if cc.IsTestPerSrcDepTag(depTag) {
2425 if ch, ok := child.(*cc.Module); ok {
2426 af := apexFileForExecutable(ctx, ch)
2427 // Handle modules created as `test_per_src` variations of a single test module:
2428 // use the name of the generated test binary (`fileToCopy`) instead of the name
2429 // of the original test module (`depName`, shared by all `test_per_src`
2430 // variations of that module).
2431 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2432 // these are not considered transitive dep
2433 af.transitiveDep = false
2434 vctx.filesInfo = append(vctx.filesInfo, af)
2435 return true // track transitive dependencies
2436 }
2437 } else if cc.IsHeaderDepTag(depTag) {
2438 // nothing
2439 } else if java.IsJniDepTag(depTag) {
2440 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2441 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2442 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2443 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2444 }
2445 } else if rust.IsDylibDepTag(depTag) {
2446 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2447 af := apexFileForRustLibrary(ctx, rustm)
2448 af.transitiveDep = true
2449 vctx.filesInfo = append(vctx.filesInfo, af)
2450 return true // track transitive dependencies
2451 }
2452 } else if rust.IsRlibDepTag(depTag) {
2453 // Rlib is statically linked, but it might have shared lib
2454 // dependencies. Track them.
2455 return true
2456 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2457 // Add the contents of the bootclasspath fragment to the apex.
2458 switch child.(type) {
2459 case *java.Library, *java.SdkLibrary:
2460 javaModule := child.(javaModule)
2461 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2462 if !af.ok() {
2463 ctx.PropertyErrorf("bootclasspath_fragments",
2464 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2465 return false
2466 }
2467 vctx.filesInfo = append(vctx.filesInfo, af)
2468 return true // track transitive dependencies
2469 default:
2470 ctx.PropertyErrorf("bootclasspath_fragments",
2471 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2472 }
2473 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2474 // Add the contents of the systemserverclasspath fragment to the apex.
2475 switch child.(type) {
2476 case *java.Library, *java.SdkLibrary:
2477 af := apexFileForJavaModule(ctx, child.(javaModule))
2478 vctx.filesInfo = append(vctx.filesInfo, af)
2479 return true // track transitive dependencies
2480 default:
2481 ctx.PropertyErrorf("systemserverclasspath_fragments",
2482 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2483 }
2484 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2485 // nothing
2486 } else if depTag == android.DarwinUniversalVariantTag {
2487 // nothing
2488 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2489 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2490 }
2491 return false
2492}
2493
Jooyung Han862c0d62022-12-21 10:15:37 +09002494func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
2495 // TODO(b/263308293) remove this
2496 if a.properties.IsCoverageVariant {
2497 return false
2498 }
2499 // TODO(b/263308515) remove this
2500 if a.testApex {
2501 return false
2502 }
2503 // TODO(b/263309864) remove this
2504 if a.Host() {
2505 return false
2506 }
2507 if a.Device() && ctx.DeviceConfig().DeviceArch() == "" {
2508 return false
2509 }
2510 return true
2511}
2512
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002513// Creates build rules for an APEX. It consists of the following major steps:
2514//
2515// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2516// 2) traverse the dependency tree to collect apexFile structs from them.
2517// 3) some fields in apexBundle struct are configured
2518// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002519func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002520 ////////////////////////////////////////////////////////////////////////////////////////////
2521 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002522 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002523 return
2524 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002525 ////////////////////////////////////////////////////////////////////////////////////////////
2526 // 2) traverse the dependency tree to collect apexFile structs from them.
braleeb0c1f0c2021-06-07 22:49:13 +08002527 // Collect the module directory for IDE info in java/jdeps.go.
2528 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2529
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002530 // TODO(jiyong): do this using WalkPayloadDeps
2531 // TODO(jiyong): make this clean!!!
Jooyung Han862c0d62022-12-21 10:15:37 +09002532 vctx := visitorContext{
2533 handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case),
2534 checkDuplicate: a.shouldCheckDuplicate(ctx),
2535 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002536 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
Jooyung Han862c0d62022-12-21 10:15:37 +09002537 vctx.normalizeFileInfo(ctx)
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002538 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002539 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002540 return
2541 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002542
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002543 ////////////////////////////////////////////////////////////////////////////////////////////
2544 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002545 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002546 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002547
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002548 a.setApexTypeAndSuffix(ctx)
2549 a.setPayloadFsType(ctx)
2550 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002551 if a.properties.ApexType != zipApex {
2552 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2553 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002554
2555 ////////////////////////////////////////////////////////////////////////////////////////////
2556 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002557 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002558 if a.properties.ApexType == flattenedApex {
2559 a.buildFlattenedApex(ctx)
2560 } else {
2561 a.buildUnflattenedApex(ctx)
2562 }
Jiyong Park956305c2020-01-09 12:32:06 +09002563 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002564 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002565
2566 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2567 if a.installable() {
2568 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2569 // along with other ordinary files. (Note that this is done by apexer for
2570 // non-flattened APEXes)
2571 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2572
2573 // Place the public key as apex_pubkey. This is also done by apexer for
2574 // non-flattened APEXes case.
2575 // TODO(jiyong): Why do we need this CP rule?
2576 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2577 ctx.Build(pctx, android.BuildParams{
2578 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002579 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002580 Output: copiedPubkey,
2581 })
2582 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2583 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002584}
2585
Paul Duffincc33ec82021-04-25 23:14:55 +01002586// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2587// the bootclasspath_fragment contributes to the apex.
2588func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2589 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2590 var filesToAdd []apexFile
2591
2592 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002593 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2594 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2595 dirInApex := filepath.Join("javalib", arch.String())
2596 for _, f := range files {
2597 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2598 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2599 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2600 filesToAdd = append(filesToAdd, af)
2601 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002602 }
2603 }
2604
satayev3db35472021-05-06 23:59:58 +01002605 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002606 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2607 filesToAdd = append(filesToAdd, *af)
2608 }
satayev3db35472021-05-06 23:59:58 +01002609
Ulya Trafimovichf5c548d2022-11-16 14:52:41 +00002610 pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2611 if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002612 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2613 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2614
2615 if pathOnHost != nil {
2616 // We need to copy the profile to a temporary path with the right filename because the apexer
2617 // will take the filename as is.
2618 ctx.Build(pctx, android.BuildParams{
2619 Rule: android.Cp,
2620 Input: pathOnHost,
2621 Output: tempPath,
2622 })
2623 } else {
2624 // At this point, the boot image profile cannot be generated. It is probably because the boot
2625 // image profile source file does not exist on the branch, or it is not available for the
2626 // current build target.
2627 // However, we cannot enforce the boot image profile to be generated because some build
2628 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2629 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2630 // only if the APEX is being built.
2631 ctx.Build(pctx, android.BuildParams{
2632 Rule: android.ErrorRule,
2633 Output: tempPath,
2634 Args: map[string]string{
2635 "error": "Boot image profile cannot be generated",
2636 },
2637 })
2638 }
2639
2640 androidMkModuleName := filepath.Base(pathInApex)
2641 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2642 filesToAdd = append(filesToAdd, af)
2643 }
2644
Paul Duffincc33ec82021-04-25 23:14:55 +01002645 return filesToAdd
2646}
2647
satayevb98371c2021-06-15 16:49:50 +01002648// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2649// the module contributes to the apex; or nil if the proto config was not generated.
2650func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2651 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2652 if !info.ClasspathFragmentProtoGenerated {
2653 return nil
2654 }
2655 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2656 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2657 return &af
satayev14e49132021-05-17 21:03:07 +01002658}
2659
Paul Duffincc33ec82021-04-25 23:14:55 +01002660// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2661// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002662func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2663 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2664
2665 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2666 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002667 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2668 if err != nil {
2669 ctx.ModuleErrorf("%s", err)
2670 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002671
2672 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2673 // bootclasspath_fragment.
2674 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2675 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002676}
2677
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002678///////////////////////////////////////////////////////////////////////////////////////////////////
2679// Factory functions
2680//
2681
2682func newApexBundle() *apexBundle {
2683 module := &apexBundle{}
2684
2685 module.AddProperties(&module.properties)
2686 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002687 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002688 module.AddProperties(&module.overridableProperties)
2689
2690 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2691 android.InitDefaultableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002692 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002693 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002694 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002695 return module
2696}
2697
Paul Duffineb8051d2021-10-18 17:49:39 +01002698func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002699 bundle := newApexBundle()
2700 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002701 return bundle
2702}
2703
2704// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2705// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002706func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002707 bundle := newApexBundle()
2708 bundle.testApex = true
2709 return bundle
2710}
2711
2712// apex packages other modules into an APEX file which is a packaging format for system-level
2713// components like binaries, shared libraries, etc.
2714func BundleFactory() android.Module {
2715 return newApexBundle()
2716}
2717
2718type Defaults struct {
2719 android.ModuleBase
2720 android.DefaultsModuleBase
2721}
2722
2723// apex_defaults provides defaultable properties to other apex modules.
2724func defaultsFactory() android.Module {
2725 return DefaultsFactory()
2726}
2727
2728func DefaultsFactory(props ...interface{}) android.Module {
2729 module := &Defaults{}
2730
2731 module.AddProperties(props...)
2732 module.AddProperties(
2733 &apexBundleProperties{},
2734 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002735 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002736 &overridableProperties{},
2737 )
2738
2739 android.InitDefaultsModule(module)
2740 return module
2741}
2742
2743type OverrideApex struct {
2744 android.ModuleBase
2745 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002746 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002747}
2748
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002749func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002750 // All the overrides happen in the base module.
2751}
2752
2753// override_apex is used to create an apex module based on another apex module by overriding some of
2754// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002755func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002756 m := &OverrideApex{}
2757
2758 m.AddProperties(&overridableProperties{})
2759
2760 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2761 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002762 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002763 return m
2764}
2765
Wei Li1c66fc72022-05-09 23:59:14 -07002766func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2767 if ctx.ModuleType() != "override_apex" {
2768 return
2769 }
2770
2771 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2772 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2773 if !baseApexExists {
2774 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2775 }
2776
2777 a, baseModuleIsApex := baseModule.(*apexBundle)
2778 if !baseModuleIsApex {
2779 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2780 }
2781 attrs, props := convertWithBp2build(a, ctx)
2782
Jingwen Chenc4c34e12022-11-29 12:07:45 +00002783 // We just want the name, not module reference.
2784 baseApexName := strings.TrimPrefix(baseApexModuleName, ":")
2785 attrs.Base_apex_name = &baseApexName
2786
Wei Li1c66fc72022-05-09 23:59:14 -07002787 for _, p := range o.GetProperties() {
2788 overridableProperties, ok := p.(*overridableProperties)
2789 if !ok {
2790 continue
2791 }
Wei Li40f98732022-05-20 22:08:11 -07002792
2793 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2794 // After it is converted in convertWithBp2build(baseApex, ctx),
2795 // the attrs.Manifest.Value.Label is the file path relative to the directory
2796 // of base apex. So the following code converts it to a label that looks like
2797 // <package of base apex>:<path of manifest file> if base apex and override
2798 // apex are not in the same package.
2799 baseApexPackage := ctx.OtherModuleDir(a)
2800 overrideApexPackage := ctx.ModuleDir()
2801 if baseApexPackage != overrideApexPackage {
2802 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2803 }
2804
Wei Li1c66fc72022-05-09 23:59:14 -07002805 // Key
2806 if overridableProperties.Key != nil {
2807 attrs.Key = bazel.LabelAttribute{}
2808 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2809 }
2810
2811 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002812 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002813 // If overridableProperties.Certificate is nil, clear this out as
2814 // well with zeroed structs, so the override_apex does not use the
2815 // base apex's certificate.
2816 attrs.Certificate = bazel.LabelAttribute{}
2817 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002818 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002819 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002820 }
2821
2822 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002823 if overridableProperties.Prebuilts != nil {
2824 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2825 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2826 }
Wei Li1c66fc72022-05-09 23:59:14 -07002827
2828 // Compressible
2829 if overridableProperties.Compressible != nil {
2830 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2831 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002832
2833 // Package name
2834 //
2835 // e.g. com.android.adbd's package name is com.android.adbd, but
2836 // com.google.android.adbd overrides the package name to com.google.android.adbd
2837 //
2838 // TODO: this can be overridden from the product configuration, see
2839 // getOverrideManifestPackageName and
2840 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2841 //
2842 // Instead of generating the BUILD files differently based on the product config
2843 // at the point of conversion, this should be handled by the BUILD file loading
2844 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2845 if overridableProperties.Package_name != "" {
2846 attrs.Package_name = &overridableProperties.Package_name
2847 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002848
2849 // Logging parent
2850 if overridableProperties.Logging_parent != "" {
2851 attrs.Logging_parent = &overridableProperties.Logging_parent
2852 }
Wei Li1c66fc72022-05-09 23:59:14 -07002853 }
2854
2855 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2856}
2857
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002858///////////////////////////////////////////////////////////////////////////////////////////////////
2859// Vality check routines
2860//
2861// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2862// certain conditions are not met.
2863//
2864// TODO(jiyong): move these checks to a separate go file.
2865
satayevad991492021-12-03 18:58:32 +00002866var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2867
Spandan Dasa5f39a12022-08-05 02:35:52 +00002868// Ensures that min_sdk_version of the included modules are equal or less than the min_sdk_version
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002869// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002870func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002871 if a.testApex || a.vndkApex {
2872 return
2873 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002874 // apexBundle::minSdkVersion reports its own errors.
2875 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002876 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002877}
2878
Albert Martineefabcf2022-03-21 20:11:16 +00002879// Returns apex's min_sdk_version string value, honoring overrides
2880func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2881 // Only override the minSdkVersion value on Apexes which already specify
2882 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2883 // min_sdk_version value is lower than the one to override with.
Colin Cross56534df2022-10-04 09:58:58 -07002884 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2885 if minApiLevel.IsNone() {
2886 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002887 }
2888
Colin Cross56534df2022-10-04 09:58:58 -07002889 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2890 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2891 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2892 minApiLevel = overrideApiLevel
2893 }
2894
2895 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002896}
2897
2898// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002899func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2900 return android.SdkSpec{
2901 Kind: android.SdkNone,
2902 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002903 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002904 }
2905}
2906
Albert Martineefabcf2022-03-21 20:11:16 +00002907// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002908func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002909 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2910}
2911
2912// Construct ApiLevel object from min_sdk_version string value
2913func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2914 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002915 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002916 }
Albert Martineefabcf2022-03-21 20:11:16 +00002917 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002918 if err != nil {
2919 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2920 return android.NoneApiLevel
2921 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002922 return apiLevel
2923}
2924
2925// Ensures that a lib providing stub isn't statically linked
2926func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2927 // Practically, we only care about regular APEXes on the device.
2928 if ctx.Host() || a.testApex || a.vndkApex {
2929 return
2930 }
2931
2932 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2933
2934 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2935 if ccm, ok := to.(*cc.Module); ok {
2936 apexName := ctx.ModuleName()
2937 fromName := ctx.OtherModuleName(from)
2938 toName := ctx.OtherModuleName(to)
2939
2940 // If `to` is not actually in the same APEX as `from` then it does not need
2941 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002942 //
2943 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002944 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2945 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2946 return false
2947 }
2948
2949 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2950 // exception to this rule. It can't make the static dependencies dynamic
2951 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002952 // Same rule should be applied to linkerconfig, because it should be executed
2953 // only with static linked libraries before linker is available with ld.config.txt
2954 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002955 return false
2956 }
2957
2958 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2959 if isStubLibraryFromOtherApex && !externalDep {
2960 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2961 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2962 }
2963
2964 }
2965 return true
2966 })
2967}
2968
satayevb98371c2021-06-15 16:49:50 +01002969// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002970func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2971 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002972 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002973 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2974 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002975 if a.UsePlatformApis() {
2976 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2977 }
Daniel Norman69109112021-12-02 12:52:42 -08002978 if a.SocSpecific() || a.DeviceSpecific() {
2979 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2980 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002981 if a.FutureUpdatable() {
2982 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2983 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002984 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002985 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002986 }
2987}
2988
satayevb98371c2021-06-15 16:49:50 +01002989// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2990func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2991 ctx.VisitDirectDeps(func(module android.Module) {
2992 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2993 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2994 if !info.ClasspathFragmentProtoGenerated {
2995 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2996 }
2997 }
2998 })
2999}
3000
3001// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01003002func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003003 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
3004 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01003005 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3006 tag := ctx.OtherModuleDependencyTag(module)
3007 switch tag {
3008 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09003009 if m, ok := module.(interface {
3010 CheckStableSdkVersion(ctx android.BaseModuleContext) error
3011 }); ok {
3012 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01003013 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
3014 }
3015 }
3016 }
3017 })
3018}
3019
satayevb98371c2021-06-15 16:49:50 +01003020// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003021func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
3022 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
3023 if ctx.Host() || a.testApex || a.vndkApex {
3024 return
3025 }
3026
3027 // Because APEXes targeting other than system/system_ext partitions can't set
3028 // apex_available, we skip checks for these APEXes
3029 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
3030 return
3031 }
3032
3033 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
3034 // Requiring them and their transitive depencies with apex_available is not right
3035 // because they just add noise.
3036 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
3037 return
3038 }
3039
3040 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
3041 // As soon as the dependency graph crosses the APEX boundary, don't go further.
3042 if externalDep {
3043 return false
3044 }
3045
3046 apexName := ctx.ModuleName()
3047 fromName := ctx.OtherModuleName(from)
3048 toName := ctx.OtherModuleName(to)
3049
3050 // If `to` is not actually in the same APEX as `from` then it does not need
3051 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00003052 //
3053 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003054 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
3055 // As soon as the dependency graph crosses the APEX boundary, don't go
3056 // further.
3057 return false
3058 }
3059
3060 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
3061 return true
3062 }
Jiyong Park767dbd92021-03-04 13:03:10 +09003063 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
3064 "\n\nDependency path:%s\n\n"+
3065 "Consider adding %q to 'apex_available' property of %q",
3066 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003067 // Visit this module's dependencies to check and report any issues with their availability.
3068 return true
3069 })
3070}
3071
Jiyong Park192600a2021-08-03 07:52:17 +00003072// checkStaticExecutable ensures that executables in an APEX are not static.
3073func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09003074 // No need to run this for host APEXes
3075 if ctx.Host() {
3076 return
3077 }
3078
Jiyong Park192600a2021-08-03 07:52:17 +00003079 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3080 if ctx.OtherModuleDependencyTag(module) != executableTag {
3081 return
3082 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09003083
3084 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00003085 apex := a.ApexVariationName()
3086 exec := ctx.OtherModuleName(module)
3087 if isStaticExecutableAllowed(apex, exec) {
3088 return
3089 }
3090 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
3091 }
3092 })
3093}
3094
3095// A small list of exceptions where static executables are allowed in APEXes.
3096func isStaticExecutableAllowed(apex string, exec string) bool {
3097 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003098 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00003099 "linker",
3100 "linkerconfig",
3101 },
3102 }
3103 execNames, ok := m[apex]
3104 return ok && android.InList(exec, execNames)
3105}
3106
braleeb0c1f0c2021-06-07 22:49:13 +08003107// Collect information for opening IDE project files in java/jdeps.go.
3108func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09003109 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
3110 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
3111 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08003112 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
3113}
3114
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003115var (
3116 apexAvailBaseline = makeApexAvailableBaseline()
3117 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
3118)
3119
Colin Cross440e0d02020-06-11 11:32:11 -07003120func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003121 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003122 moduleName = normalizeModuleName(moduleName)
3123
Colin Cross440e0d02020-06-11 11:32:11 -07003124 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003125 return true
3126 }
3127
3128 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07003129 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003130 return true
3131 }
3132
3133 return false
3134}
3135
3136func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09003137 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
3138 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00003139 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09003140 if strings.HasPrefix(moduleName, "libclang_rt.") {
3141 // This module has many arch variants that depend on the product being built.
3142 // We don't want to list them all
3143 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003144 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003145 if strings.HasPrefix(moduleName, "androidx.") {
3146 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3147 moduleName = "androidx"
3148 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003149 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003150}
3151
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003152// Transform the map of apex -> modules to module -> apexes.
3153func invertApexBaseline(m map[string][]string) map[string][]string {
3154 r := make(map[string][]string)
3155 for apex, modules := range m {
3156 for _, module := range modules {
3157 r[module] = append(r[module], apex)
3158 }
3159 }
3160 return r
3161}
3162
3163// Retrieve the baseline of apexes to which the supplied module belongs.
3164func BaselineApexAvailable(moduleName string) []string {
3165 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3166}
3167
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003168// This is a map from apex to modules, which overrides the apex_available setting for that
3169// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003170// TODO(b/147364041): remove this
3171func makeApexAvailableBaseline() map[string][]string {
3172 // The "Module separator"s below are employed to minimize merge conflicts.
3173 m := make(map[string][]string)
3174 //
3175 // Module separator
3176 //
3177 m["com.android.appsearch"] = []string{
3178 "icing-java-proto-lite",
3179 "libprotobuf-java-lite",
3180 }
3181 //
3182 // Module separator
3183 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003184 m["com.android.btservices"] = []string{
William Escande89bca3f2022-06-28 18:03:30 -07003185 // empty
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003186 }
3187 //
3188 // Module separator
3189 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003190 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3191 //
3192 // Module separator
3193 //
3194 m["com.android.extservices"] = []string{
3195 "error_prone_annotations",
3196 "ExtServices-core",
3197 "ExtServices",
3198 "libtextclassifier-java",
3199 "libz_current",
3200 "textclassifier-statsd",
3201 "TextClassifierNotificationLibNoManifest",
3202 "TextClassifierServiceLibNoManifest",
3203 }
3204 //
3205 // Module separator
3206 //
3207 m["com.android.neuralnetworks"] = []string{
3208 "android.hardware.neuralnetworks@1.0",
3209 "android.hardware.neuralnetworks@1.1",
3210 "android.hardware.neuralnetworks@1.2",
3211 "android.hardware.neuralnetworks@1.3",
3212 "android.hidl.allocator@1.0",
3213 "android.hidl.memory.token@1.0",
3214 "android.hidl.memory@1.0",
3215 "android.hidl.safe_union@1.0",
3216 "libarect",
3217 "libbuildversion",
3218 "libmath",
3219 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003220 }
3221 //
3222 // Module separator
3223 //
3224 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003225 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003226 }
3227 //
3228 // Module separator
3229 //
3230 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003231 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003232 }
3233 //
3234 // Module separator
3235 //
3236 m["com.android.mediaprovider"] = []string{
3237 "MediaProvider",
3238 "MediaProviderGoogle",
3239 "fmtlib_ndk",
3240 "libbase_ndk",
3241 "libfuse",
3242 "libfuse_jni",
3243 }
3244 //
3245 // Module separator
3246 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003247 m["com.android.runtime"] = []string{
3248 "bionic_libc_platform_headers",
3249 "libarm-optimized-routines-math",
3250 "libc_aeabi",
3251 "libc_bionic",
3252 "libc_bionic_ndk",
3253 "libc_bootstrap",
3254 "libc_common",
3255 "libc_common_shared",
3256 "libc_common_static",
3257 "libc_dns",
3258 "libc_dynamic_dispatch",
3259 "libc_fortify",
3260 "libc_freebsd",
3261 "libc_freebsd_large_stack",
3262 "libc_gdtoa",
3263 "libc_init_dynamic",
3264 "libc_init_static",
3265 "libc_jemalloc_wrapper",
3266 "libc_netbsd",
3267 "libc_nomalloc",
3268 "libc_nopthread",
3269 "libc_openbsd",
3270 "libc_openbsd_large_stack",
3271 "libc_openbsd_ndk",
3272 "libc_pthread",
3273 "libc_static_dispatch",
3274 "libc_syscalls",
3275 "libc_tzcode",
3276 "libc_unwind_static",
3277 "libdebuggerd",
3278 "libdebuggerd_common_headers",
3279 "libdebuggerd_handler_core",
3280 "libdebuggerd_handler_fallback",
3281 "libdl_static",
3282 "libjemalloc5",
3283 "liblinker_main",
3284 "liblinker_malloc",
3285 "liblz4",
3286 "liblzma",
3287 "libprocinfo",
3288 "libpropertyinfoparser",
3289 "libscudo",
3290 "libstdc++",
3291 "libsystemproperties",
3292 "libtombstoned_client_static",
3293 "libunwindstack",
3294 "libz",
3295 "libziparchive",
3296 }
3297 //
3298 // Module separator
3299 //
3300 m["com.android.tethering"] = []string{
3301 "android.hardware.tetheroffload.config-V1.0-java",
3302 "android.hardware.tetheroffload.control-V1.0-java",
3303 "android.hidl.base-V1.0-java",
3304 "libcgrouprc",
3305 "libcgrouprc_format",
3306 "libtetherutilsjni",
3307 "libvndksupport",
3308 "net-utils-framework-common",
3309 "netd_aidl_interface-V3-java",
3310 "netlink-client",
3311 "networkstack-aidl-interfaces-java",
3312 "tethering-aidl-interfaces-java",
3313 "TetheringApiCurrentLib",
3314 }
3315 //
3316 // Module separator
3317 //
3318 m["com.android.wifi"] = []string{
3319 "PlatformProperties",
3320 "android.hardware.wifi-V1.0-java",
3321 "android.hardware.wifi-V1.0-java-constants",
3322 "android.hardware.wifi-V1.1-java",
3323 "android.hardware.wifi-V1.2-java",
3324 "android.hardware.wifi-V1.3-java",
3325 "android.hardware.wifi-V1.4-java",
3326 "android.hardware.wifi.hostapd-V1.0-java",
3327 "android.hardware.wifi.hostapd-V1.1-java",
3328 "android.hardware.wifi.hostapd-V1.2-java",
3329 "android.hardware.wifi.supplicant-V1.0-java",
3330 "android.hardware.wifi.supplicant-V1.1-java",
3331 "android.hardware.wifi.supplicant-V1.2-java",
3332 "android.hardware.wifi.supplicant-V1.3-java",
3333 "android.hidl.base-V1.0-java",
3334 "android.hidl.manager-V1.0-java",
3335 "android.hidl.manager-V1.1-java",
3336 "android.hidl.manager-V1.2-java",
3337 "bouncycastle-unbundled",
3338 "dnsresolver_aidl_interface-V2-java",
3339 "error_prone_annotations",
3340 "framework-wifi-pre-jarjar",
3341 "framework-wifi-util-lib",
3342 "ipmemorystore-aidl-interfaces-V3-java",
3343 "ipmemorystore-aidl-interfaces-java",
3344 "ksoap2",
3345 "libnanohttpd",
3346 "libwifi-jni",
3347 "net-utils-services-common",
3348 "netd_aidl_interface-V2-java",
3349 "netd_aidl_interface-unstable-java",
3350 "netd_event_listener_interface-java",
3351 "netlink-client",
3352 "networkstack-client",
3353 "services.net",
3354 "wifi-lite-protos",
3355 "wifi-nano-protos",
3356 "wifi-service-pre-jarjar",
3357 "wifi-service-resources",
3358 }
3359 //
3360 // Module separator
3361 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003362 m["com.android.os.statsd"] = []string{
3363 "libstatssocket",
3364 }
3365 //
3366 // Module separator
3367 //
3368 m[android.AvailableToAnyApex] = []string{
3369 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3370 "androidx",
3371 "androidx-constraintlayout_constraintlayout",
3372 "androidx-constraintlayout_constraintlayout-nodeps",
3373 "androidx-constraintlayout_constraintlayout-solver",
3374 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3375 "com.google.android.material_material",
3376 "com.google.android.material_material-nodeps",
3377
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003378 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003379 "libprofile-clang-extras",
3380 "libprofile-clang-extras_ndk",
3381 "libprofile-extras",
3382 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003383 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003384 }
3385 return m
3386}
3387
3388func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003389 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3390 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003391}
3392
Spandan Dasf14e2542021-11-12 00:01:37 +00003393func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3394 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3395 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003396 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003397 With("name", jar).
3398 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3399 Because(jar +
3400 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003401 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003402 " 1. If the offending code is from a statically linked library, consider " +
3403 "removing that dependency and using an alternative already in the " +
3404 "bootclasspath, or perhaps a shared library." +
3405 " 2. Move the offending code into an allowed package.\n" +
3406 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3407 "health implications of bundling that code, particularly if the offending jar " +
3408 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003409
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003410 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003411 }
3412 return rules
3413}
3414
Anton Hanssone1b18362021-12-23 15:05:38 +00003415// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003416// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003417func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003418 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003419 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003420 "android.net.ssl",
3421 "com.android.org.conscrypt",
3422 },
Wei Li40f98732022-05-20 22:08:11 -07003423 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003424 "android.media",
3425 },
3426 }
3427}
3428
Anton Hanssone1b18362021-12-23 15:05:38 +00003429// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003430// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003431func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003432 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003433 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003434 "android.provider",
3435 },
Wei Li40f98732022-05-20 22:08:11 -07003436 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003437 "android.permission",
3438 "android.app.role",
3439 "com.android.permission",
3440 "com.android.role",
3441 },
Wei Li40f98732022-05-20 22:08:11 -07003442 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003443 "android.os.ext",
3444 },
Wei Li40f98732022-05-20 22:08:11 -07003445 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003446 "android.app",
3447 "android.os",
3448 "android.util",
3449 "com.android.internal.statsd",
3450 "com.android.server.stats",
3451 },
Wei Li40f98732022-05-20 22:08:11 -07003452 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003453 "com.android.server.wifi",
3454 "com.android.wifi.x",
3455 "android.hardware.wifi",
3456 "android.net.wifi",
3457 },
Wei Li40f98732022-05-20 22:08:11 -07003458 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003459 "android.net",
3460 },
3461 }
3462}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003463
3464// For Bazel / bp2build
3465
3466type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003467 Manifest bazel.LabelAttribute
3468 Android_manifest bazel.LabelAttribute
3469 File_contexts bazel.LabelAttribute
3470 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003471 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3472 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Yu Liu4ae55d12022-01-05 17:17:23 -08003473 Min_sdk_version *string
3474 Updatable bazel.BoolAttribute
3475 Installable bazel.BoolAttribute
3476 Binaries bazel.LabelListAttribute
3477 Prebuilts bazel.LabelListAttribute
3478 Native_shared_libs_32 bazel.LabelListAttribute
3479 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003480 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003481 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003482 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003483 Tests bazel.LabelListAttribute
Jingwen Chenc4c34e12022-11-29 12:07:45 +00003484 Base_apex_name *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003485}
3486
3487type convertedNativeSharedLibs struct {
3488 Native_shared_libs_32 bazel.LabelListAttribute
3489 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003490}
3491
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003492// ConvertWithBp2build performs bp2build conversion of an apex
3493func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003494 // We only convert apex and apex_test modules at this time
3495 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003496 return
3497 }
3498
Wei Li1c66fc72022-05-09 23:59:14 -07003499 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003500 commonAttrs := android.CommonAttributes{
3501 Name: a.Name(),
3502 }
3503 if a.testApex {
3504 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3505 }
3506 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003507}
3508
3509func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003510 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003511 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003512
3513 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003514 if a.properties.AndroidManifest != nil {
3515 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003516 }
3517
3518 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003519 if a.properties.File_contexts == nil {
3520 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3521 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3522 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3523 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003524 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003525 } else {
3526 // File_contexts is a file
3527 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003528 }
3529
Albert Martineefabcf2022-03-21 20:11:16 +00003530 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3531 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003532 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003533 if a.properties.Min_sdk_version != nil {
3534 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003535 }
3536
3537 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003538 if a.overridableProperties.Key != nil {
3539 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003540 }
3541
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003542 // Certificate
3543 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003544
Yu Liu4ae55d12022-01-05 17:17:23 -08003545 nativeSharedLibs := &convertedNativeSharedLibs{
3546 Native_shared_libs_32: bazel.LabelListAttribute{},
3547 Native_shared_libs_64: bazel.LabelListAttribute{},
3548 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003549
3550 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3551 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3552 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3553 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3554 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003555 if a.CompileMultilib() != nil {
3556 compileMultilib = *a.CompileMultilib()
3557 }
3558
3559 // properties.Native_shared_libs is treated as "both"
3560 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3561 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3562 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3563 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3564 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003565
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003566 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003567 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3568 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3569
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003570 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003571 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003572
Yu Liu4c212ce2022-10-14 12:20:20 -07003573 var testsAttrs bazel.LabelListAttribute
3574 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3575 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3576 testsAttrs = bazel.MakeLabelListAttribute(tests)
3577 }
3578
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003579 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003580 if a.properties.Updatable != nil {
3581 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003582 }
3583
3584 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003585 if a.properties.Installable != nil {
3586 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003587 }
3588
Wei Lif034cb42022-01-19 15:54:31 -08003589 var compressibleAttribute bazel.BoolAttribute
3590 if a.overridableProperties.Compressible != nil {
3591 compressibleAttribute.Value = a.overridableProperties.Compressible
3592 }
3593
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003594 var packageName *string
3595 if a.overridableProperties.Package_name != "" {
3596 packageName = &a.overridableProperties.Package_name
3597 }
3598
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003599 var loggingParent *string
3600 if a.overridableProperties.Logging_parent != "" {
3601 loggingParent = &a.overridableProperties.Logging_parent
3602 }
3603
Wei Li1c66fc72022-05-09 23:59:14 -07003604 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003605 Manifest: manifestLabelAttribute,
3606 Android_manifest: androidManifestLabelAttribute,
3607 File_contexts: fileContextsLabelAttribute,
3608 Min_sdk_version: minSdkVersion,
3609 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003610 Certificate: certificate,
3611 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003612 Updatable: updatableAttribute,
3613 Installable: installableAttribute,
3614 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3615 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3616 Binaries: binariesLabelListAttribute,
3617 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003618 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003619 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003620 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003621 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003622 }
3623
3624 props := bazel.BazelTargetModuleProperties{
3625 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003626 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003627 }
3628
Wei Li1c66fc72022-05-09 23:59:14 -07003629 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003630}
Yu Liu4ae55d12022-01-05 17:17:23 -08003631
3632// The following conversions are based on this table where the rows are the compile_multilib
3633// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3634// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3635// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3636// should not be compiled.
3637// multib/compile_multilib, 32, 64, both, first
3638// 32, 32/32, none/none, 32/32, none/32
3639// 64, none/none, 64/none, 64/none, 64/none
3640// both, 32/32, 64/none, 32&64/32, 64/32
3641// first, 32/32, 64/none, 64/32, 64/32
3642
3643func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3644 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3645 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3646 switch compileMultilb {
3647 case "both", "32":
3648 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3649 case "first":
3650 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3651 case "64":
3652 // Incompatible, ignore
3653 default:
3654 invalidCompileMultilib(ctx, compileMultilb)
3655 }
3656}
3657
3658func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3659 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3660 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3661 switch compileMultilb {
3662 case "both", "64", "first":
3663 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3664 case "32":
3665 // Incompatible, ignore
3666 default:
3667 invalidCompileMultilib(ctx, compileMultilb)
3668 }
3669}
3670
3671func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3672 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3673 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3674 switch compileMultilb {
3675 case "both":
3676 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3677 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3678 case "first":
3679 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3680 case "32":
3681 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3682 case "64":
3683 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3684 default:
3685 invalidCompileMultilib(ctx, compileMultilb)
3686 }
3687}
3688
3689func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3690 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3691 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3692 switch compileMultilb {
3693 case "both", "first":
3694 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3695 case "32":
3696 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3697 case "64":
3698 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3699 default:
3700 invalidCompileMultilib(ctx, compileMultilb)
3701 }
3702}
3703
3704func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3705 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3706 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3707}
3708
3709func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3710 list := bazel.LabelListAttribute{}
3711 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3712 nativeSharedLibs.Native_shared_libs_32.Append(list)
3713}
3714
3715func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3716 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3717 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3718}
3719
3720func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3721 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3722 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3723}
3724
3725func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3726 labelListAttr *bazel.LabelListAttribute) {
3727 list := bazel.LabelListAttribute{}
3728 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3729 labelListAttr.Append(list)
3730}
3731
3732func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3733 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3734}