blob: a07576a80331123b33589de42c4e2dde245927fe [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
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900458 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900459 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900460 outputFile android.WritablePath
461
Jooyung Hana6d36672022-02-24 13:58:07 +0900462 // The built uncompressed .apex file.
463 outputApexFile android.WritablePath
464
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900465 // The built APEX file in app bundle format. This file is not directly installed to the
466 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
467 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
468 // system) to be merged into a single app bundle file that Play accepts. See
469 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
470 bundleModuleFile android.WritablePath
471
Colin Cross6340ea52021-11-04 12:01:18 -0700472 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900473 installDir android.InstallPath
474
Colin Cross6340ea52021-11-04 12:01:18 -0700475 // Path where this APEX was installed.
476 installedFile android.InstallPath
477
478 // Installed locations of symlinks for backward compatibility.
479 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900480
481 // Text file having the list of individual files that are included in this APEX. Used for
482 // debugging purpose.
483 installedFilesFile android.WritablePath
484
485 // List of module names that this APEX is including (to be shown via *-deps-info target).
486 // Used for debugging purpose.
487 android.ApexBundleDepsInfo
488
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900489 // Optional list of lint report zip files for apexes that contain java or app modules
490 lintReports android.Paths
491
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900492 prebuiltFileToDelete string
sophiezc80a2b32020-11-12 16:39:19 +0000493
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000494 isCompressed bool
495
sophiezc80a2b32020-11-12 16:39:19 +0000496 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700497 nativeApisUsedByModuleFile android.ModuleOutPath
498 nativeApisBackedByModuleFile android.ModuleOutPath
499 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800500
501 // Collect the module directory for IDE info in java/jdeps.go.
502 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900503}
504
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900505// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900506type apexFileClass int
507
Jooyung Han72bd2f82019-10-23 16:46:38 +0900508const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900509 app apexFileClass = iota
510 appSet
511 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900512 goBinary
513 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900514 nativeExecutable
515 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900516 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900517 pyBinary
518 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900519)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900520
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900521// apexFile represents a file in an APEX bundle. This is created during the first half of
522// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
523// of the function, this is used to create commands that copies the files into a staging directory,
524// where they are packaged into the APEX file. This struct is also used for creating Make modules
525// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900526type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900527 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000528 builtFile android.Path
529 installDir string
530 customStem string
531 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900532
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900533 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
534 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
535 // suffix>]
536 androidMkModuleName string // becomes LOCAL_MODULE
537 class apexFileClass // becomes LOCAL_MODULE_CLASS
538 moduleDir string // becomes LOCAL_PATH
539 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
540 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
541 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
542 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900543
544 jacocoReportClassesFile android.Path // only for javalibs and apps
545 lintDepSets java.LintDepSets // only for javalibs and apps
546 certificate java.Certificate // only for apps
547 overriddenPackageName string // only for apps
548
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900549 transitiveDep bool
550 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900551
Jiyong Park57621b22021-01-20 20:33:11 +0900552 multilib string
553
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900554 // TODO(jiyong): remove this
555 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900556}
557
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900558// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900559func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
560 ret := apexFile{
561 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900562 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900563 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900564 class: class,
565 module: module,
566 }
567 if module != nil {
568 ret.moduleDir = ctx.OtherModuleDir(module)
569 ret.requiredModuleNames = module.RequiredModuleNames()
570 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
571 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900572 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900573 }
574 return ret
575}
576
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900577func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900578 return af.builtFile != nil && af.builtFile.String() != ""
579}
580
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900581// apexRelativePath returns the relative path of the given path from the install directory of this
582// apexFile.
583// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900584func (af *apexFile) apexRelativePath(path string) string {
585 return filepath.Join(af.installDir, path)
586}
587
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900588// path returns path of this apex file relative to the APEX root
589func (af *apexFile) path() string {
590 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900591}
592
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900593// stem returns the base filename of this apex file
594func (af *apexFile) stem() string {
595 if af.customStem != "" {
596 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900597 }
598 return af.builtFile.Base()
599}
600
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900601// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
602func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900603 var ret []string
604 for _, symlink := range af.symlinks {
605 ret = append(ret, af.apexRelativePath(symlink))
606 }
607 return ret
608}
609
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900610// availableToPlatform tests whether this apexFile is from a module that can be installed to the
611// platform.
612func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900613 if af.module == nil {
614 return false
615 }
616 if am, ok := af.module.(android.ApexModule); ok {
617 return am.AvailableFor(android.AvailableToPlatform)
618 }
619 return false
620}
621
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900622////////////////////////////////////////////////////////////////////////////////////////////////////
623// Mutators
624//
625// Brief description about mutators for APEX. The following three mutators are the most important
626// ones.
627//
628// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
629// to the (direct) dependencies of this APEX bundle.
630//
Paul Duffin949abc02020-12-08 10:34:30 +0000631// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900632// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
633// modules are marked as being included in the APEX via BuildForApex().
634//
Paul Duffin949abc02020-12-08 10:34:30 +0000635// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
636// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900637
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900638type dependencyTag struct {
639 blueprint.BaseDependencyTag
640 name string
641
642 // Determines if the dependent will be part of the APEX payload. Can be false for the
643 // dependencies to the signing key module, etc.
644 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000645
646 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
647 // replacement. This is needed because some prebuilt modules do not provide all the information
648 // needed by the apex.
649 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000650
651 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
652 // also be added as exported members of that SDK.
653 memberType android.SdkMemberType
654}
655
656func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
657 return d.memberType
658}
659
660func (d *dependencyTag) ExportMember() bool {
661 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900662}
663
Paul Duffin520917a2022-05-13 13:01:59 +0000664func (d *dependencyTag) String() string {
665 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
666}
667
668func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000669 return !d.sourceOnly
670}
671
672var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000673var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000674
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900675var (
Paul Duffin520917a2022-05-13 13:01:59 +0000676 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
677 bpfTag = &dependencyTag{name: "bpf", payload: true}
678 certificateTag = &dependencyTag{name: "certificate"}
679 executableTag = &dependencyTag{name: "executable", payload: true}
680 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000681 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
682 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000683 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000684 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
685 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
686 keyTag = &dependencyTag{name: "key"}
687 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
688 rroTag = &dependencyTag{name: "rro", payload: true}
689 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
690 testForTag = &dependencyTag{name: "test for"}
691 testTag = &dependencyTag{name: "test", payload: true}
692 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900693)
694
695// TODO(jiyong): shorten this function signature
696func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900697 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900698 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900699 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900700
701 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900702 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900703 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
704 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900705 }
706
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900707 // Use *FarVariation* to be able to depend on modules having conflicting variations with
708 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
709 // 'arm' or 'arm64' for native shared libs.
Colin Cross70572ed2022-11-02 13:14:20 -0700710 ctx.AddFarVariationDependencies(binVariations, executableTag,
711 android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
712 ctx.AddFarVariationDependencies(binVariations, testTag,
713 android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
714 ctx.AddFarVariationDependencies(libVariations, jniLibTag,
715 android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
716 ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
717 android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
718 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
719 android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
720 ctx.AddFarVariationDependencies(target.Variations(), fsTag,
721 android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900722}
723
724func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900725 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900726 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
727 } else {
728 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
729 if ctx.Os().Bionic() {
730 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
731 } else {
732 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
733 }
734 }
735}
736
Jooyung Hand045ebc2022-12-06 15:23:57 +0900737// getImageVariationPair returns a pair for the image variation name as its
738// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
739// suffix indicates the vndk version when it's vendor or product.
740// getImageVariation can simply join the result of this function to get the
741// image variation name.
742func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900743 if a.vndkApex {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900744 return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900745 }
746
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900747 var prefix string
748 var vndkVersion string
749 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000750 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900751 prefix = cc.VendorVariationPrefix
752 vndkVersion = deviceConfig.VndkVersion()
753 } else if a.ProductSpecific() {
754 prefix = cc.ProductVariationPrefix
755 vndkVersion = deviceConfig.ProductVndkVersion()
756 }
757 }
758 if vndkVersion == "current" {
759 vndkVersion = deviceConfig.PlatformVndkVersion()
760 }
761 if vndkVersion != "" {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900762 return prefix, vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900763 }
764
Jooyung Hand045ebc2022-12-06 15:23:57 +0900765 return android.CoreVariation, "" // The usual case
766}
767
768// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
769// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
770func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
771 prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
772 return prefix + vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900773}
774
775func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900776 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
777 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
778 // each target os/architectures, appropriate dependencies are selected by their
779 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900780 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900781 imageVariation := a.getImageVariation(ctx)
782
783 a.combineProperties(ctx)
784
785 has32BitTarget := false
786 for _, target := range targets {
787 if target.Arch.ArchType.Multilib == "lib32" {
788 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000789 }
790 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900791 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900792 // Don't include artifacts for the host cross targets because there is no way for us
793 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900794 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900795 continue
796 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000797
Colin Cross70572ed2022-11-02 13:14:20 -0700798 var deps ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000799
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900800 // Add native modules targeting both ABIs. When multilib.* is omitted for
801 // native_shared_libs/jni_libs/tests, it implies multilib.both
Colin Cross70572ed2022-11-02 13:14:20 -0700802 deps.Merge(a.properties.Multilib.Both)
803 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900804 Native_shared_libs: a.properties.Native_shared_libs,
805 Tests: a.properties.Tests,
806 Jni_libs: a.properties.Jni_libs,
807 Binaries: nil,
808 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900809
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900810 // Add native modules targeting the first ABI When multilib.* is omitted for
811 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900812 isPrimaryAbi := i == 0
813 if isPrimaryAbi {
Colin Cross70572ed2022-11-02 13:14:20 -0700814 deps.Merge(a.properties.Multilib.First)
815 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900816 Native_shared_libs: nil,
817 Tests: nil,
818 Jni_libs: nil,
819 Binaries: a.properties.Binaries,
820 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900821 }
822
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900823 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900824 switch target.Arch.ArchType.Multilib {
825 case "lib32":
Colin Cross70572ed2022-11-02 13:14:20 -0700826 deps.Merge(a.properties.Multilib.Lib32)
827 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900828 case "lib64":
Colin Cross70572ed2022-11-02 13:14:20 -0700829 deps.Merge(a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900830 if !has32BitTarget {
Colin Cross70572ed2022-11-02 13:14:20 -0700831 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900832 }
833 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900834
Jiyong Park59140302020-12-14 18:44:04 +0900835 // Add native modules targeting a specific arch variant
836 switch target.Arch.ArchType {
837 case android.Arm:
Colin Cross70572ed2022-11-02 13:14:20 -0700838 deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900839 case android.Arm64:
Colin Cross70572ed2022-11-02 13:14:20 -0700840 deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700841 case android.Riscv64:
Colin Cross70572ed2022-11-02 13:14:20 -0700842 deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900843 case android.X86:
Colin Cross70572ed2022-11-02 13:14:20 -0700844 deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900845 case android.X86_64:
Colin Cross70572ed2022-11-02 13:14:20 -0700846 deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900847 default:
848 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
849 }
850
Colin Cross70572ed2022-11-02 13:14:20 -0700851 addDependenciesForNativeModules(ctx, deps, target, imageVariation)
Sundong Ahn80c04892021-11-23 00:57:19 +0000852 ctx.AddFarVariationDependencies([]blueprint.Variation{
853 {Mutator: "os", Variation: target.OsVariation()},
854 {Mutator: "arch", Variation: target.ArchVariation()},
855 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900856 }
857
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900858 // Common-arch dependencies come next
859 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900860 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000861 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100862}
863
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900864// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900865func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
866 if a.overridableProperties.Allowed_files != nil {
867 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100868 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900869
870 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
871 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800872 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900873 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900874 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
875 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
876 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700877 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
878 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
879 // regardless of the TARGET_PREFER_* setting. See b/144532908
880 arches := ctx.DeviceConfig().Arches()
881 if len(arches) != 0 {
882 archForPrebuiltEtc := arches[0]
883 for _, arch := range arches {
884 // Prefer 64-bit arch if there is any
885 if arch.ArchType.Multilib == "lib64" {
886 archForPrebuiltEtc = arch
887 break
888 }
889 }
890 ctx.AddFarVariationDependencies([]blueprint.Variation{
891 {Mutator: "os", Variation: ctx.Os().String()},
892 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
893 }, prebuiltTag, prebuilts...)
894 }
895 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700896
897 // Dependencies for signing
898 if String(a.overridableProperties.Key) == "" {
899 ctx.PropertyErrorf("key", "missing")
900 return
901 }
902 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
903
904 cert := android.SrcIsModule(a.getCertString(ctx))
905 if cert != "" {
906 ctx.AddDependency(ctx.Module(), certificateTag, cert)
907 // empty cert is not an error. Cert and private keys will be directly found under
908 // PRODUCT_DEFAULT_DEV_CERTIFICATE
909 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100910}
911
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900912type ApexBundleInfo struct {
913 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100914}
915
Paul Duffin949abc02020-12-08 10:34:30 +0000916var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900917
Paul Duffina7d6a892020-12-07 17:39:59 +0000918var _ ApexInfoMutator = (*apexBundle)(nil)
919
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100920func (a *apexBundle) ApexVariationName() string {
921 return a.properties.ApexVariationName
922}
923
Paul Duffina7d6a892020-12-07 17:39:59 +0000924// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900925// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
926// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
927// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
928// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000929//
930// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
931// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
932// The apexMutator uses that list to create module variants for the apexes to which it belongs.
933// The relationship between module variants and apexes is not one-to-one as variants will be
934// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000935func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900936
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900937 // The VNDK APEX is special. For the APEX, the membership is described in a very different
938 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
939 // libraries are self-identified by their vndk.enabled properties. There is no need to run
940 // this mutator for the APEX as nothing will be collected. So, let's return fast.
941 if a.vndkApex {
942 return
943 }
944
945 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
946 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
947 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
948 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
949 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900950 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
951 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900952 if proptools.Bool(a.properties.Use_vndk_as_stable) {
953 if !useVndk {
954 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
955 }
956 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
957 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
958 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
959 }
960 })
961 if mctx.Failed() {
962 return
963 }
Jooyung Handf78e212020-07-22 15:54:47 +0900964 }
965
Colin Cross56a83212020-09-15 18:30:11 -0700966 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900967 am, ok := child.(android.ApexModule)
968 if !ok || !am.CanHaveApexVariants() {
969 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900970 }
Paul Duffin573989d2021-03-17 13:25:29 +0000971 depTag := mctx.OtherModuleDependencyTag(child)
972
973 // Check to see if the tag always requires that the child module has an apex variant for every
974 // apex variant of the parent module. If it does not then it is still possible for something
975 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
976 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
977 return true
978 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000979 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900980 return false
981 }
Jooyung Handf78e212020-07-22 15:54:47 +0900982 if excludeVndkLibs {
983 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
984 return false
985 }
986 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900987 // By default, all the transitive dependencies are collected, unless filtered out
988 // above.
Colin Cross56a83212020-09-15 18:30:11 -0700989 return true
990 }
991
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900992 // Records whether a certain module is included in this apexBundle via direct dependency or
993 // inndirect dependency.
994 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -0700995 mctx.WalkDeps(func(child, parent android.Module) bool {
996 if !continueApexDepsWalk(child, parent) {
997 return false
998 }
Jooyung Han698dd9f2020-07-22 15:17:19 +0900999 // If the parent is apexBundle, this child is directly depended.
1000 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001001 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -07001002 contents[depName] = contents[depName].Add(directDep)
1003 return true
1004 })
1005
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001006 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +09001007 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -07001008 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
1009 Contents: apexContents,
1010 })
1011
Jooyung Haned124c32021-01-26 11:43:46 +09001012 minSdkVersion := a.minSdkVersion(mctx)
1013 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
1014 if minSdkVersion.IsNone() {
1015 minSdkVersion = android.FutureApiLevel
1016 }
1017
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001018 // This is the main part of this mutator. Mark the collected dependencies that they need to
1019 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +09001020
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001021 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
1022 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -07001023 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001024 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +09001025 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -07001026 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +09001027 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001028 InApexVariants: []string{apexVariationName},
1029 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -07001030 ApexContents: []*android.ApexContents{apexContents},
1031 }
Colin Cross56a83212020-09-15 18:30:11 -07001032 mctx.WalkDeps(func(child, parent android.Module) bool {
1033 if !continueApexDepsWalk(child, parent) {
1034 return false
1035 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001036 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +09001037 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +09001038 })
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001039}
1040
Paul Duffina7d6a892020-12-07 17:39:59 +00001041type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001042 // ApexVariationName returns the name of the APEX variation to use in the apex
1043 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
1044 ApexVariationName() string
1045
Paul Duffina7d6a892020-12-07 17:39:59 +00001046 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1047 // depended upon by an apex and which require an apex specific variant.
1048 ApexInfoMutator(android.TopDownMutatorContext)
1049}
1050
1051// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1052// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001053// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001054func apexInfoMutator(mctx android.TopDownMutatorContext) {
1055 if !mctx.Module().Enabled() {
1056 return
1057 }
1058
1059 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1060 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001061 }
Spandan Das42e89502022-05-06 22:12:55 +00001062 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001063}
1064
Spandan Das66773252022-01-15 00:23:18 +00001065// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1066// This check is enforced for updatable modules
1067func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1068 if !mctx.Module().Enabled() {
1069 return
1070 }
Spandan Das08c911f2022-01-21 22:07:26 +00001071 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001072 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001073 // b/208656169 Do not propagate strict updatability linting to libcore/
1074 // These libs are available on the classpath during compilation
1075 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1076 // Only skip libraries defined in libcore root, not subdirectories
1077 if mctx.OtherModuleDir(child) == "libcore" {
1078 // Do not traverse transitive deps of libcore/ libs
1079 return false
1080 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001081 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1082 return false
1083 }
Spandan Das66773252022-01-15 00:23:18 +00001084 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1085 lintable.SetStrictUpdatabilityLinting(true)
1086 }
1087 // visit transitive deps
1088 return true
1089 })
1090 }
1091}
1092
Spandan Das42e89502022-05-06 22:12:55 +00001093// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1094func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1095 if !mctx.Module().Enabled() {
1096 return
1097 }
1098 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1099 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1100 mctx.VisitDirectDeps(func(module android.Module) {
1101 // ignore android_test_app
1102 if app, ok := module.(*java.AndroidApp); ok {
1103 app.SetUpdatable(true)
1104 }
1105 })
1106 }
1107}
1108
Spandan Das08c911f2022-01-21 22:07:26 +00001109// TODO: b/215736885 Whittle the denylist
1110// Transitive deps of certain mainline modules baseline NewApi errors
1111// Skip these mainline modules for now
1112var (
1113 skipStrictUpdatabilityLintAllowlist = []string{
1114 "com.android.art",
1115 "com.android.art.debug",
1116 "com.android.conscrypt",
1117 "com.android.media",
1118 // test apexes
1119 "test_com.android.art",
1120 "test_com.android.conscrypt",
1121 "test_com.android.media",
1122 "test_jitzygote_com.android.art",
1123 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001124
1125 // TODO: b/215736885 Remove this list
1126 skipLintJavalibAllowlist = []string{
1127 "conscrypt.module.platform.api.stubs",
1128 "conscrypt.module.public.api.stubs",
1129 "conscrypt.module.public.api.stubs.system",
1130 "conscrypt.module.public.api.stubs.module_lib",
1131 "framework-media.stubs",
1132 "framework-media.stubs.system",
1133 "framework-media.stubs.module_lib",
1134 }
Spandan Das08c911f2022-01-21 22:07:26 +00001135)
1136
1137func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1138 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1139}
1140
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001141// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1142// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1143// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001144func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1145 if !mctx.Module().Enabled() {
1146 return
1147 }
1148 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001149 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1150 }
1151}
1152
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001153// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1154// the apex in order to retrieve its contents later.
1155// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001156func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1157 if !mctx.Module().Enabled() {
1158 return
1159 }
Colin Cross56a83212020-09-15 18:30:11 -07001160 if am, ok := mctx.Module().(android.ApexModule); ok {
1161 if testFor := am.TestFor(); len(testFor) > 0 {
1162 mctx.AddFarVariationDependencies([]blueprint.Variation{
1163 {Mutator: "os", Variation: am.Target().OsVariation()},
1164 {"arch", "common"},
1165 }, testForTag, testFor...)
1166 }
1167 }
1168}
1169
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001170// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001171func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1172 if !mctx.Module().Enabled() {
1173 return
1174 }
Colin Cross56a83212020-09-15 18:30:11 -07001175 if _, ok := mctx.Module().(android.ApexModule); ok {
1176 var contents []*android.ApexContents
1177 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1178 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1179 contents = append(contents, abInfo.Contents)
1180 }
1181 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1182 ApexContents: contents,
1183 })
Colin Crossaede88c2020-08-11 12:17:01 -07001184 }
1185}
1186
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001187// markPlatformAvailability marks whether or not a module can be available to platform. A module
1188// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1189// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1190// be) available to platform
1191// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001192func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1193 // Host and recovery are not considered as platform
1194 if mctx.Host() || mctx.Module().InstallInRecovery() {
1195 return
1196 }
1197
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001198 am, ok := mctx.Module().(android.ApexModule)
1199 if !ok {
1200 return
1201 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001202
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001203 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001204
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001205 // If any of the dep is not available to platform, this module is also considered as being
1206 // not available to platform even if it has "//apex_available:platform"
1207 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001208 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001209 // if the dependency crosses apex boundary, don't consider it
1210 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001211 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001212 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1213 availableToPlatform = false
1214 // TODO(b/154889534) trigger an error when 'am' has
1215 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001216 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001217 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001218
Paul Duffinb5769c12021-05-12 16:16:51 +01001219 // Exception 1: check to see if the module always requires it.
1220 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001221 availableToPlatform = true
1222 }
1223
1224 // Exception 2: bootstrap bionic libraries are also always available to platform
1225 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1226 availableToPlatform = true
1227 }
1228
1229 if !availableToPlatform {
1230 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001231 }
1232}
1233
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001234// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001235// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001236func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001237 if !mctx.Module().Enabled() {
1238 return
1239 }
Colin Cross56a83212020-09-15 18:30:11 -07001240
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001241 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001242 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001243 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001244 return
1245 }
1246
1247 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001248 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1249 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001250 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001251 if strings.HasPrefix(apexBundleName, "com.android.art") {
1252 // Create an alias from the platform variant. This is done to make
1253 // test_for dependencies work for modules that are split by the APEX
1254 // mutator, since test_for dependencies always go to the platform variant.
1255 // This doesn't happen for normal APEXes that are disjunct, so only do
1256 // this for the overlapping ART APEXes.
1257 // TODO(b/183882457): Remove this if the test_for functionality is
1258 // refactored to depend on the proper APEX variants instead of platform.
1259 mctx.CreateAliasVariation("", apexBundleName)
1260 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001261 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1262 apexBundleName := o.GetOverriddenModuleName()
1263 if apexBundleName == "" {
1264 mctx.ModuleErrorf("base property is not set")
1265 return
1266 }
1267 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001268 if strings.HasPrefix(apexBundleName, "com.android.art") {
1269 // TODO(b/183882457): See note for CreateAliasVariation above.
1270 mctx.CreateAliasVariation("", apexBundleName)
1271 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001272 }
1273}
Sundong Ahne9b55722019-09-06 17:37:42 +09001274
Paul Duffin6717d882021-06-15 19:09:41 +01001275// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1276// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001277func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001278 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001279 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001280 return !a.vndkApex
1281 }
1282
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001283 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001284}
1285
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001286// See android.UpdateDirectlyInAnyApex
1287// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001288func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1289 if !mctx.Module().Enabled() {
1290 return
1291 }
1292 if am, ok := mctx.Module().(android.ApexModule); ok {
1293 android.UpdateDirectlyInAnyApex(mctx, am)
1294 }
1295}
1296
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001297// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001298type apexPackaging int
1299
1300const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001301 // imageApex is a packaging method where contents are included in a filesystem image which
1302 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001303 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001304
1305 // zipApex is a packaging method where contents are directly included in the zip container.
1306 // This is used for host-side testing - because the contents are easily accessible by
1307 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001308 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001309
1310 // flattendApex is a packaging method where contents are not included in the APEX file, but
1311 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1312 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001313 flattenedApex
1314)
1315
1316const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001317 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001318 imageApexSuffix = ".apex"
1319 imageCapexSuffix = ".capex"
1320 zipApexSuffix = ".zipapex"
1321 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001322
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001323 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001324 imageApexType = "image"
1325 zipApexType = "zip"
1326 flattenedApexType = "flattened"
1327
Dan Willemsen47e1a752021-10-16 18:36:13 -07001328 ext4FsType = "ext4"
1329 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001330 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001331)
1332
1333// The suffix for the output "file", not the module
1334func (a apexPackaging) suffix() string {
1335 switch a {
1336 case imageApex:
1337 return imageApexSuffix
1338 case zipApex:
1339 return zipApexSuffix
1340 default:
1341 panic(fmt.Errorf("unknown APEX type %d", a))
1342 }
1343}
1344
1345func (a apexPackaging) name() string {
1346 switch a {
1347 case imageApex:
1348 return imageApexType
1349 case zipApex:
1350 return zipApexType
1351 default:
1352 panic(fmt.Errorf("unknown APEX type %d", a))
1353 }
1354}
1355
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001356// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1357// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001358func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001359 if !mctx.Module().Enabled() {
1360 return
1361 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001362 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001363 var variants []string
1364 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1365 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001366 // This is the normal case. Note that both image and flattend APEXes are
1367 // created. The image type is installed to the system partition, while the
1368 // flattened APEX is (optionally) installed to the system_ext partition.
1369 // This is mostly for GSI which has to support wide range of devices. If GSI
1370 // is installed on a newer (APEX-capable) device, the image APEX in the
1371 // system will be used. However, if the same GSI is installed on an old
1372 // device which can't support image APEX, the flattened APEX in the
1373 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001374 variants = append(variants, imageApexType, flattenedApexType)
1375 case "zip":
1376 variants = append(variants, zipApexType)
1377 case "both":
1378 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1379 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001380 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001381 return
1382 }
1383
1384 modules := mctx.CreateLocalVariations(variants...)
1385
1386 for i, v := range variants {
1387 switch v {
1388 case imageApexType:
1389 modules[i].(*apexBundle).properties.ApexType = imageApex
1390 case zipApexType:
1391 modules[i].(*apexBundle).properties.ApexType = zipApex
1392 case flattenedApexType:
1393 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001394 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001395 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001396 modules[i].(*apexBundle).MakeAsSystemExt()
1397 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001398 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001399 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001400 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001401 // payload_type is forcibly overridden to "image"
1402 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001403 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001404 }
1405}
1406
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001407var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001408
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001409// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001410func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001411 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001412 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001413 return true
1414}
1415
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001416var _ android.OutputFileProducer = (*apexBundle)(nil)
1417
1418// Implements android.OutputFileProducer
1419func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1420 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001421 case "", android.DefaultDistTag:
1422 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001423 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001424 case imageApexSuffix:
1425 // uncompressed one
1426 if a.outputApexFile != nil {
1427 return android.Paths{a.outputApexFile}, nil
1428 }
1429 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001430 default:
1431 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1432 }
1433}
1434
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001435var _ multitree.Exportable = (*apexBundle)(nil)
1436
1437func (a *apexBundle) Exportable() bool {
1438 if a.properties.ApexType == flattenedApex {
1439 return false
1440 }
1441 return true
1442}
1443
1444func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1445 ret := make(map[string]android.Paths)
1446 ret["apex"] = android.Paths{a.outputFile}
1447 return ret
1448}
1449
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001450var _ cc.Coverage = (*apexBundle)(nil)
1451
1452// Implements cc.Coverage
1453func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1454 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1455}
1456
1457// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001458func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001459 a.properties.PreventInstall = true
1460}
1461
1462// Implements cc.Coverage
1463func (a *apexBundle) HideFromMake() {
1464 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001465 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1466 // TODO(ccross): untangle these
1467 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001468}
1469
1470// Implements cc.Coverage
1471func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1472 a.properties.IsCoverageVariant = coverage
1473}
1474
1475// Implements cc.Coverage
1476func (a *apexBundle) EnableCoverageIfNeeded() {}
1477
1478var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1479
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001480// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001481func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001482 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001483}
1484
Jiyong Parkf4020582021-11-29 12:37:10 +09001485func (a *apexBundle) FutureUpdatable() bool {
1486 return proptools.BoolDefault(a.properties.Future_updatable, false)
1487}
1488
Jiyong Park1bc84122021-06-22 20:23:05 +09001489func (a *apexBundle) UsePlatformApis() bool {
1490 return proptools.BoolDefault(a.properties.Platform_apis, false)
1491}
1492
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001493// getCertString returns the name of the cert that should be used to sign this APEX. This is
1494// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001495func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001496 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001497 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1498 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1499 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001500 if a.vndkApex {
1501 moduleName = vndkApexName
1502 }
1503 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001504 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001505 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001506 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001507 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001508}
1509
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001510// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001511func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001512 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001513}
1514
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001515// See the generate_hashtree property
1516func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001517 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001518}
1519
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001520// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001521func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1522 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1523}
1524
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001525// See the test_only_force_compression property
1526func (a *apexBundle) testOnlyShouldForceCompression() bool {
1527 return proptools.Bool(a.properties.Test_only_force_compression)
1528}
1529
Dennis Shenaf41bc12022-08-03 16:46:43 +00001530// See the dynamic_common_lib_apex property
1531func (a *apexBundle) dynamic_common_lib_apex() bool {
1532 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1533}
1534
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001535// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1536// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1537// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001538
Jiyong Parkf97782b2019-02-13 20:28:58 +09001539func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1540 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1541 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1542 }
1543}
1544
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001545func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001546 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1547 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001548 }
1549
1550 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001551 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001552 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001553 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001554 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001555 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001556 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001557 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001558 }
1559 }
1560 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001561}
1562
Jooyung Han8ce8db92020-05-15 19:05:05 +09001563func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001564 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1565 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001566 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001567 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001568 for _, target := range ctx.MultiTargets() {
1569 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001570 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001571 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001572 Tests: nil,
1573 Jni_libs: nil,
1574 Binaries: nil,
1575 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001576 break
1577 }
1578 }
1579 }
1580}
1581
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001582// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1583// returned apexFile saves information about the Soong module that will be used for creating the
1584// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001585func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001586 // Decide the APEX-local directory by the multilib of the library In the future, we may
1587 // query this to the module.
1588 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001589 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001590 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001591 case "lib32":
1592 dirInApex = "lib"
1593 case "lib64":
1594 dirInApex = "lib64"
1595 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001596 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001597 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001598 }
Jooyung Han35155c42020-02-06 17:33:20 +09001599 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001600 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001601 // Special case for Bionic libs and other libs installed with them. This is to
1602 // prevent those libs from being included in the search path
1603 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1604 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1605 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1606 // will be loaded into the default linker namespace (aka "platform" namespace). If
1607 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1608 // be loaded again into the runtime linker namespace, which will result in double
1609 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001610 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001611 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001612
Colin Cross1d487152022-10-03 19:14:46 -07001613 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001614 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1615 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001616}
1617
Jiyong Park1833cef2019-12-13 13:28:36 +09001618func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001619 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001620 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001621 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001622 }
Jooyung Han35155c42020-02-06 17:33:20 +09001623 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001624 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001625 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1626 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001627 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001628 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001629 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001630}
1631
Jiyong Park99644e92020-11-17 22:21:02 +09001632func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1633 dirInApex := "bin"
1634 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1635 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1636 }
Colin Cross1d487152022-10-03 19:14:46 -07001637 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001638 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1639 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1640 return af
1641}
1642
1643func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1644 // Decide the APEX-local directory by the multilib of the library
1645 // In the future, we may query this to the module.
1646 var dirInApex string
1647 switch rustm.Arch().ArchType.Multilib {
1648 case "lib32":
1649 dirInApex = "lib"
1650 case "lib64":
1651 dirInApex = "lib64"
1652 }
1653 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1654 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1655 }
Colin Cross1d487152022-10-03 19:14:46 -07001656 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001657 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1658 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1659}
1660
Jiyong Park1833cef2019-12-13 13:28:36 +09001661func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001662 dirInApex := "bin"
1663 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001664 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001665}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001666
Jiyong Park1833cef2019-12-13 13:28:36 +09001667func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001668 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001669 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001670 // NB: Since go binaries are static we don't need the module for anything here, which is
1671 // good since the go tool is a blueprint.Module not an android.Module like we would
1672 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001673 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001674}
1675
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001676func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001677 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001678 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1679 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1680 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001681 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001682 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001683 af.symlinks = sh.Symlinks()
1684 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001685}
1686
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001687func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001688 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001689 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001690 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001691}
1692
atrost6e126252020-01-27 17:01:16 +00001693func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1694 dirInApex := filepath.Join("etc", config.SubDir())
1695 fileToCopy := config.CompatConfig()
1696 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1697}
1698
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001699// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1700// way.
1701type javaModule interface {
1702 android.Module
1703 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001704 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001705 JacocoReportClassesFile() android.Path
1706 LintDepSets() java.LintDepSets
1707 Stem() string
1708}
1709
1710var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001711var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001712var _ javaModule = (*java.SdkLibrary)(nil)
1713var _ javaModule = (*java.DexImport)(nil)
1714var _ javaModule = (*java.SdkLibraryImport)(nil)
1715
Paul Duffin190fdef2021-04-26 10:33:59 +01001716// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001717func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001718 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001719}
1720
1721// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1722func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001723 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001724 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001725 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1726 af.lintDepSets = module.LintDepSets()
1727 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001728 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1729 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1730 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1731 }
1732 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001733 return af
1734}
1735
1736// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1737// the same way.
1738type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001739 android.Module
1740 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001741 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001742 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001743 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001744 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001745 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001746 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001747}
1748
1749var _ androidApp = (*java.AndroidApp)(nil)
1750var _ androidApp = (*java.AndroidAppImport)(nil)
1751
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001752func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1753 buildId := ctx.Config().BuildId()
1754
1755 // The build ID is used as a suffix for a filename, so ensure that
1756 // the set of characters being used are sanitized.
1757 // - any word character: [a-zA-Z0-9_]
1758 // - dots: .
1759 // - dashes: -
1760 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1761 if !validRegex.MatchString(buildId) {
1762 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1763 }
1764 return buildId
1765}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001766
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001767func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001768 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001769 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001770 appDir = "priv-app"
1771 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001772
1773 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1774 // so that PackageManager correctly invalidates the existing installed apk
1775 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001776 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001777 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001778
Yo Chiange8128052020-07-23 20:09:18 +08001779 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001780 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001781 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001782 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001783
1784 if app, ok := aapp.(interface {
1785 OverriddenManifestPackageName() string
1786 }); ok {
1787 af.overriddenPackageName = app.OverriddenManifestPackageName()
1788 }
Jiyong Park618922e2020-01-08 13:35:43 +09001789 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001790}
1791
Jiyong Park69aeba92020-04-24 21:16:36 +09001792func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1793 rroDir := "overlay"
1794 dirInApex := filepath.Join(rroDir, rro.Theme())
1795 fileToCopy := rro.OutputFile()
1796 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1797 af.certificate = rro.Certificate()
1798
1799 if a, ok := rro.(interface {
1800 OverriddenManifestPackageName() string
1801 }); ok {
1802 af.overriddenPackageName = a.OverriddenManifestPackageName()
1803 }
1804 return af
1805}
1806
Ken Chenfad7f9d2021-11-10 22:02:57 +08001807func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1808 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001809 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1810}
1811
Jiyong Park12a719c2021-01-07 15:31:24 +09001812func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1813 dirInApex := filepath.Join("etc", "fs")
1814 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1815}
1816
Paul Duffin064b70c2020-11-02 17:32:38 +00001817// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001818// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1819// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1820// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001821func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001822 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001823 am, ok := child.(android.ApexModule)
1824 if !ok || !am.CanHaveApexVariants() {
1825 return false
1826 }
1827
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001828 // Filter-out unwanted depedendencies
1829 depTag := ctx.OtherModuleDependencyTag(child)
1830 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1831 return false
1832 }
Paul Duffin520917a2022-05-13 13:01:59 +00001833 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001834 return false
1835 }
1836
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001837 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001838 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001839
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001840 // Visit actually
1841 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001842 })
1843}
1844
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001845// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1846type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001847
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001848const (
1849 ext4 fsType = iota
1850 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001851 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001852)
Artur Satayev849f8442020-04-28 14:57:42 +01001853
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001854func (f fsType) string() string {
1855 switch f {
1856 case ext4:
1857 return ext4FsType
1858 case f2fs:
1859 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001860 case erofs:
1861 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001862 default:
1863 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001864 }
1865}
1866
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001867var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1868
1869func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1870 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1871}
1872
1873func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1874 bazelCtx := ctx.Config().BazelContext
1875 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1876}
1877
Jingwen Chen889f2f22022-12-16 08:16:01 +00001878// GetBazelLabel returns the bazel label of this apexBundle, or the label of the
1879// override_apex module overriding this apexBundle. An apexBundle can be
1880// overridden by different override_apex modules (e.g. Google or Go variants),
1881// which is handled by the overrides mutators.
1882func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string {
1883 if _, ok := ctx.Module().(android.OverridableModule); ok {
1884 return android.MaybeBp2buildLabelOfOverridingModule(ctx)
1885 }
1886 return a.BazelModuleBase.GetBazelLabel(ctx, a)
1887}
1888
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001889func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1890 if !a.commonBuildActions(ctx) {
1891 return
1892 }
1893
1894 a.setApexTypeAndSuffix(ctx)
1895 a.setPayloadFsType(ctx)
1896 a.setSystemLibLink(ctx)
1897
1898 if a.properties.ApexType != zipApex {
1899 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1900 }
1901
1902 bazelCtx := ctx.Config().BazelContext
1903 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1904 if err != nil {
1905 ctx.ModuleErrorf(err.Error())
1906 return
1907 }
1908 a.installDir = android.PathForModuleInstall(ctx, "apex")
1909 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1910 a.outputFile = a.outputApexFile
1911 a.setCompression(ctx)
1912
Liz Kammer0e255ef2022-11-04 16:07:04 -04001913 // TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
1914 // interface if these were set in a provider rather than the module itself
Wei Li32dcdf92022-10-26 22:30:48 -07001915 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1916 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1917 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1918 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Liz Kammer0e255ef2022-11-04 16:07:04 -04001919
Vinh Tranb6803a52022-12-14 11:34:54 -05001920 // Ensure ApexInfo.RequiresLibs are installed as part of a bundle build
1921 for _, bazelLabel := range outputs.RequiresLibs {
1922 // convert Bazel label back to Soong module name
1923 a.requiredDeps = append(a.requiredDeps, android.ModuleFromBazelLabel(bazelLabel))
1924 }
1925
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001926 apexType := a.properties.ApexType
1927 switch apexType {
1928 case imageApex:
Liz Kammer303978d2022-11-04 16:12:43 -04001929 a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001930 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
Wei Licc73a052022-11-07 14:25:34 -08001931 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001932 // TODO(b/239084755): Generate the java api using.xml file from Bazel.
Jingwen Chen1ec77852022-11-07 14:36:12 +00001933 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
Wei Li78c07de2022-11-08 16:01:05 -08001934 a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001935 installSuffix := imageApexSuffix
1936 if a.isCompressed {
1937 installSuffix = imageCapexSuffix
1938 }
1939 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1940 a.compatSymlinks.Paths()...)
1941 default:
1942 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1943 }
1944
1945 /*
1946 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1947 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1948 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1949 To find out what Soong build puts there, run:
1950 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1951 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1952 return a.depVisitor(&vctx, ctx, child, parent)
1953 })
1954 vctx.normalizeFileInfo()
1955 */
1956
1957}
1958
1959func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1960 if a.properties.ApexType != imageApex {
1961 a.isCompressed = false
1962 } else if a.testOnlyShouldForceCompression() {
1963 a.isCompressed = true
1964 } else {
1965 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1966 }
1967}
1968
1969func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1970 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1971 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1972 // the same library in the system partition, thus effectively sharing the same libraries
1973 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1974 // in the APEX.
1975 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1976
1977 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1978 // So we can't link them to /system/lib libs which are core variants.
1979 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1980 a.linkToSystemLib = false
1981 }
1982
1983 forced := ctx.Config().ForceApexSymlinkOptimization()
1984 updatable := a.Updatable() || a.FutureUpdatable()
1985
1986 // We don't need the optimization for updatable APEXes, as it might give false signal
1987 // to the system health when the APEXes are still bundled (b/149805758).
1988 if !forced && updatable && a.properties.ApexType == imageApex {
1989 a.linkToSystemLib = false
1990 }
1991
1992 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1993 if ctx.Host() {
1994 a.linkToSystemLib = false
1995 }
1996}
1997
1998func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1999 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
2000 case ext4FsType:
2001 a.payloadFsType = ext4
2002 case f2fsFsType:
2003 a.payloadFsType = f2fs
2004 case erofsFsType:
2005 a.payloadFsType = erofs
2006 default:
2007 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
2008 }
2009}
2010
2011func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
2012 // Set suffix and primaryApexType depending on the ApexType
2013 buildFlattenedAsDefault := ctx.Config().FlattenApex()
2014 switch a.properties.ApexType {
2015 case imageApex:
2016 if buildFlattenedAsDefault {
2017 a.suffix = imageApexSuffix
2018 } else {
2019 a.suffix = ""
2020 a.primaryApexType = true
2021
2022 if ctx.Config().InstallExtraFlattenedApexes() {
2023 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
2024 }
2025 }
2026 case zipApex:
2027 if proptools.String(a.properties.Payload_type) == "zip" {
2028 a.suffix = ""
2029 a.primaryApexType = true
2030 } else {
2031 a.suffix = zipApexSuffix
2032 }
2033 case flattenedApex:
2034 if buildFlattenedAsDefault {
2035 a.suffix = ""
2036 a.primaryApexType = true
2037 } else {
2038 a.suffix = flattenedSuffix
2039 }
2040 }
2041}
2042
2043func (a apexBundle) isCompressable() bool {
2044 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
2045}
2046
2047func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
2048 a.checkApexAvailability(ctx)
2049 a.checkUpdatable(ctx)
2050 a.CheckMinSdkVersion(ctx)
2051 a.checkStaticLinkingToStubLibraries(ctx)
2052 a.checkStaticExecutables(ctx)
2053 if len(a.properties.Tests) > 0 && !a.testApex {
2054 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
2055 return false
2056 }
2057 return true
2058}
2059
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002060type visitorContext struct {
2061 // all the files that will be included in this APEX
2062 filesInfo []apexFile
2063
2064 // native lib dependencies
2065 provideNativeLibs []string
2066 requireNativeLibs []string
2067
2068 handleSpecialLibs bool
Jooyung Han862c0d62022-12-21 10:15:37 +09002069
2070 // if true, raise error on duplicate apexFile
2071 checkDuplicate bool
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002072}
2073
Jooyung Han862c0d62022-12-21 10:15:37 +09002074func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002075 encountered := make(map[string]apexFile)
2076 for _, f := range vctx.filesInfo {
2077 dest := filepath.Join(f.installDir, f.builtFile.Base())
2078 if e, ok := encountered[dest]; !ok {
2079 encountered[dest] = f
2080 } else {
Jooyung Han862c0d62022-12-21 10:15:37 +09002081 if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
2082 mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
2083 dest, e.builtFile, f.builtFile)
2084 return
2085 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002086 // If a module is directly included and also transitively depended on
2087 // consider it as directly included.
2088 e.transitiveDep = e.transitiveDep && f.transitiveDep
2089 encountered[dest] = e
2090 }
2091 }
2092 vctx.filesInfo = vctx.filesInfo[:0]
2093 for _, v := range encountered {
2094 vctx.filesInfo = append(vctx.filesInfo, v)
2095 }
2096 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2097 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2098 // changes.
2099 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2100 })
2101}
2102
2103func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2104 depTag := ctx.OtherModuleDependencyTag(child)
2105 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2106 return false
2107 }
2108 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2109 return false
2110 }
2111 depName := ctx.OtherModuleName(child)
2112 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2113 switch depTag {
2114 case sharedLibTag, jniLibTag:
2115 isJniLib := depTag == jniLibTag
2116 switch ch := child.(type) {
2117 case *cc.Module:
2118 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2119 fi.isJniLib = isJniLib
2120 vctx.filesInfo = append(vctx.filesInfo, fi)
2121 // Collect the list of stub-providing libs except:
2122 // - VNDK libs are only for vendors
2123 // - bootstrap bionic libs are treated as provided by system
2124 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2125 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2126 }
2127 return true // track transitive dependencies
2128 case *rust.Module:
2129 fi := apexFileForRustLibrary(ctx, ch)
2130 fi.isJniLib = isJniLib
2131 vctx.filesInfo = append(vctx.filesInfo, fi)
2132 return true // track transitive dependencies
2133 default:
2134 propertyName := "native_shared_libs"
2135 if isJniLib {
2136 propertyName = "jni_libs"
2137 }
2138 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2139 }
2140 case executableTag:
2141 switch ch := child.(type) {
2142 case *cc.Module:
2143 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2144 return true // track transitive dependencies
2145 case *python.Module:
2146 if ch.HostToolPath().Valid() {
2147 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2148 }
2149 case bootstrap.GoBinaryTool:
2150 if a.Host() {
2151 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2152 }
2153 case *rust.Module:
2154 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2155 return true // track transitive dependencies
2156 default:
2157 ctx.PropertyErrorf("binaries",
2158 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2159 }
2160 case shBinaryTag:
2161 if csh, ok := child.(*sh.ShBinary); ok {
2162 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2163 } else {
2164 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2165 }
2166 case bcpfTag:
2167 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2168 if !ok {
2169 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2170 return false
2171 }
2172
2173 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2174 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2175 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2176 }
2177 return true
2178 case sscpfTag:
2179 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2180 ctx.PropertyErrorf("systemserverclasspath_fragments",
2181 "%q is not a systemserverclasspath_fragment module", depName)
2182 return false
2183 }
2184 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2185 vctx.filesInfo = append(vctx.filesInfo, *af)
2186 }
2187 return true
2188 case javaLibTag:
2189 switch child.(type) {
2190 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2191 af := apexFileForJavaModule(ctx, child.(javaModule))
2192 if !af.ok() {
2193 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2194 return false
2195 }
2196 vctx.filesInfo = append(vctx.filesInfo, af)
2197 return true // track transitive dependencies
2198 default:
2199 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2200 }
2201 case androidAppTag:
2202 switch ap := child.(type) {
2203 case *java.AndroidApp:
2204 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2205 return true // track transitive dependencies
2206 case *java.AndroidAppImport:
2207 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2208 case *java.AndroidTestHelperApp:
2209 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2210 case *java.AndroidAppSet:
2211 appDir := "app"
2212 if ap.Privileged() {
2213 appDir = "priv-app"
2214 }
2215 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2216 // suffixed so that PackageManager correctly invalidates the
2217 // existing installed apk in favour of the new APK-in-APEX.
2218 // See bugs for more information.
2219 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2220 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2221 af.certificate = java.PresignedCertificate
2222 vctx.filesInfo = append(vctx.filesInfo, af)
2223 default:
2224 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2225 }
2226 case rroTag:
2227 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2228 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2229 } else {
2230 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2231 }
2232 case bpfTag:
2233 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2234 filesToCopy, _ := bpfProgram.OutputFiles("")
2235 apex_sub_dir := bpfProgram.SubDir()
2236 for _, bpfFile := range filesToCopy {
2237 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2238 }
2239 } else {
2240 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2241 }
2242 case fsTag:
2243 if fs, ok := child.(filesystem.Filesystem); ok {
2244 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2245 } else {
2246 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2247 }
2248 case prebuiltTag:
2249 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2250 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2251 } else {
2252 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2253 }
2254 case compatConfigTag:
2255 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2256 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2257 } else {
2258 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2259 }
2260 case testTag:
2261 if ccTest, ok := child.(*cc.Module); ok {
2262 if ccTest.IsTestPerSrcAllTestsVariation() {
2263 // Multiple-output test module (where `test_per_src: true`).
2264 //
2265 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2266 // We do not add this variation to `filesInfo`, as it has no output;
2267 // however, we do add the other variations of this module as indirect
2268 // dependencies (see below).
2269 } else {
2270 // Single-output test module (where `test_per_src: false`).
2271 af := apexFileForExecutable(ctx, ccTest)
2272 af.class = nativeTest
2273 vctx.filesInfo = append(vctx.filesInfo, af)
2274 }
2275 return true // track transitive dependencies
2276 } else {
2277 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2278 }
2279 case keyTag:
2280 if key, ok := child.(*apexKey); ok {
2281 a.privateKeyFile = key.privateKeyFile
2282 a.publicKeyFile = key.publicKeyFile
2283 } else {
2284 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2285 }
2286 case certificateTag:
2287 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2288 a.containerCertificateFile = dep.Certificate.Pem
2289 a.containerPrivateKeyFile = dep.Certificate.Key
2290 } else {
2291 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2292 }
2293 case android.PrebuiltDepTag:
2294 // If the prebuilt is force disabled, remember to delete the prebuilt file
2295 // that might have been installed in the previous builds
2296 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2297 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2298 }
2299 }
2300 return false
2301 }
2302
2303 if a.vndkApex {
2304 return false
2305 }
2306
2307 // indirect dependencies
2308 am, ok := child.(android.ApexModule)
2309 if !ok {
2310 return false
2311 }
2312 // We cannot use a switch statement on `depTag` here as the checked
2313 // tags used below are private (e.g. `cc.sharedDepTag`).
2314 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2315 if ch, ok := child.(*cc.Module); ok {
2316 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2317 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2318 return false
2319 }
2320 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2321 af.transitiveDep = true
2322
2323 // Always track transitive dependencies for host.
2324 if a.Host() {
2325 vctx.filesInfo = append(vctx.filesInfo, af)
2326 return true
2327 }
2328
2329 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2330 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2331 // If the dependency is a stubs lib, don't include it in this APEX,
2332 // but make sure that the lib is installed on the device.
2333 // In case no APEX is having the lib, the lib is installed to the system
2334 // partition.
2335 //
2336 // Always include if we are a host-apex however since those won't have any
2337 // system libraries.
Alan Stokes73feba32022-11-14 12:21:24 +00002338 if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002339 // we need a module name for Make
2340 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2341 if !android.InList(name, a.requiredDeps) {
2342 a.requiredDeps = append(a.requiredDeps, name)
2343 }
2344 }
2345 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2346 // Don't track further
2347 return false
2348 }
2349
2350 // If the dep is not considered to be in the same
2351 // apex, don't add it to filesInfo so that it is not
2352 // included in this APEX.
2353 // TODO(jiyong): move this to at the top of the
2354 // else-if clause for the indirect dependencies.
2355 // Currently, that's impossible because we would
2356 // like to record requiredNativeLibs even when
2357 // DepIsInSameAPex is false. We also shouldn't do
2358 // this for host.
2359 //
2360 // TODO(jiyong): explain why the same module is passed in twice.
2361 // Switching the first am to parent breaks lots of tests.
2362 if !android.IsDepInSameApex(ctx, am, am) {
2363 return false
2364 }
2365
2366 vctx.filesInfo = append(vctx.filesInfo, af)
2367 return true // track transitive dependencies
2368 } else if rm, ok := child.(*rust.Module); ok {
2369 af := apexFileForRustLibrary(ctx, rm)
2370 af.transitiveDep = true
2371 vctx.filesInfo = append(vctx.filesInfo, af)
2372 return true // track transitive dependencies
2373 }
2374 } else if cc.IsTestPerSrcDepTag(depTag) {
2375 if ch, ok := child.(*cc.Module); ok {
2376 af := apexFileForExecutable(ctx, ch)
2377 // Handle modules created as `test_per_src` variations of a single test module:
2378 // use the name of the generated test binary (`fileToCopy`) instead of the name
2379 // of the original test module (`depName`, shared by all `test_per_src`
2380 // variations of that module).
2381 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2382 // these are not considered transitive dep
2383 af.transitiveDep = false
2384 vctx.filesInfo = append(vctx.filesInfo, af)
2385 return true // track transitive dependencies
2386 }
2387 } else if cc.IsHeaderDepTag(depTag) {
2388 // nothing
2389 } else if java.IsJniDepTag(depTag) {
2390 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2391 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2392 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2393 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2394 }
2395 } else if rust.IsDylibDepTag(depTag) {
2396 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2397 af := apexFileForRustLibrary(ctx, rustm)
2398 af.transitiveDep = true
2399 vctx.filesInfo = append(vctx.filesInfo, af)
2400 return true // track transitive dependencies
2401 }
2402 } else if rust.IsRlibDepTag(depTag) {
2403 // Rlib is statically linked, but it might have shared lib
2404 // dependencies. Track them.
2405 return true
2406 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2407 // Add the contents of the bootclasspath fragment to the apex.
2408 switch child.(type) {
2409 case *java.Library, *java.SdkLibrary:
2410 javaModule := child.(javaModule)
2411 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2412 if !af.ok() {
2413 ctx.PropertyErrorf("bootclasspath_fragments",
2414 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2415 return false
2416 }
2417 vctx.filesInfo = append(vctx.filesInfo, af)
2418 return true // track transitive dependencies
2419 default:
2420 ctx.PropertyErrorf("bootclasspath_fragments",
2421 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2422 }
2423 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2424 // Add the contents of the systemserverclasspath fragment to the apex.
2425 switch child.(type) {
2426 case *java.Library, *java.SdkLibrary:
2427 af := apexFileForJavaModule(ctx, child.(javaModule))
2428 vctx.filesInfo = append(vctx.filesInfo, af)
2429 return true // track transitive dependencies
2430 default:
2431 ctx.PropertyErrorf("systemserverclasspath_fragments",
2432 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2433 }
2434 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2435 // nothing
2436 } else if depTag == android.DarwinUniversalVariantTag {
2437 // nothing
2438 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2439 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2440 }
2441 return false
2442}
2443
Jooyung Han862c0d62022-12-21 10:15:37 +09002444func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
2445 // TODO(b/263308293) remove this
2446 if a.properties.IsCoverageVariant {
2447 return false
2448 }
2449 // TODO(b/263308515) remove this
2450 if a.testApex {
2451 return false
2452 }
2453 // TODO(b/263309864) remove this
2454 if a.Host() {
2455 return false
2456 }
2457 if a.Device() && ctx.DeviceConfig().DeviceArch() == "" {
2458 return false
2459 }
2460 return true
2461}
2462
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002463// Creates build rules for an APEX. It consists of the following major steps:
2464//
2465// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2466// 2) traverse the dependency tree to collect apexFile structs from them.
2467// 3) some fields in apexBundle struct are configured
2468// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002469func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002470 ////////////////////////////////////////////////////////////////////////////////////////////
2471 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002472 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002473 return
2474 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002475 ////////////////////////////////////////////////////////////////////////////////////////////
2476 // 2) traverse the dependency tree to collect apexFile structs from them.
2477
braleeb0c1f0c2021-06-07 22:49:13 +08002478 // Collect the module directory for IDE info in java/jdeps.go.
2479 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2480
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002481 // TODO(jiyong): do this using WalkPayloadDeps
2482 // TODO(jiyong): make this clean!!!
Jooyung Han862c0d62022-12-21 10:15:37 +09002483 vctx := visitorContext{
2484 handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case),
2485 checkDuplicate: a.shouldCheckDuplicate(ctx),
2486 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002487 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
Jooyung Han862c0d62022-12-21 10:15:37 +09002488 vctx.normalizeFileInfo(ctx)
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002489 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002490 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002491 return
2492 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002493
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002494 ////////////////////////////////////////////////////////////////////////////////////////////
2495 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002496 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002497 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002498
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002499 a.setApexTypeAndSuffix(ctx)
2500 a.setPayloadFsType(ctx)
2501 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002502 if a.properties.ApexType != zipApex {
2503 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2504 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002505
2506 ////////////////////////////////////////////////////////////////////////////////////////////
2507 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002508 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002509 if a.properties.ApexType == flattenedApex {
2510 a.buildFlattenedApex(ctx)
2511 } else {
2512 a.buildUnflattenedApex(ctx)
2513 }
Jiyong Park956305c2020-01-09 12:32:06 +09002514 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002515 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002516
2517 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2518 if a.installable() {
2519 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2520 // along with other ordinary files. (Note that this is done by apexer for
2521 // non-flattened APEXes)
2522 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2523
2524 // Place the public key as apex_pubkey. This is also done by apexer for
2525 // non-flattened APEXes case.
2526 // TODO(jiyong): Why do we need this CP rule?
2527 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2528 ctx.Build(pctx, android.BuildParams{
2529 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002530 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002531 Output: copiedPubkey,
2532 })
2533 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2534 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002535}
2536
Paul Duffincc33ec82021-04-25 23:14:55 +01002537// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2538// the bootclasspath_fragment contributes to the apex.
2539func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2540 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2541 var filesToAdd []apexFile
2542
2543 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002544 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2545 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2546 dirInApex := filepath.Join("javalib", arch.String())
2547 for _, f := range files {
2548 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2549 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2550 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2551 filesToAdd = append(filesToAdd, af)
2552 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002553 }
2554 }
2555
satayev3db35472021-05-06 23:59:58 +01002556 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002557 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2558 filesToAdd = append(filesToAdd, *af)
2559 }
satayev3db35472021-05-06 23:59:58 +01002560
Ulya Trafimovichf5c548d2022-11-16 14:52:41 +00002561 pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2562 if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002563 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2564 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2565
2566 if pathOnHost != nil {
2567 // We need to copy the profile to a temporary path with the right filename because the apexer
2568 // will take the filename as is.
2569 ctx.Build(pctx, android.BuildParams{
2570 Rule: android.Cp,
2571 Input: pathOnHost,
2572 Output: tempPath,
2573 })
2574 } else {
2575 // At this point, the boot image profile cannot be generated. It is probably because the boot
2576 // image profile source file does not exist on the branch, or it is not available for the
2577 // current build target.
2578 // However, we cannot enforce the boot image profile to be generated because some build
2579 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2580 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2581 // only if the APEX is being built.
2582 ctx.Build(pctx, android.BuildParams{
2583 Rule: android.ErrorRule,
2584 Output: tempPath,
2585 Args: map[string]string{
2586 "error": "Boot image profile cannot be generated",
2587 },
2588 })
2589 }
2590
2591 androidMkModuleName := filepath.Base(pathInApex)
2592 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2593 filesToAdd = append(filesToAdd, af)
2594 }
2595
Paul Duffincc33ec82021-04-25 23:14:55 +01002596 return filesToAdd
2597}
2598
satayevb98371c2021-06-15 16:49:50 +01002599// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2600// the module contributes to the apex; or nil if the proto config was not generated.
2601func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2602 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2603 if !info.ClasspathFragmentProtoGenerated {
2604 return nil
2605 }
2606 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2607 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2608 return &af
satayev14e49132021-05-17 21:03:07 +01002609}
2610
Paul Duffincc33ec82021-04-25 23:14:55 +01002611// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2612// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002613func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2614 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2615
2616 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2617 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002618 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2619 if err != nil {
2620 ctx.ModuleErrorf("%s", err)
2621 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002622
2623 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2624 // bootclasspath_fragment.
2625 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2626 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002627}
2628
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002629///////////////////////////////////////////////////////////////////////////////////////////////////
2630// Factory functions
2631//
2632
2633func newApexBundle() *apexBundle {
2634 module := &apexBundle{}
2635
2636 module.AddProperties(&module.properties)
2637 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002638 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002639 module.AddProperties(&module.overridableProperties)
2640
2641 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2642 android.InitDefaultableModule(module)
2643 android.InitSdkAwareModule(module)
2644 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002645 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002646 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002647 return module
2648}
2649
Paul Duffineb8051d2021-10-18 17:49:39 +01002650func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002651 bundle := newApexBundle()
2652 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002653 return bundle
2654}
2655
2656// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2657// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002658func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002659 bundle := newApexBundle()
2660 bundle.testApex = true
2661 return bundle
2662}
2663
2664// apex packages other modules into an APEX file which is a packaging format for system-level
2665// components like binaries, shared libraries, etc.
2666func BundleFactory() android.Module {
2667 return newApexBundle()
2668}
2669
2670type Defaults struct {
2671 android.ModuleBase
2672 android.DefaultsModuleBase
2673}
2674
2675// apex_defaults provides defaultable properties to other apex modules.
2676func defaultsFactory() android.Module {
2677 return DefaultsFactory()
2678}
2679
2680func DefaultsFactory(props ...interface{}) android.Module {
2681 module := &Defaults{}
2682
2683 module.AddProperties(props...)
2684 module.AddProperties(
2685 &apexBundleProperties{},
2686 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002687 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002688 &overridableProperties{},
2689 )
2690
2691 android.InitDefaultsModule(module)
2692 return module
2693}
2694
2695type OverrideApex struct {
2696 android.ModuleBase
2697 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002698 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002699}
2700
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002701func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002702 // All the overrides happen in the base module.
2703}
2704
2705// override_apex is used to create an apex module based on another apex module by overriding some of
2706// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002707func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002708 m := &OverrideApex{}
2709
2710 m.AddProperties(&overridableProperties{})
2711
2712 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2713 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002714 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002715 return m
2716}
2717
Wei Li1c66fc72022-05-09 23:59:14 -07002718func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2719 if ctx.ModuleType() != "override_apex" {
2720 return
2721 }
2722
2723 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2724 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2725 if !baseApexExists {
2726 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2727 }
2728
2729 a, baseModuleIsApex := baseModule.(*apexBundle)
2730 if !baseModuleIsApex {
2731 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2732 }
2733 attrs, props := convertWithBp2build(a, ctx)
2734
Jingwen Chenc4c34e12022-11-29 12:07:45 +00002735 // We just want the name, not module reference.
2736 baseApexName := strings.TrimPrefix(baseApexModuleName, ":")
2737 attrs.Base_apex_name = &baseApexName
2738
Wei Li1c66fc72022-05-09 23:59:14 -07002739 for _, p := range o.GetProperties() {
2740 overridableProperties, ok := p.(*overridableProperties)
2741 if !ok {
2742 continue
2743 }
Wei Li40f98732022-05-20 22:08:11 -07002744
2745 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2746 // After it is converted in convertWithBp2build(baseApex, ctx),
2747 // the attrs.Manifest.Value.Label is the file path relative to the directory
2748 // of base apex. So the following code converts it to a label that looks like
2749 // <package of base apex>:<path of manifest file> if base apex and override
2750 // apex are not in the same package.
2751 baseApexPackage := ctx.OtherModuleDir(a)
2752 overrideApexPackage := ctx.ModuleDir()
2753 if baseApexPackage != overrideApexPackage {
2754 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2755 }
2756
Wei Li1c66fc72022-05-09 23:59:14 -07002757 // Key
2758 if overridableProperties.Key != nil {
2759 attrs.Key = bazel.LabelAttribute{}
2760 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2761 }
2762
2763 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002764 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002765 // If overridableProperties.Certificate is nil, clear this out as
2766 // well with zeroed structs, so the override_apex does not use the
2767 // base apex's certificate.
2768 attrs.Certificate = bazel.LabelAttribute{}
2769 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002770 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002771 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002772 }
2773
2774 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002775 if overridableProperties.Prebuilts != nil {
2776 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2777 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2778 }
Wei Li1c66fc72022-05-09 23:59:14 -07002779
2780 // Compressible
2781 if overridableProperties.Compressible != nil {
2782 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2783 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002784
2785 // Package name
2786 //
2787 // e.g. com.android.adbd's package name is com.android.adbd, but
2788 // com.google.android.adbd overrides the package name to com.google.android.adbd
2789 //
2790 // TODO: this can be overridden from the product configuration, see
2791 // getOverrideManifestPackageName and
2792 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2793 //
2794 // Instead of generating the BUILD files differently based on the product config
2795 // at the point of conversion, this should be handled by the BUILD file loading
2796 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2797 if overridableProperties.Package_name != "" {
2798 attrs.Package_name = &overridableProperties.Package_name
2799 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002800
2801 // Logging parent
2802 if overridableProperties.Logging_parent != "" {
2803 attrs.Logging_parent = &overridableProperties.Logging_parent
2804 }
Wei Li1c66fc72022-05-09 23:59:14 -07002805 }
2806
2807 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2808}
2809
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002810///////////////////////////////////////////////////////////////////////////////////////////////////
2811// Vality check routines
2812//
2813// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2814// certain conditions are not met.
2815//
2816// TODO(jiyong): move these checks to a separate go file.
2817
satayevad991492021-12-03 18:58:32 +00002818var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2819
Spandan Dasa5f39a12022-08-05 02:35:52 +00002820// 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 +09002821// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002822func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002823 if a.testApex || a.vndkApex {
2824 return
2825 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002826 // apexBundle::minSdkVersion reports its own errors.
2827 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002828 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002829}
2830
Albert Martineefabcf2022-03-21 20:11:16 +00002831// Returns apex's min_sdk_version string value, honoring overrides
2832func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2833 // Only override the minSdkVersion value on Apexes which already specify
2834 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2835 // min_sdk_version value is lower than the one to override with.
Colin Cross56534df2022-10-04 09:58:58 -07002836 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2837 if minApiLevel.IsNone() {
2838 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002839 }
2840
Colin Cross56534df2022-10-04 09:58:58 -07002841 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2842 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2843 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2844 minApiLevel = overrideApiLevel
2845 }
2846
2847 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002848}
2849
2850// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002851func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2852 return android.SdkSpec{
2853 Kind: android.SdkNone,
2854 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002855 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002856 }
2857}
2858
Albert Martineefabcf2022-03-21 20:11:16 +00002859// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002860func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002861 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2862}
2863
2864// Construct ApiLevel object from min_sdk_version string value
2865func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2866 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002867 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002868 }
Albert Martineefabcf2022-03-21 20:11:16 +00002869 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002870 if err != nil {
2871 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2872 return android.NoneApiLevel
2873 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002874 return apiLevel
2875}
2876
2877// Ensures that a lib providing stub isn't statically linked
2878func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2879 // Practically, we only care about regular APEXes on the device.
2880 if ctx.Host() || a.testApex || a.vndkApex {
2881 return
2882 }
2883
2884 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2885
2886 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2887 if ccm, ok := to.(*cc.Module); ok {
2888 apexName := ctx.ModuleName()
2889 fromName := ctx.OtherModuleName(from)
2890 toName := ctx.OtherModuleName(to)
2891
2892 // If `to` is not actually in the same APEX as `from` then it does not need
2893 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002894 //
2895 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002896 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2897 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2898 return false
2899 }
2900
2901 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2902 // exception to this rule. It can't make the static dependencies dynamic
2903 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002904 // Same rule should be applied to linkerconfig, because it should be executed
2905 // only with static linked libraries before linker is available with ld.config.txt
2906 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002907 return false
2908 }
2909
2910 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2911 if isStubLibraryFromOtherApex && !externalDep {
2912 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2913 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2914 }
2915
2916 }
2917 return true
2918 })
2919}
2920
satayevb98371c2021-06-15 16:49:50 +01002921// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002922func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2923 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002924 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002925 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2926 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002927 if a.UsePlatformApis() {
2928 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2929 }
Daniel Norman69109112021-12-02 12:52:42 -08002930 if a.SocSpecific() || a.DeviceSpecific() {
2931 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2932 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002933 if a.FutureUpdatable() {
2934 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2935 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002936 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002937 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002938 }
2939}
2940
satayevb98371c2021-06-15 16:49:50 +01002941// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2942func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2943 ctx.VisitDirectDeps(func(module android.Module) {
2944 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2945 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2946 if !info.ClasspathFragmentProtoGenerated {
2947 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2948 }
2949 }
2950 })
2951}
2952
2953// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002954func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002955 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2956 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002957 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2958 tag := ctx.OtherModuleDependencyTag(module)
2959 switch tag {
2960 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002961 if m, ok := module.(interface {
2962 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2963 }); ok {
2964 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002965 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2966 }
2967 }
2968 }
2969 })
2970}
2971
satayevb98371c2021-06-15 16:49:50 +01002972// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002973func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2974 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2975 if ctx.Host() || a.testApex || a.vndkApex {
2976 return
2977 }
2978
2979 // Because APEXes targeting other than system/system_ext partitions can't set
2980 // apex_available, we skip checks for these APEXes
2981 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2982 return
2983 }
2984
2985 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2986 // Requiring them and their transitive depencies with apex_available is not right
2987 // because they just add noise.
2988 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2989 return
2990 }
2991
2992 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2993 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2994 if externalDep {
2995 return false
2996 }
2997
2998 apexName := ctx.ModuleName()
2999 fromName := ctx.OtherModuleName(from)
3000 toName := ctx.OtherModuleName(to)
3001
3002 // If `to` is not actually in the same APEX as `from` then it does not need
3003 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00003004 //
3005 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003006 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
3007 // As soon as the dependency graph crosses the APEX boundary, don't go
3008 // further.
3009 return false
3010 }
3011
3012 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
3013 return true
3014 }
Jiyong Park767dbd92021-03-04 13:03:10 +09003015 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
3016 "\n\nDependency path:%s\n\n"+
3017 "Consider adding %q to 'apex_available' property of %q",
3018 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003019 // Visit this module's dependencies to check and report any issues with their availability.
3020 return true
3021 })
3022}
3023
Jiyong Park192600a2021-08-03 07:52:17 +00003024// checkStaticExecutable ensures that executables in an APEX are not static.
3025func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09003026 // No need to run this for host APEXes
3027 if ctx.Host() {
3028 return
3029 }
3030
Jiyong Park192600a2021-08-03 07:52:17 +00003031 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3032 if ctx.OtherModuleDependencyTag(module) != executableTag {
3033 return
3034 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09003035
3036 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00003037 apex := a.ApexVariationName()
3038 exec := ctx.OtherModuleName(module)
3039 if isStaticExecutableAllowed(apex, exec) {
3040 return
3041 }
3042 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
3043 }
3044 })
3045}
3046
3047// A small list of exceptions where static executables are allowed in APEXes.
3048func isStaticExecutableAllowed(apex string, exec string) bool {
3049 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003050 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00003051 "linker",
3052 "linkerconfig",
3053 },
3054 }
3055 execNames, ok := m[apex]
3056 return ok && android.InList(exec, execNames)
3057}
3058
braleeb0c1f0c2021-06-07 22:49:13 +08003059// Collect information for opening IDE project files in java/jdeps.go.
3060func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09003061 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
3062 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
3063 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08003064 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
3065}
3066
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003067var (
3068 apexAvailBaseline = makeApexAvailableBaseline()
3069 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
3070)
3071
Colin Cross440e0d02020-06-11 11:32:11 -07003072func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003073 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003074 moduleName = normalizeModuleName(moduleName)
3075
Colin Cross440e0d02020-06-11 11:32:11 -07003076 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003077 return true
3078 }
3079
3080 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07003081 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003082 return true
3083 }
3084
3085 return false
3086}
3087
3088func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09003089 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
3090 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00003091 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09003092 if strings.HasPrefix(moduleName, "libclang_rt.") {
3093 // This module has many arch variants that depend on the product being built.
3094 // We don't want to list them all
3095 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003096 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003097 if strings.HasPrefix(moduleName, "androidx.") {
3098 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3099 moduleName = "androidx"
3100 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003101 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003102}
3103
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003104// Transform the map of apex -> modules to module -> apexes.
3105func invertApexBaseline(m map[string][]string) map[string][]string {
3106 r := make(map[string][]string)
3107 for apex, modules := range m {
3108 for _, module := range modules {
3109 r[module] = append(r[module], apex)
3110 }
3111 }
3112 return r
3113}
3114
3115// Retrieve the baseline of apexes to which the supplied module belongs.
3116func BaselineApexAvailable(moduleName string) []string {
3117 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3118}
3119
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003120// This is a map from apex to modules, which overrides the apex_available setting for that
3121// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003122// TODO(b/147364041): remove this
3123func makeApexAvailableBaseline() map[string][]string {
3124 // The "Module separator"s below are employed to minimize merge conflicts.
3125 m := make(map[string][]string)
3126 //
3127 // Module separator
3128 //
3129 m["com.android.appsearch"] = []string{
3130 "icing-java-proto-lite",
3131 "libprotobuf-java-lite",
3132 }
3133 //
3134 // Module separator
3135 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003136 m["com.android.btservices"] = []string{
William Escande89bca3f2022-06-28 18:03:30 -07003137 // empty
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003138 }
3139 //
3140 // Module separator
3141 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003142 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3143 //
3144 // Module separator
3145 //
3146 m["com.android.extservices"] = []string{
3147 "error_prone_annotations",
3148 "ExtServices-core",
3149 "ExtServices",
3150 "libtextclassifier-java",
3151 "libz_current",
3152 "textclassifier-statsd",
3153 "TextClassifierNotificationLibNoManifest",
3154 "TextClassifierServiceLibNoManifest",
3155 }
3156 //
3157 // Module separator
3158 //
3159 m["com.android.neuralnetworks"] = []string{
3160 "android.hardware.neuralnetworks@1.0",
3161 "android.hardware.neuralnetworks@1.1",
3162 "android.hardware.neuralnetworks@1.2",
3163 "android.hardware.neuralnetworks@1.3",
3164 "android.hidl.allocator@1.0",
3165 "android.hidl.memory.token@1.0",
3166 "android.hidl.memory@1.0",
3167 "android.hidl.safe_union@1.0",
3168 "libarect",
3169 "libbuildversion",
3170 "libmath",
3171 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003172 }
3173 //
3174 // Module separator
3175 //
3176 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003177 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003178 }
3179 //
3180 // Module separator
3181 //
3182 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003183 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003184 }
3185 //
3186 // Module separator
3187 //
3188 m["com.android.mediaprovider"] = []string{
3189 "MediaProvider",
3190 "MediaProviderGoogle",
3191 "fmtlib_ndk",
3192 "libbase_ndk",
3193 "libfuse",
3194 "libfuse_jni",
3195 }
3196 //
3197 // Module separator
3198 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003199 m["com.android.runtime"] = []string{
3200 "bionic_libc_platform_headers",
3201 "libarm-optimized-routines-math",
3202 "libc_aeabi",
3203 "libc_bionic",
3204 "libc_bionic_ndk",
3205 "libc_bootstrap",
3206 "libc_common",
3207 "libc_common_shared",
3208 "libc_common_static",
3209 "libc_dns",
3210 "libc_dynamic_dispatch",
3211 "libc_fortify",
3212 "libc_freebsd",
3213 "libc_freebsd_large_stack",
3214 "libc_gdtoa",
3215 "libc_init_dynamic",
3216 "libc_init_static",
3217 "libc_jemalloc_wrapper",
3218 "libc_netbsd",
3219 "libc_nomalloc",
3220 "libc_nopthread",
3221 "libc_openbsd",
3222 "libc_openbsd_large_stack",
3223 "libc_openbsd_ndk",
3224 "libc_pthread",
3225 "libc_static_dispatch",
3226 "libc_syscalls",
3227 "libc_tzcode",
3228 "libc_unwind_static",
3229 "libdebuggerd",
3230 "libdebuggerd_common_headers",
3231 "libdebuggerd_handler_core",
3232 "libdebuggerd_handler_fallback",
3233 "libdl_static",
3234 "libjemalloc5",
3235 "liblinker_main",
3236 "liblinker_malloc",
3237 "liblz4",
3238 "liblzma",
3239 "libprocinfo",
3240 "libpropertyinfoparser",
3241 "libscudo",
3242 "libstdc++",
3243 "libsystemproperties",
3244 "libtombstoned_client_static",
3245 "libunwindstack",
3246 "libz",
3247 "libziparchive",
3248 }
3249 //
3250 // Module separator
3251 //
3252 m["com.android.tethering"] = []string{
3253 "android.hardware.tetheroffload.config-V1.0-java",
3254 "android.hardware.tetheroffload.control-V1.0-java",
3255 "android.hidl.base-V1.0-java",
3256 "libcgrouprc",
3257 "libcgrouprc_format",
3258 "libtetherutilsjni",
3259 "libvndksupport",
3260 "net-utils-framework-common",
3261 "netd_aidl_interface-V3-java",
3262 "netlink-client",
3263 "networkstack-aidl-interfaces-java",
3264 "tethering-aidl-interfaces-java",
3265 "TetheringApiCurrentLib",
3266 }
3267 //
3268 // Module separator
3269 //
3270 m["com.android.wifi"] = []string{
3271 "PlatformProperties",
3272 "android.hardware.wifi-V1.0-java",
3273 "android.hardware.wifi-V1.0-java-constants",
3274 "android.hardware.wifi-V1.1-java",
3275 "android.hardware.wifi-V1.2-java",
3276 "android.hardware.wifi-V1.3-java",
3277 "android.hardware.wifi-V1.4-java",
3278 "android.hardware.wifi.hostapd-V1.0-java",
3279 "android.hardware.wifi.hostapd-V1.1-java",
3280 "android.hardware.wifi.hostapd-V1.2-java",
3281 "android.hardware.wifi.supplicant-V1.0-java",
3282 "android.hardware.wifi.supplicant-V1.1-java",
3283 "android.hardware.wifi.supplicant-V1.2-java",
3284 "android.hardware.wifi.supplicant-V1.3-java",
3285 "android.hidl.base-V1.0-java",
3286 "android.hidl.manager-V1.0-java",
3287 "android.hidl.manager-V1.1-java",
3288 "android.hidl.manager-V1.2-java",
3289 "bouncycastle-unbundled",
3290 "dnsresolver_aidl_interface-V2-java",
3291 "error_prone_annotations",
3292 "framework-wifi-pre-jarjar",
3293 "framework-wifi-util-lib",
3294 "ipmemorystore-aidl-interfaces-V3-java",
3295 "ipmemorystore-aidl-interfaces-java",
3296 "ksoap2",
3297 "libnanohttpd",
3298 "libwifi-jni",
3299 "net-utils-services-common",
3300 "netd_aidl_interface-V2-java",
3301 "netd_aidl_interface-unstable-java",
3302 "netd_event_listener_interface-java",
3303 "netlink-client",
3304 "networkstack-client",
3305 "services.net",
3306 "wifi-lite-protos",
3307 "wifi-nano-protos",
3308 "wifi-service-pre-jarjar",
3309 "wifi-service-resources",
3310 }
3311 //
3312 // Module separator
3313 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003314 m["com.android.os.statsd"] = []string{
3315 "libstatssocket",
3316 }
3317 //
3318 // Module separator
3319 //
3320 m[android.AvailableToAnyApex] = []string{
3321 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3322 "androidx",
3323 "androidx-constraintlayout_constraintlayout",
3324 "androidx-constraintlayout_constraintlayout-nodeps",
3325 "androidx-constraintlayout_constraintlayout-solver",
3326 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3327 "com.google.android.material_material",
3328 "com.google.android.material_material-nodeps",
3329
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003330 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003331 "libprofile-clang-extras",
3332 "libprofile-clang-extras_ndk",
3333 "libprofile-extras",
3334 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003335 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003336 }
3337 return m
3338}
3339
3340func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003341 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3342 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003343}
3344
Spandan Dasf14e2542021-11-12 00:01:37 +00003345func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3346 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3347 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003348 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003349 With("name", jar).
3350 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3351 Because(jar +
3352 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003353 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003354 " 1. If the offending code is from a statically linked library, consider " +
3355 "removing that dependency and using an alternative already in the " +
3356 "bootclasspath, or perhaps a shared library." +
3357 " 2. Move the offending code into an allowed package.\n" +
3358 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3359 "health implications of bundling that code, particularly if the offending jar " +
3360 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003361
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003362 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003363 }
3364 return rules
3365}
3366
Anton Hanssone1b18362021-12-23 15:05:38 +00003367// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003368// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003369func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003370 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003371 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003372 "android.net.ssl",
3373 "com.android.org.conscrypt",
3374 },
Wei Li40f98732022-05-20 22:08:11 -07003375 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003376 "android.media",
3377 },
3378 }
3379}
3380
Anton Hanssone1b18362021-12-23 15:05:38 +00003381// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003382// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003383func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003384 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003385 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003386 "android.provider",
3387 },
Wei Li40f98732022-05-20 22:08:11 -07003388 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003389 "android.permission",
3390 "android.app.role",
3391 "com.android.permission",
3392 "com.android.role",
3393 },
Wei Li40f98732022-05-20 22:08:11 -07003394 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003395 "android.os.ext",
3396 },
Wei Li40f98732022-05-20 22:08:11 -07003397 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003398 "android.app",
3399 "android.os",
3400 "android.util",
3401 "com.android.internal.statsd",
3402 "com.android.server.stats",
3403 },
Wei Li40f98732022-05-20 22:08:11 -07003404 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003405 "com.android.server.wifi",
3406 "com.android.wifi.x",
3407 "android.hardware.wifi",
3408 "android.net.wifi",
3409 },
Wei Li40f98732022-05-20 22:08:11 -07003410 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003411 "android.net",
3412 },
3413 }
3414}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003415
3416// For Bazel / bp2build
3417
3418type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003419 Manifest bazel.LabelAttribute
3420 Android_manifest bazel.LabelAttribute
3421 File_contexts bazel.LabelAttribute
3422 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003423 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3424 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Yu Liu4ae55d12022-01-05 17:17:23 -08003425 Min_sdk_version *string
3426 Updatable bazel.BoolAttribute
3427 Installable bazel.BoolAttribute
3428 Binaries bazel.LabelListAttribute
3429 Prebuilts bazel.LabelListAttribute
3430 Native_shared_libs_32 bazel.LabelListAttribute
3431 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003432 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003433 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003434 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003435 Tests bazel.LabelListAttribute
Jingwen Chenc4c34e12022-11-29 12:07:45 +00003436 Base_apex_name *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003437}
3438
3439type convertedNativeSharedLibs struct {
3440 Native_shared_libs_32 bazel.LabelListAttribute
3441 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003442}
3443
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003444// ConvertWithBp2build performs bp2build conversion of an apex
3445func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003446 // We only convert apex and apex_test modules at this time
3447 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003448 return
3449 }
3450
Wei Li1c66fc72022-05-09 23:59:14 -07003451 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003452 commonAttrs := android.CommonAttributes{
3453 Name: a.Name(),
3454 }
3455 if a.testApex {
3456 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3457 }
3458 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003459}
3460
3461func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003462 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003463 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003464
3465 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003466 if a.properties.AndroidManifest != nil {
3467 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003468 }
3469
3470 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003471 if a.properties.File_contexts == nil {
3472 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3473 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3474 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3475 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003476 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003477 } else {
3478 // File_contexts is a file
3479 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003480 }
3481
Albert Martineefabcf2022-03-21 20:11:16 +00003482 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3483 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003484 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003485 if a.properties.Min_sdk_version != nil {
3486 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003487 }
3488
3489 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003490 if a.overridableProperties.Key != nil {
3491 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003492 }
3493
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003494 // Certificate
3495 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003496
Yu Liu4ae55d12022-01-05 17:17:23 -08003497 nativeSharedLibs := &convertedNativeSharedLibs{
3498 Native_shared_libs_32: bazel.LabelListAttribute{},
3499 Native_shared_libs_64: bazel.LabelListAttribute{},
3500 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003501
3502 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3503 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3504 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3505 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3506 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003507 if a.CompileMultilib() != nil {
3508 compileMultilib = *a.CompileMultilib()
3509 }
3510
3511 // properties.Native_shared_libs is treated as "both"
3512 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3513 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3514 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3515 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3516 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003517
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003518 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003519 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3520 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3521
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003522 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003523 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003524
Yu Liu4c212ce2022-10-14 12:20:20 -07003525 var testsAttrs bazel.LabelListAttribute
3526 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3527 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3528 testsAttrs = bazel.MakeLabelListAttribute(tests)
3529 }
3530
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003531 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003532 if a.properties.Updatable != nil {
3533 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003534 }
3535
3536 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003537 if a.properties.Installable != nil {
3538 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003539 }
3540
Wei Lif034cb42022-01-19 15:54:31 -08003541 var compressibleAttribute bazel.BoolAttribute
3542 if a.overridableProperties.Compressible != nil {
3543 compressibleAttribute.Value = a.overridableProperties.Compressible
3544 }
3545
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003546 var packageName *string
3547 if a.overridableProperties.Package_name != "" {
3548 packageName = &a.overridableProperties.Package_name
3549 }
3550
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003551 var loggingParent *string
3552 if a.overridableProperties.Logging_parent != "" {
3553 loggingParent = &a.overridableProperties.Logging_parent
3554 }
3555
Wei Li1c66fc72022-05-09 23:59:14 -07003556 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003557 Manifest: manifestLabelAttribute,
3558 Android_manifest: androidManifestLabelAttribute,
3559 File_contexts: fileContextsLabelAttribute,
3560 Min_sdk_version: minSdkVersion,
3561 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003562 Certificate: certificate,
3563 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003564 Updatable: updatableAttribute,
3565 Installable: installableAttribute,
3566 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3567 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3568 Binaries: binariesLabelListAttribute,
3569 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003570 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003571 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003572 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003573 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003574 }
3575
3576 props := bazel.BazelTargetModuleProperties{
3577 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003578 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003579 }
3580
Wei Li1c66fc72022-05-09 23:59:14 -07003581 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003582}
Yu Liu4ae55d12022-01-05 17:17:23 -08003583
3584// The following conversions are based on this table where the rows are the compile_multilib
3585// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3586// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3587// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3588// should not be compiled.
3589// multib/compile_multilib, 32, 64, both, first
3590// 32, 32/32, none/none, 32/32, none/32
3591// 64, none/none, 64/none, 64/none, 64/none
3592// both, 32/32, 64/none, 32&64/32, 64/32
3593// first, 32/32, 64/none, 64/32, 64/32
3594
3595func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3596 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3597 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3598 switch compileMultilb {
3599 case "both", "32":
3600 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3601 case "first":
3602 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3603 case "64":
3604 // Incompatible, ignore
3605 default:
3606 invalidCompileMultilib(ctx, compileMultilb)
3607 }
3608}
3609
3610func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3611 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3612 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3613 switch compileMultilb {
3614 case "both", "64", "first":
3615 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3616 case "32":
3617 // Incompatible, ignore
3618 default:
3619 invalidCompileMultilib(ctx, compileMultilb)
3620 }
3621}
3622
3623func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3624 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3625 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3626 switch compileMultilb {
3627 case "both":
3628 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3629 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3630 case "first":
3631 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3632 case "32":
3633 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3634 case "64":
3635 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3636 default:
3637 invalidCompileMultilib(ctx, compileMultilb)
3638 }
3639}
3640
3641func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3642 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3643 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3644 switch compileMultilb {
3645 case "both", "first":
3646 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3647 case "32":
3648 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3649 case "64":
3650 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3651 default:
3652 invalidCompileMultilib(ctx, compileMultilb)
3653 }
3654}
3655
3656func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3657 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3658 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3659}
3660
3661func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3662 list := bazel.LabelListAttribute{}
3663 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3664 nativeSharedLibs.Native_shared_libs_32.Append(list)
3665}
3666
3667func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3668 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3669 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3670}
3671
3672func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3673 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3674 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3675}
3676
3677func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3678 labelListAttr *bazel.LabelListAttribute) {
3679 list := bazel.LabelListAttribute{}
3680 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3681 labelListAttr.Append(list)
3682}
3683
3684func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3685 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3686}