blob: db884a19b642068e9913f5dcdf3da07e1aa09342 [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()
Spandan Das66773252022-01-15 00:23:18 +000083 // Register after apex_info mutator so that it can use ApexVariationName
84 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090085}
86
87type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090088 // Json manifest file describing meta info of this APEX bundle. Refer to
89 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090090 Manifest *string `android:"path"`
91
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090092 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
93 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090094 AndroidManifest *string `android:"path"`
95
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090096 // Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
97 // device (/apex/<apex_name>). If unspecified, follows the name property.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090098 Apex_name *string
99
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900100 // Determines the file contexts file for setting the security contexts to files in this APEX
101 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
102 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900103 File_contexts *string `android:"path"`
104
Jiyong Park038e8522021-12-13 23:56:35 +0900105 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
106 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
107 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
108 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
109 // capability. If this property is not set, or a file is missing in the file, default config
110 // is used.
111 Canned_fs_config *string `android:"path"`
112
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900113 ApexNativeDependencies
114
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900115 Multilib apexMultilibProperties
116
Sundong Ahn80c04892021-11-23 00:57:19 +0000117 // List of sh binaries that are embedded inside this APEX bundle.
118 Sh_binaries []string
119
Paul Duffin3abc1742021-03-15 19:32:23 +0000120 // List of platform_compat_config files that are embedded inside this APEX bundle.
121 Compat_configs []string
122
Jiyong Park12a719c2021-01-07 15:31:24 +0900123 // List of filesystem images that are embedded inside this APEX bundle.
124 Filesystems []string
125
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900126 // The minimum SDK version that this APEX must support at minimum. This is usually set to
127 // the SDK version that the APEX was first introduced.
128 Min_sdk_version *string
129
130 // Whether this APEX is considered updatable or not. When set to true, this will enforce
131 // additional rules for making sure that the APEX is truly updatable. To be updatable,
132 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000133 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900134 Updatable *bool
135
Jiyong Parkf4020582021-11-29 12:37:10 +0900136 // Marks that this APEX is designed to be updatable in the future, although it's not
137 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
138 // updatable APEXes. Currently, this disables the size optimization, so that the size of
139 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
140 // false.
141 Future_updatable *bool
142
Jiyong Park1bc84122021-06-22 20:23:05 +0900143 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
144 // false`. Default is false.
145 Platform_apis *bool
146
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900147 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
148 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900149 Installable *bool
150
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900151 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
152 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
153 Use_vndk_as_stable *bool
154
Daniel Norman6cfb37af2021-11-16 20:28:29 +0000155 // Whether this is multi-installed APEX should skip installing symbol files.
156 // Multi-installed APEXes share the same apex_name and are installed at the same time.
157 // Default is false.
158 //
159 // Should be set to true for all multi-installed APEXes except the singular
160 // default version within the multi-installed group.
161 // Only the default version can install symbol files in $(PRODUCT_OUT}/apex,
162 // or else conflicting build rules may be created.
163 Multi_install_skip_symbol_files *bool
164
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900165 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
166 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
167 // container. When set to zip, contents are stored in a zip container directly. This type is
168 // mostly for host-side debugging. When set to both, the two types are both built. Default
169 // is 'image'.
170 Payload_type *string
171
Huang Jianan13cac632021-08-02 15:02:17 +0800172 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
173 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900174 Payload_fs_type *string
175
176 // For telling the APEX to ignore special handling for system libraries such as bionic.
177 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900178 Ignore_system_library_special_case *bool
179
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100180 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100181 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100182 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900183
184 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
185 // used in tests.
186 Test_only_unsigned_payload *bool
187
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000188 // Whenever apex should be compressed, regardless of product flag used. Should be only
189 // used in tests.
190 Test_only_force_compression *bool
191
Jooyung Han09c11ad2021-10-27 03:45:31 +0900192 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
193 // with the tool to sign payload contents.
194 Custom_sign_tool *string
195
Dennis Shenaf41bc12022-08-03 16:46:43 +0000196 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
197 // in a special way that include the digest of the lib file under /lib(64)?
198 Dynamic_common_lib_apex *bool
199
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100200 // Canonical name of this APEX bundle. Used to determine the path to the
201 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
202 // apex mutator variations. For override_apex modules, this is the name of the
203 // overridden base module.
204 ApexVariationName string `blueprint:"mutated"`
205
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900206 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900207
208 // List of sanitizer names that this APEX is enabled for
209 SanitizerNames []string `blueprint:"mutated"`
210
211 PreventInstall bool `blueprint:"mutated"`
212
213 HideFromMake bool `blueprint:"mutated"`
214
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900215 // Internal package method for this APEX. When payload_type is image, this can be either
216 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
217 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900218 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900219}
220
221type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900222 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900223 Native_shared_libs []string
224
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900225 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900226 Jni_libs []string
227
Colin Cross70572ed2022-11-02 13:14:20 -0700228 // List of rust dyn libraries that are embedded inside this APEX.
Jiyong Park99644e92020-11-17 22:21:02 +0900229 Rust_dyn_libs []string
230
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900231 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900232 Binaries []string
233
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900234 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900235 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900236
237 // List of filesystem images that are embedded inside this APEX bundle.
238 Filesystems []string
Colin Cross70572ed2022-11-02 13:14:20 -0700239
240 // List of native libraries to exclude from this APEX.
241 Exclude_native_shared_libs []string
242
243 // List of JNI libraries to exclude from this APEX.
244 Exclude_jni_libs []string
245
246 // List of rust dyn libraries to exclude from this APEX.
247 Exclude_rust_dyn_libs []string
248
249 // List of native executables to exclude from this APEX.
250 Exclude_binaries []string
251
252 // List of native tests to exclude from this APEX.
253 Exclude_tests []string
254
255 // List of filesystem images to exclude from this APEX bundle.
256 Exclude_filesystems []string
257}
258
259// Merge combines another ApexNativeDependencies into this one
260func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
261 a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
262 a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
263 a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
264 a.Binaries = append(a.Binaries, b.Binaries...)
265 a.Tests = append(a.Tests, b.Tests...)
266 a.Filesystems = append(a.Filesystems, b.Filesystems...)
267
268 a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
269 a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
270 a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
271 a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
272 a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
273 a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900274}
275
276type apexMultilibProperties struct {
277 // Native dependencies whose compile_multilib is "first"
278 First ApexNativeDependencies
279
280 // Native dependencies whose compile_multilib is "both"
281 Both ApexNativeDependencies
282
283 // Native dependencies whose compile_multilib is "prefer32"
284 Prefer32 ApexNativeDependencies
285
286 // Native dependencies whose compile_multilib is "32"
287 Lib32 ApexNativeDependencies
288
289 // Native dependencies whose compile_multilib is "64"
290 Lib64 ApexNativeDependencies
291}
292
293type apexTargetBundleProperties struct {
294 Target struct {
295 // Multilib properties only for android.
296 Android struct {
297 Multilib apexMultilibProperties
298 }
299
300 // Multilib properties only for host.
301 Host struct {
302 Multilib apexMultilibProperties
303 }
304
305 // Multilib properties only for host linux_bionic.
306 Linux_bionic struct {
307 Multilib apexMultilibProperties
308 }
309
310 // Multilib properties only for host linux_glibc.
311 Linux_glibc struct {
312 Multilib apexMultilibProperties
313 }
314 }
315}
316
Jiyong Park59140302020-12-14 18:44:04 +0900317type apexArchBundleProperties struct {
318 Arch struct {
319 Arm struct {
320 ApexNativeDependencies
321 }
322 Arm64 struct {
323 ApexNativeDependencies
324 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700325 Riscv64 struct {
326 ApexNativeDependencies
327 }
Jiyong Park59140302020-12-14 18:44:04 +0900328 X86 struct {
329 ApexNativeDependencies
330 }
331 X86_64 struct {
332 ApexNativeDependencies
333 }
334 }
335}
336
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900337// These properties can be used in override_apex to override the corresponding properties in the
338// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900339type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900340 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900341 Apps []string
342
Daniel Norman5a3ce132021-08-26 15:44:43 -0700343 // List of prebuilt files that are embedded inside this APEX bundle.
344 Prebuilts []string
345
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900346 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900347 Rros []string
348
markchien7c803b82021-08-26 22:10:06 +0800349 // List of BPF programs inside this APEX bundle.
350 Bpfs []string
351
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900352 // List of bootclasspath fragments that are embedded inside this APEX bundle.
353 Bootclasspath_fragments []string
354
355 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
356 Systemserverclasspath_fragments []string
357
358 // List of java libraries that are embedded inside this APEX bundle.
359 Java_libs []string
360
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900361 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
362 // Soong). This does not completely prevent installation of the overridden binaries, but if
363 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
364 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900365 Overrides []string
366
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900367 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900368 Logging_parent string
369
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900370 // Apex Container package name. Override value for attribute package:name in
371 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900372 Package_name string
373
374 // A txt file containing list of files that are allowed to be included in this APEX.
375 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700376
377 // Name of the apex_key module that provides the private key to sign this APEX bundle.
378 Key *string
379
380 // Specifies the certificate and the private key to sign the zip container of this APEX. If
381 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
382 // as the certificate and the private key, respectively. If this is ":module", then the
383 // certificate and the private key are provided from the android_app_certificate module
384 // named "module".
385 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400386
387 // Whether this APEX can be compressed or not. Setting this property to false means this
388 // APEX will never be compressed. When set to true, APEX will be compressed if other
389 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
390 // Default: false.
391 Compressible *bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900392}
393
394type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900395 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900396 android.ModuleBase
397 android.DefaultableModuleBase
398 android.OverridableModuleBase
399 android.SdkBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400400 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900401 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900402
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900403 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900404 properties apexBundleProperties
405 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900406 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900407 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900408 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900409
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900410 ///////////////////////////////////////////////////////////////////////////////////////////
411 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900412
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900413 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800414 publicKeyFile android.Path
415 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900416
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900417 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800418 containerCertificateFile android.Path
419 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900420
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900421 // Flags for special variants of APEX
422 testApex bool
423 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900424
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900425 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
426 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900427 primaryApexType bool
428
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900429 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900430 suffix string
431
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900432 // File system type of apex_payload.img
433 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900434
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900435 // Whether to create symlink to the system file instead of having a file inside the apex or
436 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900437 linkToSystemLib bool
438
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900439 // List of files to be included in this APEX. This is filled in the first part of
440 // GenerateAndroidBuildActions.
441 filesInfo []apexFile
442
443 // List of other module names that should be installed when this APEX gets installed.
444 requiredDeps []string
445
446 ///////////////////////////////////////////////////////////////////////////////////////////
447 // Outputs (final and intermediates)
448
449 // Processed apex manifest in JSONson format (for Q)
450 manifestJsonOut android.WritablePath
451
452 // Processed apex manifest in PB format (for R+)
453 manifestPbOut android.WritablePath
454
455 // Processed file_contexts files
456 fileContexts android.WritablePath
457
Bob Badourde6a0872022-04-01 18:00:00 +0000458 // Path to notice file in html.gz format.
459 htmlGzNotice android.WritablePath
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900460
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"}
682 executableTag = &dependencyTag{name: "executable", payload: true}
683 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000684 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
685 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000686 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000687 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
688 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
689 keyTag = &dependencyTag{name: "key"}
690 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
691 rroTag = &dependencyTag{name: "rro", payload: true}
692 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
693 testForTag = &dependencyTag{name: "test for"}
694 testTag = &dependencyTag{name: "test", payload: true}
695 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900696)
697
698// TODO(jiyong): shorten this function signature
699func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900700 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900701 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900702 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900703
704 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900705 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900706 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
707 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900708 }
709
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900710 // Use *FarVariation* to be able to depend on modules having conflicting variations with
711 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
712 // 'arm' or 'arm64' for native shared libs.
Colin Cross70572ed2022-11-02 13:14:20 -0700713 ctx.AddFarVariationDependencies(binVariations, executableTag,
714 android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
715 ctx.AddFarVariationDependencies(binVariations, testTag,
716 android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
717 ctx.AddFarVariationDependencies(libVariations, jniLibTag,
718 android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
719 ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
720 android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
721 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
722 android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
723 ctx.AddFarVariationDependencies(target.Variations(), fsTag,
724 android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900725}
726
727func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900728 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900729 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
730 } else {
731 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
732 if ctx.Os().Bionic() {
733 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
734 } else {
735 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
736 }
737 }
738}
739
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900740// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
741// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
742func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
743 deviceConfig := ctx.DeviceConfig()
744 if a.vndkApex {
745 return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900746 }
747
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900748 var prefix string
749 var vndkVersion string
750 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000751 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900752 prefix = cc.VendorVariationPrefix
753 vndkVersion = deviceConfig.VndkVersion()
754 } else if a.ProductSpecific() {
755 prefix = cc.ProductVariationPrefix
756 vndkVersion = deviceConfig.ProductVndkVersion()
757 }
758 }
759 if vndkVersion == "current" {
760 vndkVersion = deviceConfig.PlatformVndkVersion()
761 }
762 if vndkVersion != "" {
763 return prefix + vndkVersion
764 }
765
766 return android.CoreVariation // The usual case
767}
768
769func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900770 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
771 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
772 // each target os/architectures, appropriate dependencies are selected by their
773 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900774 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900775 imageVariation := a.getImageVariation(ctx)
776
777 a.combineProperties(ctx)
778
779 has32BitTarget := false
780 for _, target := range targets {
781 if target.Arch.ArchType.Multilib == "lib32" {
782 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000783 }
784 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900785 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900786 // Don't include artifacts for the host cross targets because there is no way for us
787 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900788 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900789 continue
790 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000791
Colin Cross70572ed2022-11-02 13:14:20 -0700792 var deps ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000793
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900794 // Add native modules targeting both ABIs. When multilib.* is omitted for
795 // native_shared_libs/jni_libs/tests, it implies multilib.both
Colin Cross70572ed2022-11-02 13:14:20 -0700796 deps.Merge(a.properties.Multilib.Both)
797 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900798 Native_shared_libs: a.properties.Native_shared_libs,
799 Tests: a.properties.Tests,
800 Jni_libs: a.properties.Jni_libs,
801 Binaries: nil,
802 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900803
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900804 // Add native modules targeting the first ABI When multilib.* is omitted for
805 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900806 isPrimaryAbi := i == 0
807 if isPrimaryAbi {
Colin Cross70572ed2022-11-02 13:14:20 -0700808 deps.Merge(a.properties.Multilib.First)
809 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900810 Native_shared_libs: nil,
811 Tests: nil,
812 Jni_libs: nil,
813 Binaries: a.properties.Binaries,
814 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900815 }
816
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900817 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900818 switch target.Arch.ArchType.Multilib {
819 case "lib32":
Colin Cross70572ed2022-11-02 13:14:20 -0700820 deps.Merge(a.properties.Multilib.Lib32)
821 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900822 case "lib64":
Colin Cross70572ed2022-11-02 13:14:20 -0700823 deps.Merge(a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900824 if !has32BitTarget {
Colin Cross70572ed2022-11-02 13:14:20 -0700825 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900826 }
827 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900828
Jiyong Park59140302020-12-14 18:44:04 +0900829 // Add native modules targeting a specific arch variant
830 switch target.Arch.ArchType {
831 case android.Arm:
Colin Cross70572ed2022-11-02 13:14:20 -0700832 deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900833 case android.Arm64:
Colin Cross70572ed2022-11-02 13:14:20 -0700834 deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700835 case android.Riscv64:
Colin Cross70572ed2022-11-02 13:14:20 -0700836 deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900837 case android.X86:
Colin Cross70572ed2022-11-02 13:14:20 -0700838 deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900839 case android.X86_64:
Colin Cross70572ed2022-11-02 13:14:20 -0700840 deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900841 default:
842 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
843 }
844
Colin Cross70572ed2022-11-02 13:14:20 -0700845 addDependenciesForNativeModules(ctx, deps, target, imageVariation)
Sundong Ahn80c04892021-11-23 00:57:19 +0000846 ctx.AddFarVariationDependencies([]blueprint.Variation{
847 {Mutator: "os", Variation: target.OsVariation()},
848 {Mutator: "arch", Variation: target.ArchVariation()},
849 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900850 }
851
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900852 // Common-arch dependencies come next
853 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900854 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000855 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100856}
857
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900858// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900859func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
860 if a.overridableProperties.Allowed_files != nil {
861 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100862 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900863
864 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
865 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800866 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900867 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900868 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
869 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
870 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700871 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
872 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
873 // regardless of the TARGET_PREFER_* setting. See b/144532908
874 arches := ctx.DeviceConfig().Arches()
875 if len(arches) != 0 {
876 archForPrebuiltEtc := arches[0]
877 for _, arch := range arches {
878 // Prefer 64-bit arch if there is any
879 if arch.ArchType.Multilib == "lib64" {
880 archForPrebuiltEtc = arch
881 break
882 }
883 }
884 ctx.AddFarVariationDependencies([]blueprint.Variation{
885 {Mutator: "os", Variation: ctx.Os().String()},
886 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
887 }, prebuiltTag, prebuilts...)
888 }
889 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700890
891 // Dependencies for signing
892 if String(a.overridableProperties.Key) == "" {
893 ctx.PropertyErrorf("key", "missing")
894 return
895 }
896 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
897
898 cert := android.SrcIsModule(a.getCertString(ctx))
899 if cert != "" {
900 ctx.AddDependency(ctx.Module(), certificateTag, cert)
901 // empty cert is not an error. Cert and private keys will be directly found under
902 // PRODUCT_DEFAULT_DEV_CERTIFICATE
903 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100904}
905
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900906type ApexBundleInfo struct {
907 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100908}
909
Paul Duffin949abc02020-12-08 10:34:30 +0000910var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900911
Paul Duffina7d6a892020-12-07 17:39:59 +0000912var _ ApexInfoMutator = (*apexBundle)(nil)
913
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100914func (a *apexBundle) ApexVariationName() string {
915 return a.properties.ApexVariationName
916}
917
Paul Duffina7d6a892020-12-07 17:39:59 +0000918// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900919// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
920// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
921// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
922// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000923//
924// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
925// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
926// The apexMutator uses that list to create module variants for the apexes to which it belongs.
927// The relationship between module variants and apexes is not one-to-one as variants will be
928// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000929func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900930
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900931 // The VNDK APEX is special. For the APEX, the membership is described in a very different
932 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
933 // libraries are self-identified by their vndk.enabled properties. There is no need to run
934 // this mutator for the APEX as nothing will be collected. So, let's return fast.
935 if a.vndkApex {
936 return
937 }
938
939 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
940 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
941 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
942 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
943 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900944 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
945 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900946 if proptools.Bool(a.properties.Use_vndk_as_stable) {
947 if !useVndk {
948 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
949 }
950 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
951 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
952 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
953 }
954 })
955 if mctx.Failed() {
956 return
957 }
Jooyung Handf78e212020-07-22 15:54:47 +0900958 }
959
Colin Cross56a83212020-09-15 18:30:11 -0700960 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900961 am, ok := child.(android.ApexModule)
962 if !ok || !am.CanHaveApexVariants() {
963 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900964 }
Paul Duffin573989d2021-03-17 13:25:29 +0000965 depTag := mctx.OtherModuleDependencyTag(child)
966
967 // Check to see if the tag always requires that the child module has an apex variant for every
968 // apex variant of the parent module. If it does not then it is still possible for something
969 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
970 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
971 return true
972 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000973 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900974 return false
975 }
Jooyung Handf78e212020-07-22 15:54:47 +0900976 if excludeVndkLibs {
977 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
978 return false
979 }
980 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900981 // By default, all the transitive dependencies are collected, unless filtered out
982 // above.
Colin Cross56a83212020-09-15 18:30:11 -0700983 return true
984 }
985
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900986 // Records whether a certain module is included in this apexBundle via direct dependency or
987 // inndirect dependency.
988 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -0700989 mctx.WalkDeps(func(child, parent android.Module) bool {
990 if !continueApexDepsWalk(child, parent) {
991 return false
992 }
Jooyung Han698dd9f2020-07-22 15:17:19 +0900993 // If the parent is apexBundle, this child is directly depended.
994 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900995 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -0700996 contents[depName] = contents[depName].Add(directDep)
997 return true
998 })
999
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001000 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +09001001 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -07001002 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
1003 Contents: apexContents,
1004 })
1005
Jooyung Haned124c32021-01-26 11:43:46 +09001006 minSdkVersion := a.minSdkVersion(mctx)
1007 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
1008 if minSdkVersion.IsNone() {
1009 minSdkVersion = android.FutureApiLevel
1010 }
1011
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001012 // This is the main part of this mutator. Mark the collected dependencies that they need to
1013 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +09001014
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001015 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
1016 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -07001017 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001018 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +09001019 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -07001020 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +09001021 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001022 InApexVariants: []string{apexVariationName},
1023 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -07001024 ApexContents: []*android.ApexContents{apexContents},
1025 }
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 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001030 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +09001031 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +09001032 })
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001033}
1034
Paul Duffina7d6a892020-12-07 17:39:59 +00001035type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001036 // ApexVariationName returns the name of the APEX variation to use in the apex
1037 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
1038 ApexVariationName() string
1039
Paul Duffina7d6a892020-12-07 17:39:59 +00001040 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1041 // depended upon by an apex and which require an apex specific variant.
1042 ApexInfoMutator(android.TopDownMutatorContext)
1043}
1044
1045// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1046// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001047// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001048func apexInfoMutator(mctx android.TopDownMutatorContext) {
1049 if !mctx.Module().Enabled() {
1050 return
1051 }
1052
1053 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1054 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001055 }
Spandan Das42e89502022-05-06 22:12:55 +00001056 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001057}
1058
Spandan Das66773252022-01-15 00:23:18 +00001059// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1060// This check is enforced for updatable modules
1061func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1062 if !mctx.Module().Enabled() {
1063 return
1064 }
Spandan Das08c911f2022-01-21 22:07:26 +00001065 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001066 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001067 // b/208656169 Do not propagate strict updatability linting to libcore/
1068 // These libs are available on the classpath during compilation
1069 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1070 // Only skip libraries defined in libcore root, not subdirectories
1071 if mctx.OtherModuleDir(child) == "libcore" {
1072 // Do not traverse transitive deps of libcore/ libs
1073 return false
1074 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001075 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1076 return false
1077 }
Spandan Das66773252022-01-15 00:23:18 +00001078 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1079 lintable.SetStrictUpdatabilityLinting(true)
1080 }
1081 // visit transitive deps
1082 return true
1083 })
1084 }
1085}
1086
Spandan Das42e89502022-05-06 22:12:55 +00001087// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1088func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1089 if !mctx.Module().Enabled() {
1090 return
1091 }
1092 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1093 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1094 mctx.VisitDirectDeps(func(module android.Module) {
1095 // ignore android_test_app
1096 if app, ok := module.(*java.AndroidApp); ok {
1097 app.SetUpdatable(true)
1098 }
1099 })
1100 }
1101}
1102
Spandan Das08c911f2022-01-21 22:07:26 +00001103// TODO: b/215736885 Whittle the denylist
1104// Transitive deps of certain mainline modules baseline NewApi errors
1105// Skip these mainline modules for now
1106var (
1107 skipStrictUpdatabilityLintAllowlist = []string{
1108 "com.android.art",
1109 "com.android.art.debug",
1110 "com.android.conscrypt",
1111 "com.android.media",
1112 // test apexes
1113 "test_com.android.art",
1114 "test_com.android.conscrypt",
1115 "test_com.android.media",
1116 "test_jitzygote_com.android.art",
1117 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001118
1119 // TODO: b/215736885 Remove this list
1120 skipLintJavalibAllowlist = []string{
1121 "conscrypt.module.platform.api.stubs",
1122 "conscrypt.module.public.api.stubs",
1123 "conscrypt.module.public.api.stubs.system",
1124 "conscrypt.module.public.api.stubs.module_lib",
1125 "framework-media.stubs",
1126 "framework-media.stubs.system",
1127 "framework-media.stubs.module_lib",
1128 }
Spandan Das08c911f2022-01-21 22:07:26 +00001129)
1130
1131func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1132 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1133}
1134
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001135// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1136// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1137// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001138func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1139 if !mctx.Module().Enabled() {
1140 return
1141 }
1142 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001143 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1144 }
1145}
1146
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001147// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1148// the apex in order to retrieve its contents later.
1149// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001150func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1151 if !mctx.Module().Enabled() {
1152 return
1153 }
Colin Cross56a83212020-09-15 18:30:11 -07001154 if am, ok := mctx.Module().(android.ApexModule); ok {
1155 if testFor := am.TestFor(); len(testFor) > 0 {
1156 mctx.AddFarVariationDependencies([]blueprint.Variation{
1157 {Mutator: "os", Variation: am.Target().OsVariation()},
1158 {"arch", "common"},
1159 }, testForTag, testFor...)
1160 }
1161 }
1162}
1163
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001164// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001165func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1166 if !mctx.Module().Enabled() {
1167 return
1168 }
Colin Cross56a83212020-09-15 18:30:11 -07001169 if _, ok := mctx.Module().(android.ApexModule); ok {
1170 var contents []*android.ApexContents
1171 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1172 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1173 contents = append(contents, abInfo.Contents)
1174 }
1175 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1176 ApexContents: contents,
1177 })
Colin Crossaede88c2020-08-11 12:17:01 -07001178 }
1179}
1180
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001181// markPlatformAvailability marks whether or not a module can be available to platform. A module
1182// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1183// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1184// be) available to platform
1185// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001186func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1187 // Host and recovery are not considered as platform
1188 if mctx.Host() || mctx.Module().InstallInRecovery() {
1189 return
1190 }
1191
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001192 am, ok := mctx.Module().(android.ApexModule)
1193 if !ok {
1194 return
1195 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001196
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001197 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001198
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001199 // If any of the dep is not available to platform, this module is also considered as being
1200 // not available to platform even if it has "//apex_available:platform"
1201 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001202 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001203 // if the dependency crosses apex boundary, don't consider it
1204 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001205 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001206 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1207 availableToPlatform = false
1208 // TODO(b/154889534) trigger an error when 'am' has
1209 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001210 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001211 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001212
Paul Duffinb5769c12021-05-12 16:16:51 +01001213 // Exception 1: check to see if the module always requires it.
1214 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001215 availableToPlatform = true
1216 }
1217
1218 // Exception 2: bootstrap bionic libraries are also always available to platform
1219 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1220 availableToPlatform = true
1221 }
1222
1223 if !availableToPlatform {
1224 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001225 }
1226}
1227
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001228// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001229// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001230func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001231 if !mctx.Module().Enabled() {
1232 return
1233 }
Colin Cross56a83212020-09-15 18:30:11 -07001234
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001235 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001236 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001237 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001238 return
1239 }
1240
1241 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001242 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1243 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001244 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001245 if strings.HasPrefix(apexBundleName, "com.android.art") {
1246 // Create an alias from the platform variant. This is done to make
1247 // test_for dependencies work for modules that are split by the APEX
1248 // mutator, since test_for dependencies always go to the platform variant.
1249 // This doesn't happen for normal APEXes that are disjunct, so only do
1250 // this for the overlapping ART APEXes.
1251 // TODO(b/183882457): Remove this if the test_for functionality is
1252 // refactored to depend on the proper APEX variants instead of platform.
1253 mctx.CreateAliasVariation("", apexBundleName)
1254 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001255 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1256 apexBundleName := o.GetOverriddenModuleName()
1257 if apexBundleName == "" {
1258 mctx.ModuleErrorf("base property is not set")
1259 return
1260 }
1261 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001262 if strings.HasPrefix(apexBundleName, "com.android.art") {
1263 // TODO(b/183882457): See note for CreateAliasVariation above.
1264 mctx.CreateAliasVariation("", apexBundleName)
1265 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001266 }
1267}
Sundong Ahne9b55722019-09-06 17:37:42 +09001268
Paul Duffin6717d882021-06-15 19:09:41 +01001269// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1270// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001271func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001272 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001273 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001274 return !a.vndkApex
1275 }
1276
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001277 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001278}
1279
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001280// See android.UpdateDirectlyInAnyApex
1281// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001282func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1283 if !mctx.Module().Enabled() {
1284 return
1285 }
1286 if am, ok := mctx.Module().(android.ApexModule); ok {
1287 android.UpdateDirectlyInAnyApex(mctx, am)
1288 }
1289}
1290
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001291// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001292type apexPackaging int
1293
1294const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001295 // imageApex is a packaging method where contents are included in a filesystem image which
1296 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001297 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001298
1299 // zipApex is a packaging method where contents are directly included in the zip container.
1300 // This is used for host-side testing - because the contents are easily accessible by
1301 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001302 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001303
1304 // flattendApex is a packaging method where contents are not included in the APEX file, but
1305 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1306 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001307 flattenedApex
1308)
1309
1310const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001311 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001312 imageApexSuffix = ".apex"
1313 imageCapexSuffix = ".capex"
1314 zipApexSuffix = ".zipapex"
1315 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001316
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001317 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001318 imageApexType = "image"
1319 zipApexType = "zip"
1320 flattenedApexType = "flattened"
1321
Dan Willemsen47e1a752021-10-16 18:36:13 -07001322 ext4FsType = "ext4"
1323 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001324 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001325)
1326
1327// The suffix for the output "file", not the module
1328func (a apexPackaging) suffix() string {
1329 switch a {
1330 case imageApex:
1331 return imageApexSuffix
1332 case zipApex:
1333 return zipApexSuffix
1334 default:
1335 panic(fmt.Errorf("unknown APEX type %d", a))
1336 }
1337}
1338
1339func (a apexPackaging) name() string {
1340 switch a {
1341 case imageApex:
1342 return imageApexType
1343 case zipApex:
1344 return zipApexType
1345 default:
1346 panic(fmt.Errorf("unknown APEX type %d", a))
1347 }
1348}
1349
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001350// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1351// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001352func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001353 if !mctx.Module().Enabled() {
1354 return
1355 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001356 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001357 var variants []string
1358 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1359 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001360 // This is the normal case. Note that both image and flattend APEXes are
1361 // created. The image type is installed to the system partition, while the
1362 // flattened APEX is (optionally) installed to the system_ext partition.
1363 // This is mostly for GSI which has to support wide range of devices. If GSI
1364 // is installed on a newer (APEX-capable) device, the image APEX in the
1365 // system will be used. However, if the same GSI is installed on an old
1366 // device which can't support image APEX, the flattened APEX in the
1367 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001368 variants = append(variants, imageApexType, flattenedApexType)
1369 case "zip":
1370 variants = append(variants, zipApexType)
1371 case "both":
1372 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1373 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001374 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001375 return
1376 }
1377
1378 modules := mctx.CreateLocalVariations(variants...)
1379
1380 for i, v := range variants {
1381 switch v {
1382 case imageApexType:
1383 modules[i].(*apexBundle).properties.ApexType = imageApex
1384 case zipApexType:
1385 modules[i].(*apexBundle).properties.ApexType = zipApex
1386 case flattenedApexType:
1387 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001388 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001389 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001390 modules[i].(*apexBundle).MakeAsSystemExt()
1391 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001392 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001393 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001394 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001395 // payload_type is forcibly overridden to "image"
1396 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001397 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001398 }
1399}
1400
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001401var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001402
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001403// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001404func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001405 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001406 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001407 return true
1408}
1409
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001410var _ android.OutputFileProducer = (*apexBundle)(nil)
1411
1412// Implements android.OutputFileProducer
1413func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1414 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001415 case "", android.DefaultDistTag:
1416 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001417 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001418 case imageApexSuffix:
1419 // uncompressed one
1420 if a.outputApexFile != nil {
1421 return android.Paths{a.outputApexFile}, nil
1422 }
1423 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001424 default:
1425 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1426 }
1427}
1428
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001429var _ multitree.Exportable = (*apexBundle)(nil)
1430
1431func (a *apexBundle) Exportable() bool {
1432 if a.properties.ApexType == flattenedApex {
1433 return false
1434 }
1435 return true
1436}
1437
1438func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1439 ret := make(map[string]android.Paths)
1440 ret["apex"] = android.Paths{a.outputFile}
1441 return ret
1442}
1443
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001444var _ cc.Coverage = (*apexBundle)(nil)
1445
1446// Implements cc.Coverage
1447func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1448 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1449}
1450
1451// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001452func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001453 a.properties.PreventInstall = true
1454}
1455
1456// Implements cc.Coverage
1457func (a *apexBundle) HideFromMake() {
1458 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001459 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1460 // TODO(ccross): untangle these
1461 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001462}
1463
1464// Implements cc.Coverage
1465func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1466 a.properties.IsCoverageVariant = coverage
1467}
1468
1469// Implements cc.Coverage
1470func (a *apexBundle) EnableCoverageIfNeeded() {}
1471
1472var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1473
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001474// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001475func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001476 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001477}
1478
Jiyong Parkf4020582021-11-29 12:37:10 +09001479func (a *apexBundle) FutureUpdatable() bool {
1480 return proptools.BoolDefault(a.properties.Future_updatable, false)
1481}
1482
Jiyong Park1bc84122021-06-22 20:23:05 +09001483func (a *apexBundle) UsePlatformApis() bool {
1484 return proptools.BoolDefault(a.properties.Platform_apis, false)
1485}
1486
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001487// getCertString returns the name of the cert that should be used to sign this APEX. This is
1488// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001489func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001490 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001491 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1492 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1493 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001494 if a.vndkApex {
1495 moduleName = vndkApexName
1496 }
1497 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001498 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001499 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001500 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001501 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001502}
1503
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001504// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001505func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001506 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001507}
1508
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001509// See the generate_hashtree property
1510func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001511 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001512}
1513
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001514// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001515func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1516 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1517}
1518
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001519// See the test_only_force_compression property
1520func (a *apexBundle) testOnlyShouldForceCompression() bool {
1521 return proptools.Bool(a.properties.Test_only_force_compression)
1522}
1523
Dennis Shenaf41bc12022-08-03 16:46:43 +00001524// See the dynamic_common_lib_apex property
1525func (a *apexBundle) dynamic_common_lib_apex() bool {
1526 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1527}
1528
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001529// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1530// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1531// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001532
Jiyong Parkf97782b2019-02-13 20:28:58 +09001533func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1534 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1535 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1536 }
1537}
1538
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001539func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001540 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1541 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001542 }
1543
1544 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001545 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001546 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001547 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001548 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001549 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001550 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001551 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001552 }
1553 }
1554 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001555}
1556
Jooyung Han8ce8db92020-05-15 19:05:05 +09001557func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001558 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1559 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001560 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001561 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001562 for _, target := range ctx.MultiTargets() {
1563 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001564 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001565 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001566 Tests: nil,
1567 Jni_libs: nil,
1568 Binaries: nil,
1569 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001570 break
1571 }
1572 }
1573 }
1574}
1575
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001576// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1577// returned apexFile saves information about the Soong module that will be used for creating the
1578// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001579func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001580 // Decide the APEX-local directory by the multilib of the library In the future, we may
1581 // query this to the module.
1582 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001583 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001584 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001585 case "lib32":
1586 dirInApex = "lib"
1587 case "lib64":
1588 dirInApex = "lib64"
1589 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001590 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001591 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001592 }
Jooyung Han35155c42020-02-06 17:33:20 +09001593 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001594 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001595 // Special case for Bionic libs and other libs installed with them. This is to
1596 // prevent those libs from being included in the search path
1597 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1598 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1599 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1600 // will be loaded into the default linker namespace (aka "platform" namespace). If
1601 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1602 // be loaded again into the runtime linker namespace, which will result in double
1603 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001604 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001605 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001606
Colin Cross1d487152022-10-03 19:14:46 -07001607 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001608 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1609 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001610}
1611
Jiyong Park1833cef2019-12-13 13:28:36 +09001612func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001613 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001614 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001615 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001616 }
Jooyung Han35155c42020-02-06 17:33:20 +09001617 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001618 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001619 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1620 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001621 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001622 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001623 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001624}
1625
Jiyong Park99644e92020-11-17 22:21:02 +09001626func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1627 dirInApex := "bin"
1628 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1629 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1630 }
Colin Cross1d487152022-10-03 19:14:46 -07001631 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001632 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1633 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1634 return af
1635}
1636
1637func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1638 // Decide the APEX-local directory by the multilib of the library
1639 // In the future, we may query this to the module.
1640 var dirInApex string
1641 switch rustm.Arch().ArchType.Multilib {
1642 case "lib32":
1643 dirInApex = "lib"
1644 case "lib64":
1645 dirInApex = "lib64"
1646 }
1647 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1648 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1649 }
Colin Cross1d487152022-10-03 19:14:46 -07001650 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001651 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1652 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1653}
1654
Jiyong Park1833cef2019-12-13 13:28:36 +09001655func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001656 dirInApex := "bin"
1657 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001658 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001659}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001660
Jiyong Park1833cef2019-12-13 13:28:36 +09001661func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001662 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001663 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001664 // NB: Since go binaries are static we don't need the module for anything here, which is
1665 // good since the go tool is a blueprint.Module not an android.Module like we would
1666 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001667 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001668}
1669
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001670func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001671 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001672 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1673 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1674 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001675 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001676 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001677 af.symlinks = sh.Symlinks()
1678 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001679}
1680
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001681func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001682 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001683 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001684 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001685}
1686
atrost6e126252020-01-27 17:01:16 +00001687func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1688 dirInApex := filepath.Join("etc", config.SubDir())
1689 fileToCopy := config.CompatConfig()
1690 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1691}
1692
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001693// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1694// way.
1695type javaModule interface {
1696 android.Module
1697 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001698 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001699 JacocoReportClassesFile() android.Path
1700 LintDepSets() java.LintDepSets
1701 Stem() string
1702}
1703
1704var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001705var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001706var _ javaModule = (*java.SdkLibrary)(nil)
1707var _ javaModule = (*java.DexImport)(nil)
1708var _ javaModule = (*java.SdkLibraryImport)(nil)
1709
Paul Duffin190fdef2021-04-26 10:33:59 +01001710// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001711func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001712 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001713}
1714
1715// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1716func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001717 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001718 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001719 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1720 af.lintDepSets = module.LintDepSets()
1721 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001722 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1723 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1724 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1725 }
1726 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001727 return af
1728}
1729
1730// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1731// the same way.
1732type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001733 android.Module
1734 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001735 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001736 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001737 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001738 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001739 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001740 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001741}
1742
1743var _ androidApp = (*java.AndroidApp)(nil)
1744var _ androidApp = (*java.AndroidAppImport)(nil)
1745
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001746func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1747 buildId := ctx.Config().BuildId()
1748
1749 // The build ID is used as a suffix for a filename, so ensure that
1750 // the set of characters being used are sanitized.
1751 // - any word character: [a-zA-Z0-9_]
1752 // - dots: .
1753 // - dashes: -
1754 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1755 if !validRegex.MatchString(buildId) {
1756 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1757 }
1758 return buildId
1759}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001760
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001761func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001762 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001763 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001764 appDir = "priv-app"
1765 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001766
1767 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1768 // so that PackageManager correctly invalidates the existing installed apk
1769 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001770 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001771 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001772
Yo Chiange8128052020-07-23 20:09:18 +08001773 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001774 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001775 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001776 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001777
1778 if app, ok := aapp.(interface {
1779 OverriddenManifestPackageName() string
1780 }); ok {
1781 af.overriddenPackageName = app.OverriddenManifestPackageName()
1782 }
Jiyong Park618922e2020-01-08 13:35:43 +09001783 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001784}
1785
Jiyong Park69aeba92020-04-24 21:16:36 +09001786func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1787 rroDir := "overlay"
1788 dirInApex := filepath.Join(rroDir, rro.Theme())
1789 fileToCopy := rro.OutputFile()
1790 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1791 af.certificate = rro.Certificate()
1792
1793 if a, ok := rro.(interface {
1794 OverriddenManifestPackageName() string
1795 }); ok {
1796 af.overriddenPackageName = a.OverriddenManifestPackageName()
1797 }
1798 return af
1799}
1800
Ken Chenfad7f9d2021-11-10 22:02:57 +08001801func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1802 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001803 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1804}
1805
Jiyong Park12a719c2021-01-07 15:31:24 +09001806func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1807 dirInApex := filepath.Join("etc", "fs")
1808 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1809}
1810
Paul Duffin064b70c2020-11-02 17:32:38 +00001811// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001812// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1813// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1814// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001815func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001816 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001817 am, ok := child.(android.ApexModule)
1818 if !ok || !am.CanHaveApexVariants() {
1819 return false
1820 }
1821
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001822 // Filter-out unwanted depedendencies
1823 depTag := ctx.OtherModuleDependencyTag(child)
1824 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1825 return false
1826 }
Paul Duffin520917a2022-05-13 13:01:59 +00001827 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001828 return false
1829 }
1830
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001831 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001832 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001833
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001834 // Visit actually
1835 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001836 })
1837}
1838
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001839// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1840type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001841
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001842const (
1843 ext4 fsType = iota
1844 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001845 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001846)
Artur Satayev849f8442020-04-28 14:57:42 +01001847
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001848func (f fsType) string() string {
1849 switch f {
1850 case ext4:
1851 return ext4FsType
1852 case f2fs:
1853 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001854 case erofs:
1855 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001856 default:
1857 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001858 }
1859}
1860
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001861var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1862
1863func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1864 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1865}
1866
1867func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1868 bazelCtx := ctx.Config().BazelContext
1869 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1870}
1871
1872func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1873 if !a.commonBuildActions(ctx) {
1874 return
1875 }
1876
1877 a.setApexTypeAndSuffix(ctx)
1878 a.setPayloadFsType(ctx)
1879 a.setSystemLibLink(ctx)
1880
1881 if a.properties.ApexType != zipApex {
1882 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1883 }
1884
1885 bazelCtx := ctx.Config().BazelContext
1886 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1887 if err != nil {
1888 ctx.ModuleErrorf(err.Error())
1889 return
1890 }
1891 a.installDir = android.PathForModuleInstall(ctx, "apex")
1892 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1893 a.outputFile = a.outputApexFile
1894 a.setCompression(ctx)
1895
Liz Kammer0e255ef2022-11-04 16:07:04 -04001896 // TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
1897 // interface if these were set in a provider rather than the module itself
Wei Li32dcdf92022-10-26 22:30:48 -07001898 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1899 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1900 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1901 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Liz Kammer0e255ef2022-11-04 16:07:04 -04001902
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001903 apexType := a.properties.ApexType
1904 switch apexType {
1905 case imageApex:
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001906 // TODO(b/190817312): Generate the notice file from the apex rule.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001907 a.htmlGzNotice = android.PathForBazelOut(ctx, "NOTICE.html.gz")
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001908 // TODO(b/239081457): Generate the bazel bundle module file from the apex rule.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001909 a.bundleModuleFile = android.PathForBazelOut(ctx, a.Name()+apexType.suffix()+"-base.zip")
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001910 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
1911 // TODO(b/239081456): Generate the backing.txt file from Bazel.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001912 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_backing.txt"))
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001913 // TODO(b/239084755): Generate the java api using.xml file from Bazel.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001914 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.xml"))
1915 installSuffix := imageApexSuffix
1916 if a.isCompressed {
1917 installSuffix = imageCapexSuffix
1918 }
1919 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1920 a.compatSymlinks.Paths()...)
1921 default:
1922 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1923 }
1924
1925 /*
1926 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1927 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1928 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1929 To find out what Soong build puts there, run:
1930 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1931 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1932 return a.depVisitor(&vctx, ctx, child, parent)
1933 })
1934 vctx.normalizeFileInfo()
1935 */
1936
1937}
1938
1939func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1940 if a.properties.ApexType != imageApex {
1941 a.isCompressed = false
1942 } else if a.testOnlyShouldForceCompression() {
1943 a.isCompressed = true
1944 } else {
1945 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1946 }
1947}
1948
1949func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1950 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1951 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1952 // the same library in the system partition, thus effectively sharing the same libraries
1953 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1954 // in the APEX.
1955 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1956
1957 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1958 // So we can't link them to /system/lib libs which are core variants.
1959 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1960 a.linkToSystemLib = false
1961 }
1962
1963 forced := ctx.Config().ForceApexSymlinkOptimization()
1964 updatable := a.Updatable() || a.FutureUpdatable()
1965
1966 // We don't need the optimization for updatable APEXes, as it might give false signal
1967 // to the system health when the APEXes are still bundled (b/149805758).
1968 if !forced && updatable && a.properties.ApexType == imageApex {
1969 a.linkToSystemLib = false
1970 }
1971
1972 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1973 if ctx.Host() {
1974 a.linkToSystemLib = false
1975 }
1976}
1977
1978func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1979 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
1980 case ext4FsType:
1981 a.payloadFsType = ext4
1982 case f2fsFsType:
1983 a.payloadFsType = f2fs
1984 case erofsFsType:
1985 a.payloadFsType = erofs
1986 default:
1987 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
1988 }
1989}
1990
1991func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
1992 // Set suffix and primaryApexType depending on the ApexType
1993 buildFlattenedAsDefault := ctx.Config().FlattenApex()
1994 switch a.properties.ApexType {
1995 case imageApex:
1996 if buildFlattenedAsDefault {
1997 a.suffix = imageApexSuffix
1998 } else {
1999 a.suffix = ""
2000 a.primaryApexType = true
2001
2002 if ctx.Config().InstallExtraFlattenedApexes() {
2003 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
2004 }
2005 }
2006 case zipApex:
2007 if proptools.String(a.properties.Payload_type) == "zip" {
2008 a.suffix = ""
2009 a.primaryApexType = true
2010 } else {
2011 a.suffix = zipApexSuffix
2012 }
2013 case flattenedApex:
2014 if buildFlattenedAsDefault {
2015 a.suffix = ""
2016 a.primaryApexType = true
2017 } else {
2018 a.suffix = flattenedSuffix
2019 }
2020 }
2021}
2022
2023func (a apexBundle) isCompressable() bool {
2024 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
2025}
2026
2027func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
2028 a.checkApexAvailability(ctx)
2029 a.checkUpdatable(ctx)
2030 a.CheckMinSdkVersion(ctx)
2031 a.checkStaticLinkingToStubLibraries(ctx)
2032 a.checkStaticExecutables(ctx)
2033 if len(a.properties.Tests) > 0 && !a.testApex {
2034 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
2035 return false
2036 }
2037 return true
2038}
2039
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002040type visitorContext struct {
2041 // all the files that will be included in this APEX
2042 filesInfo []apexFile
2043
2044 // native lib dependencies
2045 provideNativeLibs []string
2046 requireNativeLibs []string
2047
2048 handleSpecialLibs bool
2049}
2050
2051func (vctx *visitorContext) normalizeFileInfo() {
2052 encountered := make(map[string]apexFile)
2053 for _, f := range vctx.filesInfo {
2054 dest := filepath.Join(f.installDir, f.builtFile.Base())
2055 if e, ok := encountered[dest]; !ok {
2056 encountered[dest] = f
2057 } else {
2058 // If a module is directly included and also transitively depended on
2059 // consider it as directly included.
2060 e.transitiveDep = e.transitiveDep && f.transitiveDep
2061 encountered[dest] = e
2062 }
2063 }
2064 vctx.filesInfo = vctx.filesInfo[:0]
2065 for _, v := range encountered {
2066 vctx.filesInfo = append(vctx.filesInfo, v)
2067 }
2068 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2069 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2070 // changes.
2071 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2072 })
2073}
2074
2075func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2076 depTag := ctx.OtherModuleDependencyTag(child)
2077 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2078 return false
2079 }
2080 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2081 return false
2082 }
2083 depName := ctx.OtherModuleName(child)
2084 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2085 switch depTag {
2086 case sharedLibTag, jniLibTag:
2087 isJniLib := depTag == jniLibTag
2088 switch ch := child.(type) {
2089 case *cc.Module:
2090 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2091 fi.isJniLib = isJniLib
2092 vctx.filesInfo = append(vctx.filesInfo, fi)
2093 // Collect the list of stub-providing libs except:
2094 // - VNDK libs are only for vendors
2095 // - bootstrap bionic libs are treated as provided by system
2096 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2097 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2098 }
2099 return true // track transitive dependencies
2100 case *rust.Module:
2101 fi := apexFileForRustLibrary(ctx, ch)
2102 fi.isJniLib = isJniLib
2103 vctx.filesInfo = append(vctx.filesInfo, fi)
2104 return true // track transitive dependencies
2105 default:
2106 propertyName := "native_shared_libs"
2107 if isJniLib {
2108 propertyName = "jni_libs"
2109 }
2110 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2111 }
2112 case executableTag:
2113 switch ch := child.(type) {
2114 case *cc.Module:
2115 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2116 return true // track transitive dependencies
2117 case *python.Module:
2118 if ch.HostToolPath().Valid() {
2119 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2120 }
2121 case bootstrap.GoBinaryTool:
2122 if a.Host() {
2123 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2124 }
2125 case *rust.Module:
2126 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2127 return true // track transitive dependencies
2128 default:
2129 ctx.PropertyErrorf("binaries",
2130 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2131 }
2132 case shBinaryTag:
2133 if csh, ok := child.(*sh.ShBinary); ok {
2134 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2135 } else {
2136 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2137 }
2138 case bcpfTag:
2139 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2140 if !ok {
2141 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2142 return false
2143 }
2144
2145 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2146 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2147 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2148 }
2149 return true
2150 case sscpfTag:
2151 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2152 ctx.PropertyErrorf("systemserverclasspath_fragments",
2153 "%q is not a systemserverclasspath_fragment module", depName)
2154 return false
2155 }
2156 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2157 vctx.filesInfo = append(vctx.filesInfo, *af)
2158 }
2159 return true
2160 case javaLibTag:
2161 switch child.(type) {
2162 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2163 af := apexFileForJavaModule(ctx, child.(javaModule))
2164 if !af.ok() {
2165 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2166 return false
2167 }
2168 vctx.filesInfo = append(vctx.filesInfo, af)
2169 return true // track transitive dependencies
2170 default:
2171 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2172 }
2173 case androidAppTag:
2174 switch ap := child.(type) {
2175 case *java.AndroidApp:
2176 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2177 return true // track transitive dependencies
2178 case *java.AndroidAppImport:
2179 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2180 case *java.AndroidTestHelperApp:
2181 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2182 case *java.AndroidAppSet:
2183 appDir := "app"
2184 if ap.Privileged() {
2185 appDir = "priv-app"
2186 }
2187 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2188 // suffixed so that PackageManager correctly invalidates the
2189 // existing installed apk in favour of the new APK-in-APEX.
2190 // See bugs for more information.
2191 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2192 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2193 af.certificate = java.PresignedCertificate
2194 vctx.filesInfo = append(vctx.filesInfo, af)
2195 default:
2196 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2197 }
2198 case rroTag:
2199 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2200 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2201 } else {
2202 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2203 }
2204 case bpfTag:
2205 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2206 filesToCopy, _ := bpfProgram.OutputFiles("")
2207 apex_sub_dir := bpfProgram.SubDir()
2208 for _, bpfFile := range filesToCopy {
2209 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2210 }
2211 } else {
2212 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2213 }
2214 case fsTag:
2215 if fs, ok := child.(filesystem.Filesystem); ok {
2216 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2217 } else {
2218 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2219 }
2220 case prebuiltTag:
2221 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2222 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2223 } else {
2224 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2225 }
2226 case compatConfigTag:
2227 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2228 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2229 } else {
2230 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2231 }
2232 case testTag:
2233 if ccTest, ok := child.(*cc.Module); ok {
2234 if ccTest.IsTestPerSrcAllTestsVariation() {
2235 // Multiple-output test module (where `test_per_src: true`).
2236 //
2237 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2238 // We do not add this variation to `filesInfo`, as it has no output;
2239 // however, we do add the other variations of this module as indirect
2240 // dependencies (see below).
2241 } else {
2242 // Single-output test module (where `test_per_src: false`).
2243 af := apexFileForExecutable(ctx, ccTest)
2244 af.class = nativeTest
2245 vctx.filesInfo = append(vctx.filesInfo, af)
2246 }
2247 return true // track transitive dependencies
2248 } else {
2249 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2250 }
2251 case keyTag:
2252 if key, ok := child.(*apexKey); ok {
2253 a.privateKeyFile = key.privateKeyFile
2254 a.publicKeyFile = key.publicKeyFile
2255 } else {
2256 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2257 }
2258 case certificateTag:
2259 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2260 a.containerCertificateFile = dep.Certificate.Pem
2261 a.containerPrivateKeyFile = dep.Certificate.Key
2262 } else {
2263 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2264 }
2265 case android.PrebuiltDepTag:
2266 // If the prebuilt is force disabled, remember to delete the prebuilt file
2267 // that might have been installed in the previous builds
2268 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2269 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2270 }
2271 }
2272 return false
2273 }
2274
2275 if a.vndkApex {
2276 return false
2277 }
2278
2279 // indirect dependencies
2280 am, ok := child.(android.ApexModule)
2281 if !ok {
2282 return false
2283 }
2284 // We cannot use a switch statement on `depTag` here as the checked
2285 // tags used below are private (e.g. `cc.sharedDepTag`).
2286 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2287 if ch, ok := child.(*cc.Module); ok {
2288 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2289 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2290 return false
2291 }
2292 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2293 af.transitiveDep = true
2294
2295 // Always track transitive dependencies for host.
2296 if a.Host() {
2297 vctx.filesInfo = append(vctx.filesInfo, af)
2298 return true
2299 }
2300
2301 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2302 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2303 // If the dependency is a stubs lib, don't include it in this APEX,
2304 // but make sure that the lib is installed on the device.
2305 // In case no APEX is having the lib, the lib is installed to the system
2306 // partition.
2307 //
2308 // Always include if we are a host-apex however since those won't have any
2309 // system libraries.
2310 if !am.DirectlyInAnyApex() {
2311 // we need a module name for Make
2312 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2313 if !android.InList(name, a.requiredDeps) {
2314 a.requiredDeps = append(a.requiredDeps, name)
2315 }
2316 }
2317 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2318 // Don't track further
2319 return false
2320 }
2321
2322 // If the dep is not considered to be in the same
2323 // apex, don't add it to filesInfo so that it is not
2324 // included in this APEX.
2325 // TODO(jiyong): move this to at the top of the
2326 // else-if clause for the indirect dependencies.
2327 // Currently, that's impossible because we would
2328 // like to record requiredNativeLibs even when
2329 // DepIsInSameAPex is false. We also shouldn't do
2330 // this for host.
2331 //
2332 // TODO(jiyong): explain why the same module is passed in twice.
2333 // Switching the first am to parent breaks lots of tests.
2334 if !android.IsDepInSameApex(ctx, am, am) {
2335 return false
2336 }
2337
2338 vctx.filesInfo = append(vctx.filesInfo, af)
2339 return true // track transitive dependencies
2340 } else if rm, ok := child.(*rust.Module); ok {
2341 af := apexFileForRustLibrary(ctx, rm)
2342 af.transitiveDep = true
2343 vctx.filesInfo = append(vctx.filesInfo, af)
2344 return true // track transitive dependencies
2345 }
2346 } else if cc.IsTestPerSrcDepTag(depTag) {
2347 if ch, ok := child.(*cc.Module); ok {
2348 af := apexFileForExecutable(ctx, ch)
2349 // Handle modules created as `test_per_src` variations of a single test module:
2350 // use the name of the generated test binary (`fileToCopy`) instead of the name
2351 // of the original test module (`depName`, shared by all `test_per_src`
2352 // variations of that module).
2353 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2354 // these are not considered transitive dep
2355 af.transitiveDep = false
2356 vctx.filesInfo = append(vctx.filesInfo, af)
2357 return true // track transitive dependencies
2358 }
2359 } else if cc.IsHeaderDepTag(depTag) {
2360 // nothing
2361 } else if java.IsJniDepTag(depTag) {
2362 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2363 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2364 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2365 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2366 }
2367 } else if rust.IsDylibDepTag(depTag) {
2368 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2369 af := apexFileForRustLibrary(ctx, rustm)
2370 af.transitiveDep = true
2371 vctx.filesInfo = append(vctx.filesInfo, af)
2372 return true // track transitive dependencies
2373 }
2374 } else if rust.IsRlibDepTag(depTag) {
2375 // Rlib is statically linked, but it might have shared lib
2376 // dependencies. Track them.
2377 return true
2378 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2379 // Add the contents of the bootclasspath fragment to the apex.
2380 switch child.(type) {
2381 case *java.Library, *java.SdkLibrary:
2382 javaModule := child.(javaModule)
2383 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2384 if !af.ok() {
2385 ctx.PropertyErrorf("bootclasspath_fragments",
2386 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2387 return false
2388 }
2389 vctx.filesInfo = append(vctx.filesInfo, af)
2390 return true // track transitive dependencies
2391 default:
2392 ctx.PropertyErrorf("bootclasspath_fragments",
2393 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2394 }
2395 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2396 // Add the contents of the systemserverclasspath fragment to the apex.
2397 switch child.(type) {
2398 case *java.Library, *java.SdkLibrary:
2399 af := apexFileForJavaModule(ctx, child.(javaModule))
2400 vctx.filesInfo = append(vctx.filesInfo, af)
2401 return true // track transitive dependencies
2402 default:
2403 ctx.PropertyErrorf("systemserverclasspath_fragments",
2404 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2405 }
2406 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2407 // nothing
2408 } else if depTag == android.DarwinUniversalVariantTag {
2409 // nothing
2410 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2411 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2412 }
2413 return false
2414}
2415
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002416// Creates build rules for an APEX. It consists of the following major steps:
2417//
2418// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2419// 2) traverse the dependency tree to collect apexFile structs from them.
2420// 3) some fields in apexBundle struct are configured
2421// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002422func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002423 ////////////////////////////////////////////////////////////////////////////////////////////
2424 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002425 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002426 return
2427 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002428 ////////////////////////////////////////////////////////////////////////////////////////////
2429 // 2) traverse the dependency tree to collect apexFile structs from them.
2430
braleeb0c1f0c2021-06-07 22:49:13 +08002431 // Collect the module directory for IDE info in java/jdeps.go.
2432 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2433
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002434 // TODO(jiyong): do this using WalkPayloadDeps
2435 // TODO(jiyong): make this clean!!!
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002436 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2437 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
2438 vctx.normalizeFileInfo()
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002439 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002440 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002441 return
2442 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002443
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002444 ////////////////////////////////////////////////////////////////////////////////////////////
2445 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002446 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002447 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002448
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002449 a.setApexTypeAndSuffix(ctx)
2450 a.setPayloadFsType(ctx)
2451 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002452 if a.properties.ApexType != zipApex {
2453 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2454 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002455
2456 ////////////////////////////////////////////////////////////////////////////////////////////
2457 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002458 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002459 if a.properties.ApexType == flattenedApex {
2460 a.buildFlattenedApex(ctx)
2461 } else {
2462 a.buildUnflattenedApex(ctx)
2463 }
Jiyong Park956305c2020-01-09 12:32:06 +09002464 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002465 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002466
2467 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2468 if a.installable() {
2469 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2470 // along with other ordinary files. (Note that this is done by apexer for
2471 // non-flattened APEXes)
2472 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2473
2474 // Place the public key as apex_pubkey. This is also done by apexer for
2475 // non-flattened APEXes case.
2476 // TODO(jiyong): Why do we need this CP rule?
2477 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2478 ctx.Build(pctx, android.BuildParams{
2479 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002480 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002481 Output: copiedPubkey,
2482 })
2483 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2484 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002485}
2486
Paul Duffincc33ec82021-04-25 23:14:55 +01002487// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2488// the bootclasspath_fragment contributes to the apex.
2489func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2490 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2491 var filesToAdd []apexFile
2492
2493 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002494 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2495 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2496 dirInApex := filepath.Join("javalib", arch.String())
2497 for _, f := range files {
2498 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2499 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2500 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2501 filesToAdd = append(filesToAdd, af)
2502 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002503 }
2504 }
2505
satayev3db35472021-05-06 23:59:58 +01002506 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002507 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2508 filesToAdd = append(filesToAdd, *af)
2509 }
satayev3db35472021-05-06 23:59:58 +01002510
Ulya Trafimovichf5c548d2022-11-16 14:52:41 +00002511 pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2512 if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002513 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2514 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2515
2516 if pathOnHost != nil {
2517 // We need to copy the profile to a temporary path with the right filename because the apexer
2518 // will take the filename as is.
2519 ctx.Build(pctx, android.BuildParams{
2520 Rule: android.Cp,
2521 Input: pathOnHost,
2522 Output: tempPath,
2523 })
2524 } else {
2525 // At this point, the boot image profile cannot be generated. It is probably because the boot
2526 // image profile source file does not exist on the branch, or it is not available for the
2527 // current build target.
2528 // However, we cannot enforce the boot image profile to be generated because some build
2529 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2530 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2531 // only if the APEX is being built.
2532 ctx.Build(pctx, android.BuildParams{
2533 Rule: android.ErrorRule,
2534 Output: tempPath,
2535 Args: map[string]string{
2536 "error": "Boot image profile cannot be generated",
2537 },
2538 })
2539 }
2540
2541 androidMkModuleName := filepath.Base(pathInApex)
2542 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2543 filesToAdd = append(filesToAdd, af)
2544 }
2545
Paul Duffincc33ec82021-04-25 23:14:55 +01002546 return filesToAdd
2547}
2548
satayevb98371c2021-06-15 16:49:50 +01002549// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2550// the module contributes to the apex; or nil if the proto config was not generated.
2551func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2552 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2553 if !info.ClasspathFragmentProtoGenerated {
2554 return nil
2555 }
2556 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2557 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2558 return &af
satayev14e49132021-05-17 21:03:07 +01002559}
2560
Paul Duffincc33ec82021-04-25 23:14:55 +01002561// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2562// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002563func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2564 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2565
2566 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2567 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002568 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2569 if err != nil {
2570 ctx.ModuleErrorf("%s", err)
2571 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002572
2573 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2574 // bootclasspath_fragment.
2575 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2576 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002577}
2578
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002579///////////////////////////////////////////////////////////////////////////////////////////////////
2580// Factory functions
2581//
2582
2583func newApexBundle() *apexBundle {
2584 module := &apexBundle{}
2585
2586 module.AddProperties(&module.properties)
2587 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002588 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002589 module.AddProperties(&module.overridableProperties)
2590
2591 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2592 android.InitDefaultableModule(module)
2593 android.InitSdkAwareModule(module)
2594 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002595 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002596 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002597 return module
2598}
2599
Paul Duffineb8051d2021-10-18 17:49:39 +01002600func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002601 bundle := newApexBundle()
2602 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002603 return bundle
2604}
2605
2606// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2607// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002608func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002609 bundle := newApexBundle()
2610 bundle.testApex = true
2611 return bundle
2612}
2613
2614// apex packages other modules into an APEX file which is a packaging format for system-level
2615// components like binaries, shared libraries, etc.
2616func BundleFactory() android.Module {
2617 return newApexBundle()
2618}
2619
2620type Defaults struct {
2621 android.ModuleBase
2622 android.DefaultsModuleBase
2623}
2624
2625// apex_defaults provides defaultable properties to other apex modules.
2626func defaultsFactory() android.Module {
2627 return DefaultsFactory()
2628}
2629
2630func DefaultsFactory(props ...interface{}) android.Module {
2631 module := &Defaults{}
2632
2633 module.AddProperties(props...)
2634 module.AddProperties(
2635 &apexBundleProperties{},
2636 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002637 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002638 &overridableProperties{},
2639 )
2640
2641 android.InitDefaultsModule(module)
2642 return module
2643}
2644
2645type OverrideApex struct {
2646 android.ModuleBase
2647 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002648 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002649}
2650
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002651func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002652 // All the overrides happen in the base module.
2653}
2654
2655// override_apex is used to create an apex module based on another apex module by overriding some of
2656// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002657func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002658 m := &OverrideApex{}
2659
2660 m.AddProperties(&overridableProperties{})
2661
2662 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2663 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002664 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002665 return m
2666}
2667
Wei Li1c66fc72022-05-09 23:59:14 -07002668func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2669 if ctx.ModuleType() != "override_apex" {
2670 return
2671 }
2672
2673 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2674 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2675 if !baseApexExists {
2676 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2677 }
2678
2679 a, baseModuleIsApex := baseModule.(*apexBundle)
2680 if !baseModuleIsApex {
2681 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2682 }
2683 attrs, props := convertWithBp2build(a, ctx)
2684
2685 for _, p := range o.GetProperties() {
2686 overridableProperties, ok := p.(*overridableProperties)
2687 if !ok {
2688 continue
2689 }
Wei Li40f98732022-05-20 22:08:11 -07002690
2691 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2692 // After it is converted in convertWithBp2build(baseApex, ctx),
2693 // the attrs.Manifest.Value.Label is the file path relative to the directory
2694 // of base apex. So the following code converts it to a label that looks like
2695 // <package of base apex>:<path of manifest file> if base apex and override
2696 // apex are not in the same package.
2697 baseApexPackage := ctx.OtherModuleDir(a)
2698 overrideApexPackage := ctx.ModuleDir()
2699 if baseApexPackage != overrideApexPackage {
2700 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2701 }
2702
Wei Li1c66fc72022-05-09 23:59:14 -07002703 // Key
2704 if overridableProperties.Key != nil {
2705 attrs.Key = bazel.LabelAttribute{}
2706 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2707 }
2708
2709 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002710 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002711 // If overridableProperties.Certificate is nil, clear this out as
2712 // well with zeroed structs, so the override_apex does not use the
2713 // base apex's certificate.
2714 attrs.Certificate = bazel.LabelAttribute{}
2715 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002716 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002717 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002718 }
2719
2720 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002721 if overridableProperties.Prebuilts != nil {
2722 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2723 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2724 }
Wei Li1c66fc72022-05-09 23:59:14 -07002725
2726 // Compressible
2727 if overridableProperties.Compressible != nil {
2728 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2729 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002730
2731 // Package name
2732 //
2733 // e.g. com.android.adbd's package name is com.android.adbd, but
2734 // com.google.android.adbd overrides the package name to com.google.android.adbd
2735 //
2736 // TODO: this can be overridden from the product configuration, see
2737 // getOverrideManifestPackageName and
2738 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2739 //
2740 // Instead of generating the BUILD files differently based on the product config
2741 // at the point of conversion, this should be handled by the BUILD file loading
2742 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2743 if overridableProperties.Package_name != "" {
2744 attrs.Package_name = &overridableProperties.Package_name
2745 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002746
2747 // Logging parent
2748 if overridableProperties.Logging_parent != "" {
2749 attrs.Logging_parent = &overridableProperties.Logging_parent
2750 }
Wei Li1c66fc72022-05-09 23:59:14 -07002751 }
2752
2753 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2754}
2755
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002756///////////////////////////////////////////////////////////////////////////////////////////////////
2757// Vality check routines
2758//
2759// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2760// certain conditions are not met.
2761//
2762// TODO(jiyong): move these checks to a separate go file.
2763
satayevad991492021-12-03 18:58:32 +00002764var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2765
Spandan Dasa5f39a12022-08-05 02:35:52 +00002766// 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 +09002767// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002768func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002769 if a.testApex || a.vndkApex {
2770 return
2771 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002772 // apexBundle::minSdkVersion reports its own errors.
2773 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002774 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002775}
2776
Albert Martineefabcf2022-03-21 20:11:16 +00002777// Returns apex's min_sdk_version string value, honoring overrides
2778func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2779 // Only override the minSdkVersion value on Apexes which already specify
2780 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2781 // min_sdk_version value is lower than the one to override with.
Colin Cross56534df2022-10-04 09:58:58 -07002782 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2783 if minApiLevel.IsNone() {
2784 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002785 }
2786
Colin Cross56534df2022-10-04 09:58:58 -07002787 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2788 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2789 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2790 minApiLevel = overrideApiLevel
2791 }
2792
2793 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002794}
2795
2796// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002797func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2798 return android.SdkSpec{
2799 Kind: android.SdkNone,
2800 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002801 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002802 }
2803}
2804
Albert Martineefabcf2022-03-21 20:11:16 +00002805// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002806func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002807 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2808}
2809
2810// Construct ApiLevel object from min_sdk_version string value
2811func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2812 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002813 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002814 }
Albert Martineefabcf2022-03-21 20:11:16 +00002815 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002816 if err != nil {
2817 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2818 return android.NoneApiLevel
2819 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002820 return apiLevel
2821}
2822
2823// Ensures that a lib providing stub isn't statically linked
2824func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2825 // Practically, we only care about regular APEXes on the device.
2826 if ctx.Host() || a.testApex || a.vndkApex {
2827 return
2828 }
2829
2830 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2831
2832 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2833 if ccm, ok := to.(*cc.Module); ok {
2834 apexName := ctx.ModuleName()
2835 fromName := ctx.OtherModuleName(from)
2836 toName := ctx.OtherModuleName(to)
2837
2838 // If `to` is not actually in the same APEX as `from` then it does not need
2839 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002840 //
2841 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002842 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2843 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2844 return false
2845 }
2846
2847 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2848 // exception to this rule. It can't make the static dependencies dynamic
2849 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002850 // Same rule should be applied to linkerconfig, because it should be executed
2851 // only with static linked libraries before linker is available with ld.config.txt
2852 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002853 return false
2854 }
2855
2856 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2857 if isStubLibraryFromOtherApex && !externalDep {
2858 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2859 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2860 }
2861
2862 }
2863 return true
2864 })
2865}
2866
satayevb98371c2021-06-15 16:49:50 +01002867// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002868func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2869 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002870 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002871 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2872 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002873 if a.UsePlatformApis() {
2874 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2875 }
Daniel Norman69109112021-12-02 12:52:42 -08002876 if a.SocSpecific() || a.DeviceSpecific() {
2877 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2878 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002879 if a.FutureUpdatable() {
2880 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2881 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002882 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002883 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002884 }
2885}
2886
satayevb98371c2021-06-15 16:49:50 +01002887// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2888func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2889 ctx.VisitDirectDeps(func(module android.Module) {
2890 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2891 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2892 if !info.ClasspathFragmentProtoGenerated {
2893 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2894 }
2895 }
2896 })
2897}
2898
2899// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002900func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002901 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2902 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002903 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2904 tag := ctx.OtherModuleDependencyTag(module)
2905 switch tag {
2906 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002907 if m, ok := module.(interface {
2908 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2909 }); ok {
2910 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002911 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2912 }
2913 }
2914 }
2915 })
2916}
2917
satayevb98371c2021-06-15 16:49:50 +01002918// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002919func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2920 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2921 if ctx.Host() || a.testApex || a.vndkApex {
2922 return
2923 }
2924
2925 // Because APEXes targeting other than system/system_ext partitions can't set
2926 // apex_available, we skip checks for these APEXes
2927 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2928 return
2929 }
2930
2931 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2932 // Requiring them and their transitive depencies with apex_available is not right
2933 // because they just add noise.
2934 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2935 return
2936 }
2937
2938 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2939 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2940 if externalDep {
2941 return false
2942 }
2943
2944 apexName := ctx.ModuleName()
2945 fromName := ctx.OtherModuleName(from)
2946 toName := ctx.OtherModuleName(to)
2947
2948 // If `to` is not actually in the same APEX as `from` then it does not need
2949 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002950 //
2951 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002952 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2953 // As soon as the dependency graph crosses the APEX boundary, don't go
2954 // further.
2955 return false
2956 }
2957
2958 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
2959 return true
2960 }
Jiyong Park767dbd92021-03-04 13:03:10 +09002961 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2962 "\n\nDependency path:%s\n\n"+
2963 "Consider adding %q to 'apex_available' property of %q",
2964 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002965 // Visit this module's dependencies to check and report any issues with their availability.
2966 return true
2967 })
2968}
2969
Jiyong Park192600a2021-08-03 07:52:17 +00002970// checkStaticExecutable ensures that executables in an APEX are not static.
2971func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09002972 // No need to run this for host APEXes
2973 if ctx.Host() {
2974 return
2975 }
2976
Jiyong Park192600a2021-08-03 07:52:17 +00002977 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2978 if ctx.OtherModuleDependencyTag(module) != executableTag {
2979 return
2980 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09002981
2982 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00002983 apex := a.ApexVariationName()
2984 exec := ctx.OtherModuleName(module)
2985 if isStaticExecutableAllowed(apex, exec) {
2986 return
2987 }
2988 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
2989 }
2990 })
2991}
2992
2993// A small list of exceptions where static executables are allowed in APEXes.
2994func isStaticExecutableAllowed(apex string, exec string) bool {
2995 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07002996 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00002997 "linker",
2998 "linkerconfig",
2999 },
3000 }
3001 execNames, ok := m[apex]
3002 return ok && android.InList(exec, execNames)
3003}
3004
braleeb0c1f0c2021-06-07 22:49:13 +08003005// Collect information for opening IDE project files in java/jdeps.go.
3006func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09003007 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
3008 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
3009 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08003010 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
3011}
3012
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003013var (
3014 apexAvailBaseline = makeApexAvailableBaseline()
3015 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
3016)
3017
Colin Cross440e0d02020-06-11 11:32:11 -07003018func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003019 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003020 moduleName = normalizeModuleName(moduleName)
3021
Colin Cross440e0d02020-06-11 11:32:11 -07003022 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003023 return true
3024 }
3025
3026 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07003027 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003028 return true
3029 }
3030
3031 return false
3032}
3033
3034func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09003035 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
3036 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00003037 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09003038 if strings.HasPrefix(moduleName, "libclang_rt.") {
3039 // This module has many arch variants that depend on the product being built.
3040 // We don't want to list them all
3041 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003042 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003043 if strings.HasPrefix(moduleName, "androidx.") {
3044 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3045 moduleName = "androidx"
3046 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003047 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003048}
3049
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003050// Transform the map of apex -> modules to module -> apexes.
3051func invertApexBaseline(m map[string][]string) map[string][]string {
3052 r := make(map[string][]string)
3053 for apex, modules := range m {
3054 for _, module := range modules {
3055 r[module] = append(r[module], apex)
3056 }
3057 }
3058 return r
3059}
3060
3061// Retrieve the baseline of apexes to which the supplied module belongs.
3062func BaselineApexAvailable(moduleName string) []string {
3063 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3064}
3065
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003066// This is a map from apex to modules, which overrides the apex_available setting for that
3067// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003068// TODO(b/147364041): remove this
3069func makeApexAvailableBaseline() map[string][]string {
3070 // The "Module separator"s below are employed to minimize merge conflicts.
3071 m := make(map[string][]string)
3072 //
3073 // Module separator
3074 //
3075 m["com.android.appsearch"] = []string{
3076 "icing-java-proto-lite",
3077 "libprotobuf-java-lite",
3078 }
3079 //
3080 // Module separator
3081 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003082 m["com.android.btservices"] = []string{
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003083 "bluetooth-protos-lite",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003084 "internal_include_headers",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003085 "libaudio-a2dp-hw-utils",
3086 "libaudio-hearing-aid-hw-utils",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003087 "libbluetooth",
3088 "libbluetooth-types",
3089 "libbluetooth-types-header",
3090 "libbluetooth_gd",
3091 "libbluetooth_headers",
3092 "libbluetooth_jni",
3093 "libbt-audio-hal-interface",
3094 "libbt-bta",
3095 "libbt-common",
3096 "libbt-hci",
3097 "libbt-platform-protos-lite",
3098 "libbt-protos-lite",
3099 "libbt-sbc-decoder",
3100 "libbt-sbc-encoder",
3101 "libbt-stack",
3102 "libbt-utils",
3103 "libbtcore",
3104 "libbtdevice",
3105 "libbte",
3106 "libbtif",
3107 "libchrome",
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003108 }
3109 //
3110 // Module separator
3111 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003112 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3113 //
3114 // Module separator
3115 //
3116 m["com.android.extservices"] = []string{
3117 "error_prone_annotations",
3118 "ExtServices-core",
3119 "ExtServices",
3120 "libtextclassifier-java",
3121 "libz_current",
3122 "textclassifier-statsd",
3123 "TextClassifierNotificationLibNoManifest",
3124 "TextClassifierServiceLibNoManifest",
3125 }
3126 //
3127 // Module separator
3128 //
3129 m["com.android.neuralnetworks"] = []string{
3130 "android.hardware.neuralnetworks@1.0",
3131 "android.hardware.neuralnetworks@1.1",
3132 "android.hardware.neuralnetworks@1.2",
3133 "android.hardware.neuralnetworks@1.3",
3134 "android.hidl.allocator@1.0",
3135 "android.hidl.memory.token@1.0",
3136 "android.hidl.memory@1.0",
3137 "android.hidl.safe_union@1.0",
3138 "libarect",
3139 "libbuildversion",
3140 "libmath",
3141 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003142 }
3143 //
3144 // Module separator
3145 //
3146 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003147 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003148 }
3149 //
3150 // Module separator
3151 //
3152 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003153 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003154 }
3155 //
3156 // Module separator
3157 //
3158 m["com.android.mediaprovider"] = []string{
3159 "MediaProvider",
3160 "MediaProviderGoogle",
3161 "fmtlib_ndk",
3162 "libbase_ndk",
3163 "libfuse",
3164 "libfuse_jni",
3165 }
3166 //
3167 // Module separator
3168 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003169 m["com.android.runtime"] = []string{
3170 "bionic_libc_platform_headers",
3171 "libarm-optimized-routines-math",
3172 "libc_aeabi",
3173 "libc_bionic",
3174 "libc_bionic_ndk",
3175 "libc_bootstrap",
3176 "libc_common",
3177 "libc_common_shared",
3178 "libc_common_static",
3179 "libc_dns",
3180 "libc_dynamic_dispatch",
3181 "libc_fortify",
3182 "libc_freebsd",
3183 "libc_freebsd_large_stack",
3184 "libc_gdtoa",
3185 "libc_init_dynamic",
3186 "libc_init_static",
3187 "libc_jemalloc_wrapper",
3188 "libc_netbsd",
3189 "libc_nomalloc",
3190 "libc_nopthread",
3191 "libc_openbsd",
3192 "libc_openbsd_large_stack",
3193 "libc_openbsd_ndk",
3194 "libc_pthread",
3195 "libc_static_dispatch",
3196 "libc_syscalls",
3197 "libc_tzcode",
3198 "libc_unwind_static",
3199 "libdebuggerd",
3200 "libdebuggerd_common_headers",
3201 "libdebuggerd_handler_core",
3202 "libdebuggerd_handler_fallback",
3203 "libdl_static",
3204 "libjemalloc5",
3205 "liblinker_main",
3206 "liblinker_malloc",
3207 "liblz4",
3208 "liblzma",
3209 "libprocinfo",
3210 "libpropertyinfoparser",
3211 "libscudo",
3212 "libstdc++",
3213 "libsystemproperties",
3214 "libtombstoned_client_static",
3215 "libunwindstack",
3216 "libz",
3217 "libziparchive",
3218 }
3219 //
3220 // Module separator
3221 //
3222 m["com.android.tethering"] = []string{
3223 "android.hardware.tetheroffload.config-V1.0-java",
3224 "android.hardware.tetheroffload.control-V1.0-java",
3225 "android.hidl.base-V1.0-java",
3226 "libcgrouprc",
3227 "libcgrouprc_format",
3228 "libtetherutilsjni",
3229 "libvndksupport",
3230 "net-utils-framework-common",
3231 "netd_aidl_interface-V3-java",
3232 "netlink-client",
3233 "networkstack-aidl-interfaces-java",
3234 "tethering-aidl-interfaces-java",
3235 "TetheringApiCurrentLib",
3236 }
3237 //
3238 // Module separator
3239 //
3240 m["com.android.wifi"] = []string{
3241 "PlatformProperties",
3242 "android.hardware.wifi-V1.0-java",
3243 "android.hardware.wifi-V1.0-java-constants",
3244 "android.hardware.wifi-V1.1-java",
3245 "android.hardware.wifi-V1.2-java",
3246 "android.hardware.wifi-V1.3-java",
3247 "android.hardware.wifi-V1.4-java",
3248 "android.hardware.wifi.hostapd-V1.0-java",
3249 "android.hardware.wifi.hostapd-V1.1-java",
3250 "android.hardware.wifi.hostapd-V1.2-java",
3251 "android.hardware.wifi.supplicant-V1.0-java",
3252 "android.hardware.wifi.supplicant-V1.1-java",
3253 "android.hardware.wifi.supplicant-V1.2-java",
3254 "android.hardware.wifi.supplicant-V1.3-java",
3255 "android.hidl.base-V1.0-java",
3256 "android.hidl.manager-V1.0-java",
3257 "android.hidl.manager-V1.1-java",
3258 "android.hidl.manager-V1.2-java",
3259 "bouncycastle-unbundled",
3260 "dnsresolver_aidl_interface-V2-java",
3261 "error_prone_annotations",
3262 "framework-wifi-pre-jarjar",
3263 "framework-wifi-util-lib",
3264 "ipmemorystore-aidl-interfaces-V3-java",
3265 "ipmemorystore-aidl-interfaces-java",
3266 "ksoap2",
3267 "libnanohttpd",
3268 "libwifi-jni",
3269 "net-utils-services-common",
3270 "netd_aidl_interface-V2-java",
3271 "netd_aidl_interface-unstable-java",
3272 "netd_event_listener_interface-java",
3273 "netlink-client",
3274 "networkstack-client",
3275 "services.net",
3276 "wifi-lite-protos",
3277 "wifi-nano-protos",
3278 "wifi-service-pre-jarjar",
3279 "wifi-service-resources",
3280 }
3281 //
3282 // Module separator
3283 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003284 m["com.android.os.statsd"] = []string{
3285 "libstatssocket",
3286 }
3287 //
3288 // Module separator
3289 //
3290 m[android.AvailableToAnyApex] = []string{
3291 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3292 "androidx",
3293 "androidx-constraintlayout_constraintlayout",
3294 "androidx-constraintlayout_constraintlayout-nodeps",
3295 "androidx-constraintlayout_constraintlayout-solver",
3296 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3297 "com.google.android.material_material",
3298 "com.google.android.material_material-nodeps",
3299
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003300 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003301 "libprofile-clang-extras",
3302 "libprofile-clang-extras_ndk",
3303 "libprofile-extras",
3304 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003305 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003306 }
3307 return m
3308}
3309
3310func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003311 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3312 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003313}
3314
Spandan Dasf14e2542021-11-12 00:01:37 +00003315func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3316 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3317 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003318 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003319 With("name", jar).
3320 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3321 Because(jar +
3322 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003323 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003324 " 1. If the offending code is from a statically linked library, consider " +
3325 "removing that dependency and using an alternative already in the " +
3326 "bootclasspath, or perhaps a shared library." +
3327 " 2. Move the offending code into an allowed package.\n" +
3328 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3329 "health implications of bundling that code, particularly if the offending jar " +
3330 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003331
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003332 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003333 }
3334 return rules
3335}
3336
Anton Hanssone1b18362021-12-23 15:05:38 +00003337// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003338// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003339func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003340 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003341 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003342 "android.net.ssl",
3343 "com.android.org.conscrypt",
3344 },
Wei Li40f98732022-05-20 22:08:11 -07003345 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003346 "android.media",
3347 },
3348 }
3349}
3350
Anton Hanssone1b18362021-12-23 15:05:38 +00003351// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003352// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003353func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003354 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003355 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003356 "android.provider",
3357 },
Wei Li40f98732022-05-20 22:08:11 -07003358 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003359 "android.permission",
3360 "android.app.role",
3361 "com.android.permission",
3362 "com.android.role",
3363 },
Wei Li40f98732022-05-20 22:08:11 -07003364 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003365 "android.os.ext",
3366 },
Wei Li40f98732022-05-20 22:08:11 -07003367 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003368 "android.app",
3369 "android.os",
3370 "android.util",
3371 "com.android.internal.statsd",
3372 "com.android.server.stats",
3373 },
Wei Li40f98732022-05-20 22:08:11 -07003374 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003375 "com.android.server.wifi",
3376 "com.android.wifi.x",
3377 "android.hardware.wifi",
3378 "android.net.wifi",
3379 },
Wei Li40f98732022-05-20 22:08:11 -07003380 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003381 "android.net",
3382 },
3383 }
3384}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003385
3386// For Bazel / bp2build
3387
3388type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003389 Manifest bazel.LabelAttribute
3390 Android_manifest bazel.LabelAttribute
3391 File_contexts bazel.LabelAttribute
3392 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003393 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3394 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Yu Liu4ae55d12022-01-05 17:17:23 -08003395 Min_sdk_version *string
3396 Updatable bazel.BoolAttribute
3397 Installable bazel.BoolAttribute
3398 Binaries bazel.LabelListAttribute
3399 Prebuilts bazel.LabelListAttribute
3400 Native_shared_libs_32 bazel.LabelListAttribute
3401 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003402 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003403 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003404 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003405 Tests bazel.LabelListAttribute
Yu Liu4ae55d12022-01-05 17:17:23 -08003406}
3407
3408type convertedNativeSharedLibs struct {
3409 Native_shared_libs_32 bazel.LabelListAttribute
3410 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003411}
3412
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003413// ConvertWithBp2build performs bp2build conversion of an apex
3414func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003415 // We only convert apex and apex_test modules at this time
3416 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003417 return
3418 }
3419
Wei Li1c66fc72022-05-09 23:59:14 -07003420 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003421 commonAttrs := android.CommonAttributes{
3422 Name: a.Name(),
3423 }
3424 if a.testApex {
3425 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3426 }
3427 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003428}
3429
3430func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003431 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003432 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003433
3434 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003435 if a.properties.AndroidManifest != nil {
3436 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003437 }
3438
3439 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003440 if a.properties.File_contexts == nil {
3441 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3442 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3443 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3444 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003445 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003446 } else {
3447 // File_contexts is a file
3448 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003449 }
3450
Albert Martineefabcf2022-03-21 20:11:16 +00003451 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3452 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003453 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003454 if a.properties.Min_sdk_version != nil {
3455 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003456 }
3457
3458 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003459 if a.overridableProperties.Key != nil {
3460 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003461 }
3462
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003463 // Certificate
3464 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003465
Yu Liu4ae55d12022-01-05 17:17:23 -08003466 nativeSharedLibs := &convertedNativeSharedLibs{
3467 Native_shared_libs_32: bazel.LabelListAttribute{},
3468 Native_shared_libs_64: bazel.LabelListAttribute{},
3469 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003470
3471 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3472 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3473 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3474 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3475 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003476 if a.CompileMultilib() != nil {
3477 compileMultilib = *a.CompileMultilib()
3478 }
3479
3480 // properties.Native_shared_libs is treated as "both"
3481 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3482 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3483 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3484 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3485 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003486
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003487 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003488 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3489 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3490
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003491 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003492 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003493
Yu Liu4c212ce2022-10-14 12:20:20 -07003494 var testsAttrs bazel.LabelListAttribute
3495 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3496 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3497 testsAttrs = bazel.MakeLabelListAttribute(tests)
3498 }
3499
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003500 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003501 if a.properties.Updatable != nil {
3502 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003503 }
3504
3505 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003506 if a.properties.Installable != nil {
3507 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003508 }
3509
Wei Lif034cb42022-01-19 15:54:31 -08003510 var compressibleAttribute bazel.BoolAttribute
3511 if a.overridableProperties.Compressible != nil {
3512 compressibleAttribute.Value = a.overridableProperties.Compressible
3513 }
3514
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003515 var packageName *string
3516 if a.overridableProperties.Package_name != "" {
3517 packageName = &a.overridableProperties.Package_name
3518 }
3519
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003520 var loggingParent *string
3521 if a.overridableProperties.Logging_parent != "" {
3522 loggingParent = &a.overridableProperties.Logging_parent
3523 }
3524
Wei Li1c66fc72022-05-09 23:59:14 -07003525 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003526 Manifest: manifestLabelAttribute,
3527 Android_manifest: androidManifestLabelAttribute,
3528 File_contexts: fileContextsLabelAttribute,
3529 Min_sdk_version: minSdkVersion,
3530 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003531 Certificate: certificate,
3532 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003533 Updatable: updatableAttribute,
3534 Installable: installableAttribute,
3535 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3536 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3537 Binaries: binariesLabelListAttribute,
3538 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003539 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003540 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003541 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003542 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003543 }
3544
3545 props := bazel.BazelTargetModuleProperties{
3546 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003547 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003548 }
3549
Wei Li1c66fc72022-05-09 23:59:14 -07003550 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003551}
Yu Liu4ae55d12022-01-05 17:17:23 -08003552
3553// The following conversions are based on this table where the rows are the compile_multilib
3554// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3555// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3556// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3557// should not be compiled.
3558// multib/compile_multilib, 32, 64, both, first
3559// 32, 32/32, none/none, 32/32, none/32
3560// 64, none/none, 64/none, 64/none, 64/none
3561// both, 32/32, 64/none, 32&64/32, 64/32
3562// first, 32/32, 64/none, 64/32, 64/32
3563
3564func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3565 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3566 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3567 switch compileMultilb {
3568 case "both", "32":
3569 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3570 case "first":
3571 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3572 case "64":
3573 // Incompatible, ignore
3574 default:
3575 invalidCompileMultilib(ctx, compileMultilb)
3576 }
3577}
3578
3579func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3580 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3581 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3582 switch compileMultilb {
3583 case "both", "64", "first":
3584 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3585 case "32":
3586 // Incompatible, ignore
3587 default:
3588 invalidCompileMultilib(ctx, compileMultilb)
3589 }
3590}
3591
3592func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3593 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3594 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3595 switch compileMultilb {
3596 case "both":
3597 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3598 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3599 case "first":
3600 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3601 case "32":
3602 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3603 case "64":
3604 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3605 default:
3606 invalidCompileMultilib(ctx, compileMultilb)
3607 }
3608}
3609
3610func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3611 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3612 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3613 switch compileMultilb {
3614 case "both", "first":
3615 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3616 case "32":
3617 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3618 case "64":
3619 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3620 default:
3621 invalidCompileMultilib(ctx, compileMultilb)
3622 }
3623}
3624
3625func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3626 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3627 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3628}
3629
3630func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3631 list := bazel.LabelListAttribute{}
3632 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3633 nativeSharedLibs.Native_shared_libs_32.Append(list)
3634}
3635
3636func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3637 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3638 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3639}
3640
3641func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3642 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3643 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3644}
3645
3646func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3647 labelListAttr *bazel.LabelListAttribute) {
3648 list := bazel.LabelListAttribute{}
3649 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3650 labelListAttr.Append(list)
3651}
3652
3653func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3654 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3655}