blob: bc2a136b507799fd255ccd405a5a05d7e2782b84 [file] [log] [blame]
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090015// package apex implements build rules for creating the APEX files which are container for
16// lower-level system components. See https://source.android.com/devices/tech/ota/apex
Jiyong Park48ca7dc2018-10-10 14:01:00 +090017package apex
18
19import (
20 "fmt"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090021 "path/filepath"
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +000022 "regexp"
Jiyong Parkab3ceb32018-10-10 14:05:29 +090023 "sort"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090024 "strings"
25
Yu Liu4c212ce2022-10-14 12:20:20 -070026 "android/soong/bazel/cquery"
27
Jiyong Park48ca7dc2018-10-10 14:01:00 +090028 "github.com/google/blueprint"
Alex Light778127a2019-02-27 14:19:50 -080029 "github.com/google/blueprint/bootstrap"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090030 "github.com/google/blueprint/proptools"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070031
32 "android/soong/android"
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -040033 "android/soong/bazel"
markchien2f59ec92020-09-02 16:23:38 +080034 "android/soong/bpf"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070035 "android/soong/cc"
36 prebuilt_etc "android/soong/etc"
Jiyong Park12a719c2021-01-07 15:31:24 +090037 "android/soong/filesystem"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070038 "android/soong/java"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090039 "android/soong/multitree"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070040 "android/soong/python"
Jiyong Park99644e92020-11-17 22:21:02 +090041 "android/soong/rust"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070042 "android/soong/sh"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090043)
44
Jiyong Park8e6d52f2020-11-19 14:37:47 +090045func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000046 registerApexBuildComponents(android.InitRegistrationContext)
47}
Jiyong Park8e6d52f2020-11-19 14:37:47 +090048
Paul Duffin667893c2021-03-09 22:34:13 +000049func registerApexBuildComponents(ctx android.RegistrationContext) {
50 ctx.RegisterModuleType("apex", BundleFactory)
Yu Liu4c212ce2022-10-14 12:20:20 -070051 ctx.RegisterModuleType("apex_test", TestApexBundleFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000052 ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
53 ctx.RegisterModuleType("apex_defaults", defaultsFactory)
54 ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
Wei Li1c66fc72022-05-09 23:59:14 -070055 ctx.RegisterModuleType("override_apex", OverrideApexFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000056 ctx.RegisterModuleType("apex_set", apexSetFactory)
57
Paul Duffin5dda3e32021-05-05 14:13:27 +010058 ctx.PreArchMutators(registerPreArchMutators)
Paul Duffin667893c2021-03-09 22:34:13 +000059 ctx.PreDepsMutators(RegisterPreDepsMutators)
60 ctx.PostDepsMutators(RegisterPostDepsMutators)
Jiyong Park8e6d52f2020-11-19 14:37:47 +090061}
62
Paul Duffin5dda3e32021-05-05 14:13:27 +010063func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
64 ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
65}
66
Jiyong Park8e6d52f2020-11-19 14:37:47 +090067func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
68 ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
69 ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
70}
71
72func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
Paul Duffin949abc02020-12-08 10:34:30 +000073 ctx.TopDown("apex_info", apexInfoMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090074 ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
75 ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
76 ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
Paul Duffin28bf7ee2021-05-12 16:41:35 +010077 // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
78 // it should create a platform variant.
79 ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090080 ctx.BottomUp("apex", apexMutator).Parallel()
81 ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
82 ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
Dennis Shene2ed70c2023-01-11 14:15:43 +000083 ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
Spandan Das66773252022-01-15 00:23:18 +000084 // Register after apex_info mutator so that it can use ApexVariationName
85 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090086}
87
88type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090089 // Json manifest file describing meta info of this APEX bundle. Refer to
90 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090091 Manifest *string `android:"path"`
92
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090093 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
94 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090095 AndroidManifest *string `android:"path"`
96
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090097 // Determines the file contexts file for setting the security contexts to files in this APEX
98 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
99 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900100 File_contexts *string `android:"path"`
101
Jiyong Park038e8522021-12-13 23:56:35 +0900102 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
103 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
104 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
105 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
106 // capability. If this property is not set, or a file is missing in the file, default config
107 // is used.
108 Canned_fs_config *string `android:"path"`
109
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900110 ApexNativeDependencies
111
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900112 Multilib apexMultilibProperties
113
Sundong Ahn80c04892021-11-23 00:57:19 +0000114 // List of sh binaries that are embedded inside this APEX bundle.
115 Sh_binaries []string
116
Paul Duffin3abc1742021-03-15 19:32:23 +0000117 // List of platform_compat_config files that are embedded inside this APEX bundle.
118 Compat_configs []string
119
Jiyong Park12a719c2021-01-07 15:31:24 +0900120 // List of filesystem images that are embedded inside this APEX bundle.
121 Filesystems []string
122
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900123 // Whether this APEX is considered updatable or not. When set to true, this will enforce
124 // additional rules for making sure that the APEX is truly updatable. To be updatable,
125 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000126 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900127 Updatable *bool
128
Jiyong Parkf4020582021-11-29 12:37:10 +0900129 // Marks that this APEX is designed to be updatable in the future, although it's not
130 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
131 // updatable APEXes. Currently, this disables the size optimization, so that the size of
132 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
133 // false.
134 Future_updatable *bool
135
Jiyong Park1bc84122021-06-22 20:23:05 +0900136 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
137 // false`. Default is false.
138 Platform_apis *bool
139
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900140 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
141 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900142 Installable *bool
143
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900144 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
145 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
146 Use_vndk_as_stable *bool
147
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900148 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
149 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
150 // container. When set to zip, contents are stored in a zip container directly. This type is
151 // mostly for host-side debugging. When set to both, the two types are both built. Default
152 // is 'image'.
153 Payload_type *string
154
Huang Jianan13cac632021-08-02 15:02:17 +0800155 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
156 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900157 Payload_fs_type *string
158
159 // For telling the APEX to ignore special handling for system libraries such as bionic.
160 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900161 Ignore_system_library_special_case *bool
162
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100163 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100164 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100165 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900166
167 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
168 // used in tests.
169 Test_only_unsigned_payload *bool
170
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000171 // Whenever apex should be compressed, regardless of product flag used. Should be only
172 // used in tests.
173 Test_only_force_compression *bool
174
Jooyung Han09c11ad2021-10-27 03:45:31 +0900175 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
176 // with the tool to sign payload contents.
177 Custom_sign_tool *string
178
Dennis Shenaf41bc12022-08-03 16:46:43 +0000179 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
180 // in a special way that include the digest of the lib file under /lib(64)?
181 Dynamic_common_lib_apex *bool
182
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100183 // Canonical name of this APEX bundle. Used to determine the path to the
184 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
185 // apex mutator variations. For override_apex modules, this is the name of the
186 // overridden base module.
187 ApexVariationName string `blueprint:"mutated"`
188
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900189 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900190
191 // List of sanitizer names that this APEX is enabled for
192 SanitizerNames []string `blueprint:"mutated"`
193
194 PreventInstall bool `blueprint:"mutated"`
195
196 HideFromMake bool `blueprint:"mutated"`
197
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900198 // Internal package method for this APEX. When payload_type is image, this can be either
199 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
200 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900201 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900202}
203
204type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900205 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900206 Native_shared_libs []string
207
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900208 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900209 Jni_libs []string
210
Colin Cross70572ed2022-11-02 13:14:20 -0700211 // List of rust dyn libraries that are embedded inside this APEX.
Jiyong Park99644e92020-11-17 22:21:02 +0900212 Rust_dyn_libs []string
213
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900214 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900215 Binaries []string
216
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900217 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900218 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900219
220 // List of filesystem images that are embedded inside this APEX bundle.
221 Filesystems []string
Colin Cross70572ed2022-11-02 13:14:20 -0700222
223 // List of native libraries to exclude from this APEX.
224 Exclude_native_shared_libs []string
225
226 // List of JNI libraries to exclude from this APEX.
227 Exclude_jni_libs []string
228
229 // List of rust dyn libraries to exclude from this APEX.
230 Exclude_rust_dyn_libs []string
231
232 // List of native executables to exclude from this APEX.
233 Exclude_binaries []string
234
235 // List of native tests to exclude from this APEX.
236 Exclude_tests []string
237
238 // List of filesystem images to exclude from this APEX bundle.
239 Exclude_filesystems []string
240}
241
242// Merge combines another ApexNativeDependencies into this one
243func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
244 a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
245 a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
246 a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
247 a.Binaries = append(a.Binaries, b.Binaries...)
248 a.Tests = append(a.Tests, b.Tests...)
249 a.Filesystems = append(a.Filesystems, b.Filesystems...)
250
251 a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
252 a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
253 a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
254 a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
255 a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
256 a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900257}
258
259type apexMultilibProperties struct {
260 // Native dependencies whose compile_multilib is "first"
261 First ApexNativeDependencies
262
263 // Native dependencies whose compile_multilib is "both"
264 Both ApexNativeDependencies
265
266 // Native dependencies whose compile_multilib is "prefer32"
267 Prefer32 ApexNativeDependencies
268
269 // Native dependencies whose compile_multilib is "32"
270 Lib32 ApexNativeDependencies
271
272 // Native dependencies whose compile_multilib is "64"
273 Lib64 ApexNativeDependencies
274}
275
276type apexTargetBundleProperties struct {
277 Target struct {
278 // Multilib properties only for android.
279 Android struct {
280 Multilib apexMultilibProperties
281 }
282
283 // Multilib properties only for host.
284 Host struct {
285 Multilib apexMultilibProperties
286 }
287
288 // Multilib properties only for host linux_bionic.
289 Linux_bionic struct {
290 Multilib apexMultilibProperties
291 }
292
293 // Multilib properties only for host linux_glibc.
294 Linux_glibc struct {
295 Multilib apexMultilibProperties
296 }
297 }
298}
299
Jiyong Park59140302020-12-14 18:44:04 +0900300type apexArchBundleProperties struct {
301 Arch struct {
302 Arm struct {
303 ApexNativeDependencies
304 }
305 Arm64 struct {
306 ApexNativeDependencies
307 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700308 Riscv64 struct {
309 ApexNativeDependencies
310 }
Jiyong Park59140302020-12-14 18:44:04 +0900311 X86 struct {
312 ApexNativeDependencies
313 }
314 X86_64 struct {
315 ApexNativeDependencies
316 }
317 }
318}
319
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900320// These properties can be used in override_apex to override the corresponding properties in the
321// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900322type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900323 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900324 Apps []string
325
Daniel Norman5a3ce132021-08-26 15:44:43 -0700326 // List of prebuilt files that are embedded inside this APEX bundle.
327 Prebuilts []string
328
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900329 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900330 Rros []string
331
markchien7c803b82021-08-26 22:10:06 +0800332 // List of BPF programs inside this APEX bundle.
333 Bpfs []string
334
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900335 // List of bootclasspath fragments that are embedded inside this APEX bundle.
336 Bootclasspath_fragments []string
337
338 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
339 Systemserverclasspath_fragments []string
340
341 // List of java libraries that are embedded inside this APEX bundle.
342 Java_libs []string
343
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900344 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
345 // Soong). This does not completely prevent installation of the overridden binaries, but if
346 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
347 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900348 Overrides []string
349
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900350 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900351 Logging_parent string
352
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900353 // Apex Container package name. Override value for attribute package:name in
354 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900355 Package_name string
356
357 // A txt file containing list of files that are allowed to be included in this APEX.
358 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700359
360 // Name of the apex_key module that provides the private key to sign this APEX bundle.
361 Key *string
362
363 // Specifies the certificate and the private key to sign the zip container of this APEX. If
364 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
365 // as the certificate and the private key, respectively. If this is ":module", then the
366 // certificate and the private key are provided from the android_app_certificate module
367 // named "module".
368 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400369
370 // Whether this APEX can be compressed or not. Setting this property to false means this
371 // APEX will never be compressed. When set to true, APEX will be compressed if other
372 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
373 // Default: false.
374 Compressible *bool
Dennis Shene2ed70c2023-01-11 14:15:43 +0000375
376 // Trim against a specific Dynamic Common Lib APEX
377 Trim_against *string
zhidou133c55b2023-01-31 19:34:10 +0000378
379 // The minimum SDK version that this APEX must support at minimum. This is usually set to
380 // the SDK version that the APEX was first introduced.
381 Min_sdk_version *string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900382}
383
384type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900385 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900386 android.ModuleBase
387 android.DefaultableModuleBase
388 android.OverridableModuleBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400389 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900390 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900391
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900392 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900393 properties apexBundleProperties
394 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900395 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900396 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900397 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900398
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900399 ///////////////////////////////////////////////////////////////////////////////////////////
400 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900401
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900402 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800403 publicKeyFile android.Path
404 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900405
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900406 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800407 containerCertificateFile android.Path
408 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900409
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900410 // Flags for special variants of APEX
411 testApex bool
412 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900413
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900414 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
415 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900416 primaryApexType bool
417
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900418 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900419 suffix string
420
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900421 // File system type of apex_payload.img
422 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900423
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900424 // Whether to create symlink to the system file instead of having a file inside the apex or
425 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900426 linkToSystemLib bool
427
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900428 // List of files to be included in this APEX. This is filled in the first part of
429 // GenerateAndroidBuildActions.
430 filesInfo []apexFile
431
Jingwen Chen29743c82023-01-25 17:49:46 +0000432 // List of other module names that should be installed when this APEX gets installed (LOCAL_REQUIRED_MODULES).
433 makeModulesToInstall []string
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900434
435 ///////////////////////////////////////////////////////////////////////////////////////////
436 // Outputs (final and intermediates)
437
438 // Processed apex manifest in JSONson format (for Q)
439 manifestJsonOut android.WritablePath
440
441 // Processed apex manifest in PB format (for R+)
442 manifestPbOut android.WritablePath
443
444 // Processed file_contexts files
445 fileContexts android.WritablePath
446
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900447 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900448 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900449 outputFile android.WritablePath
450
Jooyung Hana6d36672022-02-24 13:58:07 +0900451 // The built uncompressed .apex file.
452 outputApexFile android.WritablePath
453
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900454 // The built APEX file in app bundle format. This file is not directly installed to the
455 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
456 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
457 // system) to be merged into a single app bundle file that Play accepts. See
458 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
459 bundleModuleFile android.WritablePath
460
Colin Cross6340ea52021-11-04 12:01:18 -0700461 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900462 installDir android.InstallPath
463
Colin Cross6340ea52021-11-04 12:01:18 -0700464 // Path where this APEX was installed.
465 installedFile android.InstallPath
466
467 // Installed locations of symlinks for backward compatibility.
468 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900469
470 // Text file having the list of individual files that are included in this APEX. Used for
471 // debugging purpose.
472 installedFilesFile android.WritablePath
473
474 // List of module names that this APEX is including (to be shown via *-deps-info target).
475 // Used for debugging purpose.
476 android.ApexBundleDepsInfo
477
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900478 // Optional list of lint report zip files for apexes that contain java or app modules
479 lintReports android.Paths
480
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000481 isCompressed bool
482
sophiezc80a2b32020-11-12 16:39:19 +0000483 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700484 nativeApisUsedByModuleFile android.ModuleOutPath
485 nativeApisBackedByModuleFile android.ModuleOutPath
486 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800487
488 // Collect the module directory for IDE info in java/jdeps.go.
489 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900490}
491
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900492// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900493type apexFileClass int
494
Jooyung Han72bd2f82019-10-23 16:46:38 +0900495const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900496 app apexFileClass = iota
497 appSet
498 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900499 goBinary
500 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900501 nativeExecutable
502 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900503 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900504 pyBinary
505 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900506)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900507
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900508// apexFile represents a file in an APEX bundle. This is created during the first half of
509// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
510// of the function, this is used to create commands that copies the files into a staging directory,
511// where they are packaged into the APEX file. This struct is also used for creating Make modules
512// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900513type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900514 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000515 builtFile android.Path
516 installDir string
517 customStem string
518 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900519
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900520 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
521 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
522 // suffix>]
523 androidMkModuleName string // becomes LOCAL_MODULE
524 class apexFileClass // becomes LOCAL_MODULE_CLASS
525 moduleDir string // becomes LOCAL_PATH
526 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
527 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
528 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
529 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900530
531 jacocoReportClassesFile android.Path // only for javalibs and apps
532 lintDepSets java.LintDepSets // only for javalibs and apps
533 certificate java.Certificate // only for apps
534 overriddenPackageName string // only for apps
535
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900536 transitiveDep bool
537 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900538
Jiyong Park57621b22021-01-20 20:33:11 +0900539 multilib string
540
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900541 // TODO(jiyong): remove this
542 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900543}
544
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900545// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900546func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
547 ret := apexFile{
548 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900549 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900550 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900551 class: class,
552 module: module,
553 }
554 if module != nil {
555 ret.moduleDir = ctx.OtherModuleDir(module)
556 ret.requiredModuleNames = module.RequiredModuleNames()
557 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
558 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900559 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900560 }
561 return ret
562}
563
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900564func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900565 return af.builtFile != nil && af.builtFile.String() != ""
566}
567
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900568// apexRelativePath returns the relative path of the given path from the install directory of this
569// apexFile.
570// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900571func (af *apexFile) apexRelativePath(path string) string {
572 return filepath.Join(af.installDir, path)
573}
574
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900575// path returns path of this apex file relative to the APEX root
576func (af *apexFile) path() string {
577 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900578}
579
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900580// stem returns the base filename of this apex file
581func (af *apexFile) stem() string {
582 if af.customStem != "" {
583 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900584 }
585 return af.builtFile.Base()
586}
587
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900588// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
589func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900590 var ret []string
591 for _, symlink := range af.symlinks {
592 ret = append(ret, af.apexRelativePath(symlink))
593 }
594 return ret
595}
596
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900597// availableToPlatform tests whether this apexFile is from a module that can be installed to the
598// platform.
599func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900600 if af.module == nil {
601 return false
602 }
603 if am, ok := af.module.(android.ApexModule); ok {
604 return am.AvailableFor(android.AvailableToPlatform)
605 }
606 return false
607}
608
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900609////////////////////////////////////////////////////////////////////////////////////////////////////
610// Mutators
611//
612// Brief description about mutators for APEX. The following three mutators are the most important
613// ones.
614//
615// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
616// to the (direct) dependencies of this APEX bundle.
617//
Paul Duffin949abc02020-12-08 10:34:30 +0000618// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900619// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
620// modules are marked as being included in the APEX via BuildForApex().
621//
Paul Duffin949abc02020-12-08 10:34:30 +0000622// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
623// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900624
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900625type dependencyTag struct {
626 blueprint.BaseDependencyTag
627 name string
628
629 // Determines if the dependent will be part of the APEX payload. Can be false for the
630 // dependencies to the signing key module, etc.
631 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000632
633 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
634 // replacement. This is needed because some prebuilt modules do not provide all the information
635 // needed by the apex.
636 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000637
638 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
639 // also be added as exported members of that SDK.
640 memberType android.SdkMemberType
641}
642
643func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
644 return d.memberType
645}
646
647func (d *dependencyTag) ExportMember() bool {
648 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900649}
650
Paul Duffin520917a2022-05-13 13:01:59 +0000651func (d *dependencyTag) String() string {
652 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
653}
654
655func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000656 return !d.sourceOnly
657}
658
659var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000660var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000661
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900662var (
Paul Duffin520917a2022-05-13 13:01:59 +0000663 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
664 bpfTag = &dependencyTag{name: "bpf", payload: true}
665 certificateTag = &dependencyTag{name: "certificate"}
Dennis Shene2ed70c2023-01-11 14:15:43 +0000666 dclaTag = &dependencyTag{name: "dcla"}
Paul Duffin520917a2022-05-13 13:01:59 +0000667 executableTag = &dependencyTag{name: "executable", payload: true}
668 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000669 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
670 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000671 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000672 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
673 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
674 keyTag = &dependencyTag{name: "key"}
675 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
676 rroTag = &dependencyTag{name: "rro", payload: true}
677 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
678 testForTag = &dependencyTag{name: "test for"}
679 testTag = &dependencyTag{name: "test", payload: true}
680 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900681)
682
683// TODO(jiyong): shorten this function signature
684func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900685 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900686 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900687 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900688
689 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900690 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900691 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
692 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900693 }
694
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900695 // Use *FarVariation* to be able to depend on modules having conflicting variations with
696 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
697 // 'arm' or 'arm64' for native shared libs.
Colin Cross70572ed2022-11-02 13:14:20 -0700698 ctx.AddFarVariationDependencies(binVariations, executableTag,
699 android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
700 ctx.AddFarVariationDependencies(binVariations, testTag,
701 android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
702 ctx.AddFarVariationDependencies(libVariations, jniLibTag,
703 android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
704 ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
705 android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
706 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
707 android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
708 ctx.AddFarVariationDependencies(target.Variations(), fsTag,
709 android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900710}
711
712func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900713 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900714 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
715 } else {
716 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
717 if ctx.Os().Bionic() {
718 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
719 } else {
720 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
721 }
722 }
723}
724
Jooyung Hand045ebc2022-12-06 15:23:57 +0900725// getImageVariationPair returns a pair for the image variation name as its
726// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
727// suffix indicates the vndk version when it's vendor or product.
728// getImageVariation can simply join the result of this function to get the
729// image variation name.
730func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900731 if a.vndkApex {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900732 return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900733 }
734
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900735 var prefix string
736 var vndkVersion string
737 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000738 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900739 prefix = cc.VendorVariationPrefix
740 vndkVersion = deviceConfig.VndkVersion()
741 } else if a.ProductSpecific() {
742 prefix = cc.ProductVariationPrefix
743 vndkVersion = deviceConfig.ProductVndkVersion()
744 }
745 }
746 if vndkVersion == "current" {
747 vndkVersion = deviceConfig.PlatformVndkVersion()
748 }
749 if vndkVersion != "" {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900750 return prefix, vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900751 }
752
Jooyung Hand045ebc2022-12-06 15:23:57 +0900753 return android.CoreVariation, "" // The usual case
754}
755
756// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
757// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
758func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
759 prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
760 return prefix + vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900761}
762
763func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900764 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
765 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
766 // each target os/architectures, appropriate dependencies are selected by their
767 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900768 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900769 imageVariation := a.getImageVariation(ctx)
770
771 a.combineProperties(ctx)
772
773 has32BitTarget := false
774 for _, target := range targets {
775 if target.Arch.ArchType.Multilib == "lib32" {
776 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000777 }
778 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900779 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900780 // Don't include artifacts for the host cross targets because there is no way for us
781 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900782 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900783 continue
784 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000785
Colin Cross70572ed2022-11-02 13:14:20 -0700786 var deps ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000787
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900788 // Add native modules targeting both ABIs. When multilib.* is omitted for
789 // native_shared_libs/jni_libs/tests, it implies multilib.both
Colin Cross70572ed2022-11-02 13:14:20 -0700790 deps.Merge(a.properties.Multilib.Both)
791 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900792 Native_shared_libs: a.properties.Native_shared_libs,
793 Tests: a.properties.Tests,
794 Jni_libs: a.properties.Jni_libs,
795 Binaries: nil,
796 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900797
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900798 // Add native modules targeting the first ABI When multilib.* is omitted for
799 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900800 isPrimaryAbi := i == 0
801 if isPrimaryAbi {
Colin Cross70572ed2022-11-02 13:14:20 -0700802 deps.Merge(a.properties.Multilib.First)
803 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900804 Native_shared_libs: nil,
805 Tests: nil,
806 Jni_libs: nil,
807 Binaries: a.properties.Binaries,
808 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900809 }
810
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900811 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900812 switch target.Arch.ArchType.Multilib {
813 case "lib32":
Colin Cross70572ed2022-11-02 13:14:20 -0700814 deps.Merge(a.properties.Multilib.Lib32)
815 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900816 case "lib64":
Colin Cross70572ed2022-11-02 13:14:20 -0700817 deps.Merge(a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900818 if !has32BitTarget {
Colin Cross70572ed2022-11-02 13:14:20 -0700819 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900820 }
821 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900822
Jiyong Park59140302020-12-14 18:44:04 +0900823 // Add native modules targeting a specific arch variant
824 switch target.Arch.ArchType {
825 case android.Arm:
Colin Cross70572ed2022-11-02 13:14:20 -0700826 deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900827 case android.Arm64:
Colin Cross70572ed2022-11-02 13:14:20 -0700828 deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700829 case android.Riscv64:
Colin Cross70572ed2022-11-02 13:14:20 -0700830 deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900831 case android.X86:
Colin Cross70572ed2022-11-02 13:14:20 -0700832 deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900833 case android.X86_64:
Colin Cross70572ed2022-11-02 13:14:20 -0700834 deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900835 default:
836 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
837 }
838
Colin Cross70572ed2022-11-02 13:14:20 -0700839 addDependenciesForNativeModules(ctx, deps, target, imageVariation)
Sundong Ahn80c04892021-11-23 00:57:19 +0000840 ctx.AddFarVariationDependencies([]blueprint.Variation{
841 {Mutator: "os", Variation: target.OsVariation()},
842 {Mutator: "arch", Variation: target.ArchVariation()},
843 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900844 }
845
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900846 // Common-arch dependencies come next
847 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900848 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000849 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100850}
851
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900852// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900853func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
854 if a.overridableProperties.Allowed_files != nil {
855 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100856 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900857
858 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
859 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800860 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900861 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900862 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
863 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
864 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700865 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
866 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
867 // regardless of the TARGET_PREFER_* setting. See b/144532908
868 arches := ctx.DeviceConfig().Arches()
869 if len(arches) != 0 {
870 archForPrebuiltEtc := arches[0]
871 for _, arch := range arches {
872 // Prefer 64-bit arch if there is any
873 if arch.ArchType.Multilib == "lib64" {
874 archForPrebuiltEtc = arch
875 break
876 }
877 }
878 ctx.AddFarVariationDependencies([]blueprint.Variation{
879 {Mutator: "os", Variation: ctx.Os().String()},
880 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
881 }, prebuiltTag, prebuilts...)
882 }
883 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700884
885 // Dependencies for signing
886 if String(a.overridableProperties.Key) == "" {
887 ctx.PropertyErrorf("key", "missing")
888 return
889 }
890 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
891
892 cert := android.SrcIsModule(a.getCertString(ctx))
893 if cert != "" {
894 ctx.AddDependency(ctx.Module(), certificateTag, cert)
895 // empty cert is not an error. Cert and private keys will be directly found under
896 // PRODUCT_DEFAULT_DEV_CERTIFICATE
897 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100898}
899
Dennis Shene2ed70c2023-01-11 14:15:43 +0000900func apexDCLADepsMutator(mctx android.BottomUpMutatorContext) {
901 if !mctx.Config().ApexTrimEnabled() {
902 return
903 }
904 if a, ok := mctx.Module().(*apexBundle); ok && a.overridableProperties.Trim_against != nil {
905 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
906 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(a.overridableProperties.Trim_against))
907 } else if o, ok := mctx.Module().(*OverrideApex); ok {
908 for _, p := range o.GetProperties() {
909 properties, ok := p.(*overridableProperties)
910 if !ok {
911 continue
912 }
913 if properties.Trim_against != nil {
914 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
915 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(properties.Trim_against))
916 }
917 }
918 }
919}
920
921type DCLAInfo struct {
922 ProvidedLibs []string
923}
924
925var DCLAInfoProvider = blueprint.NewMutatorProvider(DCLAInfo{}, "apex_info")
926
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900927type ApexBundleInfo struct {
928 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100929}
930
Paul Duffin949abc02020-12-08 10:34:30 +0000931var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900932
Paul Duffina7d6a892020-12-07 17:39:59 +0000933var _ ApexInfoMutator = (*apexBundle)(nil)
934
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100935func (a *apexBundle) ApexVariationName() string {
936 return a.properties.ApexVariationName
937}
938
Paul Duffina7d6a892020-12-07 17:39:59 +0000939// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900940// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
941// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
942// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
943// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000944//
945// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
946// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
947// The apexMutator uses that list to create module variants for the apexes to which it belongs.
948// The relationship between module variants and apexes is not one-to-one as variants will be
949// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000950func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900951
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900952 // The VNDK APEX is special. For the APEX, the membership is described in a very different
953 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
954 // libraries are self-identified by their vndk.enabled properties. There is no need to run
955 // this mutator for the APEX as nothing will be collected. So, let's return fast.
956 if a.vndkApex {
957 return
958 }
959
960 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
961 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
962 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
963 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
964 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900965 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
966 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900967 if proptools.Bool(a.properties.Use_vndk_as_stable) {
968 if !useVndk {
969 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
970 }
971 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
972 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
973 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
974 }
975 })
976 if mctx.Failed() {
977 return
978 }
Jooyung Handf78e212020-07-22 15:54:47 +0900979 }
980
Colin Cross56a83212020-09-15 18:30:11 -0700981 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900982 am, ok := child.(android.ApexModule)
983 if !ok || !am.CanHaveApexVariants() {
984 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900985 }
Paul Duffin573989d2021-03-17 13:25:29 +0000986 depTag := mctx.OtherModuleDependencyTag(child)
987
988 // Check to see if the tag always requires that the child module has an apex variant for every
989 // apex variant of the parent module. If it does not then it is still possible for something
990 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
991 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
992 return true
993 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000994 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900995 return false
996 }
Jooyung Handf78e212020-07-22 15:54:47 +0900997 if excludeVndkLibs {
998 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
999 return false
1000 }
1001 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001002 // By default, all the transitive dependencies are collected, unless filtered out
1003 // above.
Colin Cross56a83212020-09-15 18:30:11 -07001004 return true
1005 }
1006
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001007 // Records whether a certain module is included in this apexBundle via direct dependency or
1008 // inndirect dependency.
1009 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -07001010 mctx.WalkDeps(func(child, parent android.Module) bool {
1011 if !continueApexDepsWalk(child, parent) {
1012 return false
1013 }
Jooyung Han698dd9f2020-07-22 15:17:19 +09001014 // If the parent is apexBundle, this child is directly depended.
1015 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001016 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -07001017 contents[depName] = contents[depName].Add(directDep)
1018 return true
1019 })
1020
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001021 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +09001022 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -07001023 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
1024 Contents: apexContents,
1025 })
1026
Jooyung Haned124c32021-01-26 11:43:46 +09001027 minSdkVersion := a.minSdkVersion(mctx)
1028 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
1029 if minSdkVersion.IsNone() {
1030 minSdkVersion = android.FutureApiLevel
1031 }
1032
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001033 // This is the main part of this mutator. Mark the collected dependencies that they need to
1034 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +09001035
Jooyung Han63dff462023-02-09 00:11:27 +00001036 apexVariationName := mctx.ModuleName() // could be com.android.foo
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001037 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -07001038 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001039 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +09001040 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -07001041 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +09001042 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001043 InApexVariants: []string{apexVariationName},
1044 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -07001045 ApexContents: []*android.ApexContents{apexContents},
1046 }
Colin Cross56a83212020-09-15 18:30:11 -07001047 mctx.WalkDeps(func(child, parent android.Module) bool {
1048 if !continueApexDepsWalk(child, parent) {
1049 return false
1050 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001051 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +09001052 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +09001053 })
Dennis Shene2ed70c2023-01-11 14:15:43 +00001054
1055 if a.dynamic_common_lib_apex() {
1056 mctx.SetProvider(DCLAInfoProvider, DCLAInfo{
1057 ProvidedLibs: a.properties.Native_shared_libs,
1058 })
1059 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001060}
1061
Paul Duffina7d6a892020-12-07 17:39:59 +00001062type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001063 // ApexVariationName returns the name of the APEX variation to use in the apex
1064 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
1065 ApexVariationName() string
1066
Paul Duffina7d6a892020-12-07 17:39:59 +00001067 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1068 // depended upon by an apex and which require an apex specific variant.
1069 ApexInfoMutator(android.TopDownMutatorContext)
1070}
1071
1072// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1073// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001074// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001075func apexInfoMutator(mctx android.TopDownMutatorContext) {
1076 if !mctx.Module().Enabled() {
1077 return
1078 }
1079
1080 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1081 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001082 }
Spandan Das42e89502022-05-06 22:12:55 +00001083 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001084}
1085
Spandan Das66773252022-01-15 00:23:18 +00001086// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1087// This check is enforced for updatable modules
1088func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1089 if !mctx.Module().Enabled() {
1090 return
1091 }
Spandan Das08c911f2022-01-21 22:07:26 +00001092 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001093 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001094 // b/208656169 Do not propagate strict updatability linting to libcore/
1095 // These libs are available on the classpath during compilation
1096 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1097 // Only skip libraries defined in libcore root, not subdirectories
1098 if mctx.OtherModuleDir(child) == "libcore" {
1099 // Do not traverse transitive deps of libcore/ libs
1100 return false
1101 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001102 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1103 return false
1104 }
Spandan Das66773252022-01-15 00:23:18 +00001105 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1106 lintable.SetStrictUpdatabilityLinting(true)
1107 }
1108 // visit transitive deps
1109 return true
1110 })
1111 }
1112}
1113
Spandan Das42e89502022-05-06 22:12:55 +00001114// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1115func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1116 if !mctx.Module().Enabled() {
1117 return
1118 }
1119 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1120 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1121 mctx.VisitDirectDeps(func(module android.Module) {
1122 // ignore android_test_app
1123 if app, ok := module.(*java.AndroidApp); ok {
1124 app.SetUpdatable(true)
1125 }
1126 })
1127 }
1128}
1129
Spandan Das08c911f2022-01-21 22:07:26 +00001130// TODO: b/215736885 Whittle the denylist
1131// Transitive deps of certain mainline modules baseline NewApi errors
1132// Skip these mainline modules for now
1133var (
1134 skipStrictUpdatabilityLintAllowlist = []string{
1135 "com.android.art",
1136 "com.android.art.debug",
1137 "com.android.conscrypt",
1138 "com.android.media",
1139 // test apexes
1140 "test_com.android.art",
1141 "test_com.android.conscrypt",
1142 "test_com.android.media",
1143 "test_jitzygote_com.android.art",
1144 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001145
1146 // TODO: b/215736885 Remove this list
1147 skipLintJavalibAllowlist = []string{
1148 "conscrypt.module.platform.api.stubs",
1149 "conscrypt.module.public.api.stubs",
1150 "conscrypt.module.public.api.stubs.system",
1151 "conscrypt.module.public.api.stubs.module_lib",
1152 "framework-media.stubs",
1153 "framework-media.stubs.system",
1154 "framework-media.stubs.module_lib",
1155 }
Spandan Das08c911f2022-01-21 22:07:26 +00001156)
1157
1158func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1159 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1160}
1161
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001162// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1163// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1164// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001165func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1166 if !mctx.Module().Enabled() {
1167 return
1168 }
1169 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001170 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1171 }
1172}
1173
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001174// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1175// the apex in order to retrieve its contents later.
1176// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001177func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1178 if !mctx.Module().Enabled() {
1179 return
1180 }
Colin Cross56a83212020-09-15 18:30:11 -07001181 if am, ok := mctx.Module().(android.ApexModule); ok {
1182 if testFor := am.TestFor(); len(testFor) > 0 {
1183 mctx.AddFarVariationDependencies([]blueprint.Variation{
1184 {Mutator: "os", Variation: am.Target().OsVariation()},
1185 {"arch", "common"},
1186 }, testForTag, testFor...)
1187 }
1188 }
1189}
1190
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001191// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001192func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1193 if !mctx.Module().Enabled() {
1194 return
1195 }
Colin Cross56a83212020-09-15 18:30:11 -07001196 if _, ok := mctx.Module().(android.ApexModule); ok {
1197 var contents []*android.ApexContents
1198 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1199 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1200 contents = append(contents, abInfo.Contents)
1201 }
1202 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1203 ApexContents: contents,
1204 })
Colin Crossaede88c2020-08-11 12:17:01 -07001205 }
1206}
1207
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001208// markPlatformAvailability marks whether or not a module can be available to platform. A module
1209// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1210// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1211// be) available to platform
1212// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001213func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1214 // Host and recovery are not considered as platform
1215 if mctx.Host() || mctx.Module().InstallInRecovery() {
1216 return
1217 }
1218
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001219 am, ok := mctx.Module().(android.ApexModule)
1220 if !ok {
1221 return
1222 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001223
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001224 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001225
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001226 // If any of the dep is not available to platform, this module is also considered as being
1227 // not available to platform even if it has "//apex_available:platform"
1228 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001229 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001230 // if the dependency crosses apex boundary, don't consider it
1231 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001232 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001233 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1234 availableToPlatform = false
1235 // TODO(b/154889534) trigger an error when 'am' has
1236 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001237 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001238 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001239
Paul Duffinb5769c12021-05-12 16:16:51 +01001240 // Exception 1: check to see if the module always requires it.
1241 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001242 availableToPlatform = true
1243 }
1244
1245 // Exception 2: bootstrap bionic libraries are also always available to platform
1246 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1247 availableToPlatform = true
1248 }
1249
1250 if !availableToPlatform {
1251 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001252 }
1253}
1254
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001255// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001256// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001257func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001258 if !mctx.Module().Enabled() {
1259 return
1260 }
Colin Cross56a83212020-09-15 18:30:11 -07001261
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001262 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001263 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001264 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001265 return
1266 }
1267
1268 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001269 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1270 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001271 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001272 if strings.HasPrefix(apexBundleName, "com.android.art") {
1273 // Create an alias from the platform variant. This is done to make
1274 // test_for dependencies work for modules that are split by the APEX
1275 // mutator, since test_for dependencies always go to the platform variant.
1276 // This doesn't happen for normal APEXes that are disjunct, so only do
1277 // this for the overlapping ART APEXes.
1278 // TODO(b/183882457): Remove this if the test_for functionality is
1279 // refactored to depend on the proper APEX variants instead of platform.
1280 mctx.CreateAliasVariation("", apexBundleName)
1281 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001282 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1283 apexBundleName := o.GetOverriddenModuleName()
1284 if apexBundleName == "" {
1285 mctx.ModuleErrorf("base property is not set")
1286 return
1287 }
1288 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001289 if strings.HasPrefix(apexBundleName, "com.android.art") {
1290 // TODO(b/183882457): See note for CreateAliasVariation above.
1291 mctx.CreateAliasVariation("", apexBundleName)
1292 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001293 }
1294}
Sundong Ahne9b55722019-09-06 17:37:42 +09001295
Paul Duffin6717d882021-06-15 19:09:41 +01001296// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1297// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001298func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001299 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001300 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001301 return !a.vndkApex
1302 }
1303
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001304 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001305}
1306
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001307// See android.UpdateDirectlyInAnyApex
1308// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001309func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1310 if !mctx.Module().Enabled() {
1311 return
1312 }
1313 if am, ok := mctx.Module().(android.ApexModule); ok {
1314 android.UpdateDirectlyInAnyApex(mctx, am)
1315 }
1316}
1317
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001318// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001319type apexPackaging int
1320
1321const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001322 // imageApex is a packaging method where contents are included in a filesystem image which
1323 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001324 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001325
1326 // zipApex is a packaging method where contents are directly included in the zip container.
1327 // This is used for host-side testing - because the contents are easily accessible by
1328 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001329 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001330
1331 // flattendApex is a packaging method where contents are not included in the APEX file, but
1332 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1333 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001334 flattenedApex
1335)
1336
1337const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001338 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001339 imageApexSuffix = ".apex"
1340 imageCapexSuffix = ".capex"
1341 zipApexSuffix = ".zipapex"
1342 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001343
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001344 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001345 imageApexType = "image"
1346 zipApexType = "zip"
1347 flattenedApexType = "flattened"
1348
Dan Willemsen47e1a752021-10-16 18:36:13 -07001349 ext4FsType = "ext4"
1350 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001351 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001352)
1353
1354// The suffix for the output "file", not the module
1355func (a apexPackaging) suffix() string {
1356 switch a {
1357 case imageApex:
1358 return imageApexSuffix
1359 case zipApex:
1360 return zipApexSuffix
1361 default:
1362 panic(fmt.Errorf("unknown APEX type %d", a))
1363 }
1364}
1365
1366func (a apexPackaging) name() string {
1367 switch a {
1368 case imageApex:
1369 return imageApexType
1370 case zipApex:
1371 return zipApexType
1372 default:
1373 panic(fmt.Errorf("unknown APEX type %d", a))
1374 }
1375}
1376
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001377// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1378// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001379func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001380 if !mctx.Module().Enabled() {
1381 return
1382 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001383 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001384 var variants []string
1385 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1386 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001387 // This is the normal case. Note that both image and flattend APEXes are
1388 // created. The image type is installed to the system partition, while the
1389 // flattened APEX is (optionally) installed to the system_ext partition.
1390 // This is mostly for GSI which has to support wide range of devices. If GSI
1391 // is installed on a newer (APEX-capable) device, the image APEX in the
1392 // system will be used. However, if the same GSI is installed on an old
1393 // device which can't support image APEX, the flattened APEX in the
1394 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001395 variants = append(variants, imageApexType, flattenedApexType)
1396 case "zip":
1397 variants = append(variants, zipApexType)
1398 case "both":
1399 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1400 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001401 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001402 return
1403 }
1404
1405 modules := mctx.CreateLocalVariations(variants...)
1406
1407 for i, v := range variants {
1408 switch v {
1409 case imageApexType:
1410 modules[i].(*apexBundle).properties.ApexType = imageApex
1411 case zipApexType:
1412 modules[i].(*apexBundle).properties.ApexType = zipApex
1413 case flattenedApexType:
1414 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001415 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001416 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001417 modules[i].(*apexBundle).MakeAsSystemExt()
1418 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001419 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001420 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001421 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001422 // payload_type is forcibly overridden to "image"
1423 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001424 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001425 }
1426}
1427
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001428var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001429
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001430// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001431func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001432 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001433 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001434 return true
1435}
1436
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001437var _ android.OutputFileProducer = (*apexBundle)(nil)
1438
1439// Implements android.OutputFileProducer
1440func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1441 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001442 case "", android.DefaultDistTag:
1443 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001444 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001445 case imageApexSuffix:
1446 // uncompressed one
1447 if a.outputApexFile != nil {
1448 return android.Paths{a.outputApexFile}, nil
1449 }
1450 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001451 default:
1452 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1453 }
1454}
1455
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001456var _ multitree.Exportable = (*apexBundle)(nil)
1457
1458func (a *apexBundle) Exportable() bool {
1459 if a.properties.ApexType == flattenedApex {
1460 return false
1461 }
1462 return true
1463}
1464
1465func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1466 ret := make(map[string]android.Paths)
1467 ret["apex"] = android.Paths{a.outputFile}
1468 return ret
1469}
1470
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001471var _ cc.Coverage = (*apexBundle)(nil)
1472
1473// Implements cc.Coverage
1474func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1475 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1476}
1477
1478// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001479func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001480 a.properties.PreventInstall = true
1481}
1482
1483// Implements cc.Coverage
1484func (a *apexBundle) HideFromMake() {
1485 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001486 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1487 // TODO(ccross): untangle these
1488 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001489}
1490
1491// Implements cc.Coverage
1492func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1493 a.properties.IsCoverageVariant = coverage
1494}
1495
1496// Implements cc.Coverage
1497func (a *apexBundle) EnableCoverageIfNeeded() {}
1498
1499var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1500
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001501// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001502func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001503 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001504}
1505
Jiyong Parkf4020582021-11-29 12:37:10 +09001506func (a *apexBundle) FutureUpdatable() bool {
1507 return proptools.BoolDefault(a.properties.Future_updatable, false)
1508}
1509
Jiyong Park1bc84122021-06-22 20:23:05 +09001510func (a *apexBundle) UsePlatformApis() bool {
1511 return proptools.BoolDefault(a.properties.Platform_apis, false)
1512}
1513
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001514// getCertString returns the name of the cert that should be used to sign this APEX. This is
1515// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001516func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001517 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001518 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1519 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1520 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001521 if a.vndkApex {
1522 moduleName = vndkApexName
1523 }
1524 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001525 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001526 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001527 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001528 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001529}
1530
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001531// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001532func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001533 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001534}
1535
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001536// See the generate_hashtree property
1537func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001538 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001539}
1540
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001541// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001542func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1543 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1544}
1545
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001546// See the test_only_force_compression property
1547func (a *apexBundle) testOnlyShouldForceCompression() bool {
1548 return proptools.Bool(a.properties.Test_only_force_compression)
1549}
1550
Dennis Shenaf41bc12022-08-03 16:46:43 +00001551// See the dynamic_common_lib_apex property
1552func (a *apexBundle) dynamic_common_lib_apex() bool {
1553 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1554}
1555
Dennis Shene2ed70c2023-01-11 14:15:43 +00001556// See the list of libs to trim
1557func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string {
1558 dclaModules := ctx.GetDirectDepsWithTag(dclaTag)
1559 if len(dclaModules) > 1 {
1560 panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules)))
1561 }
1562 if len(dclaModules) > 0 {
1563 DCLAInfo := ctx.OtherModuleProvider(dclaModules[0], DCLAInfoProvider).(DCLAInfo)
1564 return DCLAInfo.ProvidedLibs
1565 }
1566 return []string{}
1567}
1568
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001569// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1570// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1571// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001572
Jiyong Parkf97782b2019-02-13 20:28:58 +09001573func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1574 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1575 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1576 }
1577}
1578
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001579func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001580 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1581 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001582 }
1583
1584 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001585 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001586 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001587 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001588 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001589 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001590 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001591 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001592 }
1593 }
1594 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001595}
1596
Jooyung Han8ce8db92020-05-15 19:05:05 +09001597func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001598 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1599 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001600 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001601 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001602 for _, target := range ctx.MultiTargets() {
1603 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001604 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001605 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001606 Tests: nil,
1607 Jni_libs: nil,
1608 Binaries: nil,
1609 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001610 break
1611 }
1612 }
1613 }
1614}
1615
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001616// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1617// returned apexFile saves information about the Soong module that will be used for creating the
1618// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001619func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001620 // Decide the APEX-local directory by the multilib of the library In the future, we may
1621 // query this to the module.
1622 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001623 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001624 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001625 case "lib32":
1626 dirInApex = "lib"
1627 case "lib64":
1628 dirInApex = "lib64"
1629 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001630 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001631 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001632 }
Jooyung Han35155c42020-02-06 17:33:20 +09001633 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001634 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001635 // Special case for Bionic libs and other libs installed with them. This is to
1636 // prevent those libs from being included in the search path
1637 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1638 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1639 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1640 // will be loaded into the default linker namespace (aka "platform" namespace). If
1641 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1642 // be loaded again into the runtime linker namespace, which will result in double
1643 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001644 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001645 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001646
Colin Cross1d487152022-10-03 19:14:46 -07001647 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001648 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1649 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001650}
1651
Jiyong Park1833cef2019-12-13 13:28:36 +09001652func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001653 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001654 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001655 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001656 }
Jooyung Han35155c42020-02-06 17:33:20 +09001657 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001658 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001659 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1660 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001661 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001662 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001663 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001664}
1665
Jiyong Park99644e92020-11-17 22:21:02 +09001666func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1667 dirInApex := "bin"
1668 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1669 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1670 }
Colin Cross1d487152022-10-03 19:14:46 -07001671 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001672 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1673 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1674 return af
1675}
1676
1677func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1678 // Decide the APEX-local directory by the multilib of the library
1679 // In the future, we may query this to the module.
1680 var dirInApex string
1681 switch rustm.Arch().ArchType.Multilib {
1682 case "lib32":
1683 dirInApex = "lib"
1684 case "lib64":
1685 dirInApex = "lib64"
1686 }
1687 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1688 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1689 }
Colin Cross1d487152022-10-03 19:14:46 -07001690 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001691 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1692 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1693}
1694
Cole Faust4d247e62023-01-23 10:14:58 -08001695func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.PythonBinaryModule) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001696 dirInApex := "bin"
1697 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001698 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001699}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001700
Jiyong Park1833cef2019-12-13 13:28:36 +09001701func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001702 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001703 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001704 // NB: Since go binaries are static we don't need the module for anything here, which is
1705 // good since the go tool is a blueprint.Module not an android.Module like we would
1706 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001707 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001708}
1709
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001710func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001711 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001712 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1713 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1714 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001715 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001716 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001717 af.symlinks = sh.Symlinks()
1718 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001719}
1720
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001721func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001722 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001723 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001724 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001725}
1726
atrost6e126252020-01-27 17:01:16 +00001727func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1728 dirInApex := filepath.Join("etc", config.SubDir())
1729 fileToCopy := config.CompatConfig()
1730 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1731}
1732
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001733// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1734// way.
1735type javaModule interface {
1736 android.Module
1737 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001738 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001739 JacocoReportClassesFile() android.Path
1740 LintDepSets() java.LintDepSets
1741 Stem() string
1742}
1743
1744var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001745var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001746var _ javaModule = (*java.SdkLibrary)(nil)
1747var _ javaModule = (*java.DexImport)(nil)
1748var _ javaModule = (*java.SdkLibraryImport)(nil)
1749
Paul Duffin190fdef2021-04-26 10:33:59 +01001750// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001751func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001752 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001753}
1754
1755// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1756func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001757 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001758 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001759 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1760 af.lintDepSets = module.LintDepSets()
1761 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001762 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1763 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1764 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1765 }
1766 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001767 return af
1768}
1769
Jiakai Zhang3317ce72023-02-08 01:19:19 +08001770func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile {
1771 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1772 if profilePathOnHost := dexpreopter.ProfilePathOnHost(); profilePathOnHost != nil {
1773 dirInApex := "javalib"
1774 af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil)
1775 af.customStem = module.Stem() + ".jar.prof"
1776 return &af
1777 }
1778 }
1779 return nil
1780}
1781
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001782// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1783// the same way.
1784type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001785 android.Module
1786 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001787 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001788 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001789 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001790 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001791 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001792 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001793}
1794
1795var _ androidApp = (*java.AndroidApp)(nil)
1796var _ androidApp = (*java.AndroidAppImport)(nil)
1797
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001798func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1799 buildId := ctx.Config().BuildId()
1800
1801 // The build ID is used as a suffix for a filename, so ensure that
1802 // the set of characters being used are sanitized.
1803 // - any word character: [a-zA-Z0-9_]
1804 // - dots: .
1805 // - dashes: -
1806 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1807 if !validRegex.MatchString(buildId) {
1808 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1809 }
1810 return buildId
1811}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001812
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001813func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001814 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001815 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001816 appDir = "priv-app"
1817 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001818
1819 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1820 // so that PackageManager correctly invalidates the existing installed apk
1821 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001822 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001823 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001824
Yo Chiange8128052020-07-23 20:09:18 +08001825 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001826 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001827 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001828 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001829
1830 if app, ok := aapp.(interface {
1831 OverriddenManifestPackageName() string
1832 }); ok {
1833 af.overriddenPackageName = app.OverriddenManifestPackageName()
1834 }
Jiyong Park618922e2020-01-08 13:35:43 +09001835 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001836}
1837
Jiyong Park69aeba92020-04-24 21:16:36 +09001838func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1839 rroDir := "overlay"
1840 dirInApex := filepath.Join(rroDir, rro.Theme())
1841 fileToCopy := rro.OutputFile()
1842 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1843 af.certificate = rro.Certificate()
1844
1845 if a, ok := rro.(interface {
1846 OverriddenManifestPackageName() string
1847 }); ok {
1848 af.overriddenPackageName = a.OverriddenManifestPackageName()
1849 }
1850 return af
1851}
1852
Ken Chenfad7f9d2021-11-10 22:02:57 +08001853func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1854 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001855 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1856}
1857
Jiyong Park12a719c2021-01-07 15:31:24 +09001858func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1859 dirInApex := filepath.Join("etc", "fs")
1860 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1861}
1862
Paul Duffin064b70c2020-11-02 17:32:38 +00001863// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001864// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1865// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1866// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001867func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001868 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001869 am, ok := child.(android.ApexModule)
1870 if !ok || !am.CanHaveApexVariants() {
1871 return false
1872 }
1873
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001874 // Filter-out unwanted depedendencies
1875 depTag := ctx.OtherModuleDependencyTag(child)
1876 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1877 return false
1878 }
Paul Duffin520917a2022-05-13 13:01:59 +00001879 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001880 return false
1881 }
1882
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001883 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001884 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001885
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001886 // Visit actually
1887 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001888 })
1889}
1890
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001891// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1892type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001893
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001894const (
1895 ext4 fsType = iota
1896 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001897 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001898)
Artur Satayev849f8442020-04-28 14:57:42 +01001899
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001900func (f fsType) string() string {
1901 switch f {
1902 case ext4:
1903 return ext4FsType
1904 case f2fs:
1905 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001906 case erofs:
1907 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001908 default:
1909 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001910 }
1911}
1912
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001913var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1914
1915func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1916 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1917}
1918
1919func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1920 bazelCtx := ctx.Config().BazelContext
1921 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1922}
1923
Jingwen Chen889f2f22022-12-16 08:16:01 +00001924// GetBazelLabel returns the bazel label of this apexBundle, or the label of the
1925// override_apex module overriding this apexBundle. An apexBundle can be
1926// overridden by different override_apex modules (e.g. Google or Go variants),
1927// which is handled by the overrides mutators.
1928func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string {
1929 if _, ok := ctx.Module().(android.OverridableModule); ok {
1930 return android.MaybeBp2buildLabelOfOverridingModule(ctx)
1931 }
1932 return a.BazelModuleBase.GetBazelLabel(ctx, a)
1933}
1934
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001935func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1936 if !a.commonBuildActions(ctx) {
1937 return
1938 }
1939
1940 a.setApexTypeAndSuffix(ctx)
1941 a.setPayloadFsType(ctx)
1942 a.setSystemLibLink(ctx)
1943
1944 if a.properties.ApexType != zipApex {
1945 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1946 }
1947
1948 bazelCtx := ctx.Config().BazelContext
1949 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1950 if err != nil {
1951 ctx.ModuleErrorf(err.Error())
1952 return
1953 }
1954 a.installDir = android.PathForModuleInstall(ctx, "apex")
Jingwen Chen94098e82023-01-10 14:50:42 +00001955
1956 // Set the output file to .apex or .capex depending on the compression configuration.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001957 a.setCompression(ctx)
Jingwen Chen94098e82023-01-10 14:50:42 +00001958 if a.isCompressed {
1959 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedCompressedOutput)
1960 } else {
1961 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1962 }
1963 a.outputFile = a.outputApexFile
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001964
Sam Delmerico4ed95e22023-02-03 18:12:15 -05001965 if len(outputs.TidyFiles) > 0 {
1966 tidyFiles := android.PathsForBazelOut(ctx, outputs.TidyFiles)
1967 a.outputFile = android.AttachValidationActions(ctx, a.outputFile, tidyFiles)
1968 }
1969
Liz Kammer0e255ef2022-11-04 16:07:04 -04001970 // TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
1971 // interface if these were set in a provider rather than the module itself
Wei Li32dcdf92022-10-26 22:30:48 -07001972 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1973 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1974 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1975 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Liz Kammer0e255ef2022-11-04 16:07:04 -04001976
Jingwen Chen29743c82023-01-25 17:49:46 +00001977 // Ensure ApexMkInfo.install_to_system make module names are installed as
1978 // part of a bundled build.
1979 a.makeModulesToInstall = append(a.makeModulesToInstall, outputs.MakeModulesToInstall...)
Vinh Tranb6803a52022-12-14 11:34:54 -05001980
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001981 apexType := a.properties.ApexType
1982 switch apexType {
1983 case imageApex:
Liz Kammer303978d2022-11-04 16:12:43 -04001984 a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001985 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
Wei Licc73a052022-11-07 14:25:34 -08001986 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001987 // TODO(b/239084755): Generate the java api using.xml file from Bazel.
Jingwen Chen1ec77852022-11-07 14:36:12 +00001988 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
Wei Li78c07de2022-11-08 16:01:05 -08001989 a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001990 installSuffix := imageApexSuffix
1991 if a.isCompressed {
1992 installSuffix = imageCapexSuffix
1993 }
1994 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1995 a.compatSymlinks.Paths()...)
1996 default:
1997 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1998 }
1999
2000 /*
2001 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
2002 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
2003 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
2004 To find out what Soong build puts there, run:
2005 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2006 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
2007 return a.depVisitor(&vctx, ctx, child, parent)
2008 })
2009 vctx.normalizeFileInfo()
2010 */
2011
2012}
2013
2014func (a *apexBundle) setCompression(ctx android.ModuleContext) {
2015 if a.properties.ApexType != imageApex {
2016 a.isCompressed = false
2017 } else if a.testOnlyShouldForceCompression() {
2018 a.isCompressed = true
2019 } else {
2020 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
2021 }
2022}
2023
2024func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
2025 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
2026 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
2027 // the same library in the system partition, thus effectively sharing the same libraries
2028 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
2029 // in the APEX.
2030 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
2031
2032 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
2033 // So we can't link them to /system/lib libs which are core variants.
2034 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2035 a.linkToSystemLib = false
2036 }
2037
2038 forced := ctx.Config().ForceApexSymlinkOptimization()
2039 updatable := a.Updatable() || a.FutureUpdatable()
2040
2041 // We don't need the optimization for updatable APEXes, as it might give false signal
2042 // to the system health when the APEXes are still bundled (b/149805758).
2043 if !forced && updatable && a.properties.ApexType == imageApex {
2044 a.linkToSystemLib = false
2045 }
2046
2047 // We also don't want the optimization for host APEXes, because it doesn't make sense.
2048 if ctx.Host() {
2049 a.linkToSystemLib = false
2050 }
2051}
2052
2053func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
2054 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
2055 case ext4FsType:
2056 a.payloadFsType = ext4
2057 case f2fsFsType:
2058 a.payloadFsType = f2fs
2059 case erofsFsType:
2060 a.payloadFsType = erofs
2061 default:
2062 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
2063 }
2064}
2065
2066func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
2067 // Set suffix and primaryApexType depending on the ApexType
2068 buildFlattenedAsDefault := ctx.Config().FlattenApex()
2069 switch a.properties.ApexType {
2070 case imageApex:
2071 if buildFlattenedAsDefault {
2072 a.suffix = imageApexSuffix
2073 } else {
2074 a.suffix = ""
2075 a.primaryApexType = true
2076
2077 if ctx.Config().InstallExtraFlattenedApexes() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002078 a.makeModulesToInstall = append(a.makeModulesToInstall, a.Name()+flattenedSuffix)
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002079 }
2080 }
2081 case zipApex:
2082 if proptools.String(a.properties.Payload_type) == "zip" {
2083 a.suffix = ""
2084 a.primaryApexType = true
2085 } else {
2086 a.suffix = zipApexSuffix
2087 }
2088 case flattenedApex:
2089 if buildFlattenedAsDefault {
2090 a.suffix = ""
2091 a.primaryApexType = true
2092 } else {
2093 a.suffix = flattenedSuffix
2094 }
2095 }
2096}
2097
2098func (a apexBundle) isCompressable() bool {
2099 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
2100}
2101
2102func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
2103 a.checkApexAvailability(ctx)
2104 a.checkUpdatable(ctx)
2105 a.CheckMinSdkVersion(ctx)
2106 a.checkStaticLinkingToStubLibraries(ctx)
2107 a.checkStaticExecutables(ctx)
2108 if len(a.properties.Tests) > 0 && !a.testApex {
2109 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
2110 return false
2111 }
2112 return true
2113}
2114
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002115type visitorContext struct {
2116 // all the files that will be included in this APEX
2117 filesInfo []apexFile
2118
2119 // native lib dependencies
2120 provideNativeLibs []string
2121 requireNativeLibs []string
2122
2123 handleSpecialLibs bool
Jooyung Han862c0d62022-12-21 10:15:37 +09002124
2125 // if true, raise error on duplicate apexFile
2126 checkDuplicate bool
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002127}
2128
Jooyung Han862c0d62022-12-21 10:15:37 +09002129func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002130 encountered := make(map[string]apexFile)
2131 for _, f := range vctx.filesInfo {
2132 dest := filepath.Join(f.installDir, f.builtFile.Base())
2133 if e, ok := encountered[dest]; !ok {
2134 encountered[dest] = f
2135 } else {
Jooyung Han862c0d62022-12-21 10:15:37 +09002136 if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
2137 mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
2138 dest, e.builtFile, f.builtFile)
2139 return
2140 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002141 // If a module is directly included and also transitively depended on
2142 // consider it as directly included.
2143 e.transitiveDep = e.transitiveDep && f.transitiveDep
2144 encountered[dest] = e
2145 }
2146 }
2147 vctx.filesInfo = vctx.filesInfo[:0]
2148 for _, v := range encountered {
2149 vctx.filesInfo = append(vctx.filesInfo, v)
2150 }
2151 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2152 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2153 // changes.
2154 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2155 })
2156}
2157
2158func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2159 depTag := ctx.OtherModuleDependencyTag(child)
2160 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2161 return false
2162 }
2163 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2164 return false
2165 }
2166 depName := ctx.OtherModuleName(child)
2167 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2168 switch depTag {
2169 case sharedLibTag, jniLibTag:
2170 isJniLib := depTag == jniLibTag
2171 switch ch := child.(type) {
2172 case *cc.Module:
2173 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2174 fi.isJniLib = isJniLib
2175 vctx.filesInfo = append(vctx.filesInfo, fi)
2176 // Collect the list of stub-providing libs except:
2177 // - VNDK libs are only for vendors
2178 // - bootstrap bionic libs are treated as provided by system
2179 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2180 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2181 }
2182 return true // track transitive dependencies
2183 case *rust.Module:
2184 fi := apexFileForRustLibrary(ctx, ch)
2185 fi.isJniLib = isJniLib
2186 vctx.filesInfo = append(vctx.filesInfo, fi)
2187 return true // track transitive dependencies
2188 default:
2189 propertyName := "native_shared_libs"
2190 if isJniLib {
2191 propertyName = "jni_libs"
2192 }
2193 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2194 }
2195 case executableTag:
2196 switch ch := child.(type) {
2197 case *cc.Module:
2198 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2199 return true // track transitive dependencies
Cole Faust4d247e62023-01-23 10:14:58 -08002200 case *python.PythonBinaryModule:
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002201 if ch.HostToolPath().Valid() {
2202 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2203 }
2204 case bootstrap.GoBinaryTool:
2205 if a.Host() {
2206 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2207 }
2208 case *rust.Module:
2209 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2210 return true // track transitive dependencies
2211 default:
2212 ctx.PropertyErrorf("binaries",
2213 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2214 }
2215 case shBinaryTag:
2216 if csh, ok := child.(*sh.ShBinary); ok {
2217 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2218 } else {
2219 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2220 }
2221 case bcpfTag:
2222 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2223 if !ok {
2224 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2225 return false
2226 }
2227
2228 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2229 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002230 a.makeModulesToInstall = append(a.makeModulesToInstall, makeModuleName)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002231 }
2232 return true
2233 case sscpfTag:
2234 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2235 ctx.PropertyErrorf("systemserverclasspath_fragments",
2236 "%q is not a systemserverclasspath_fragment module", depName)
2237 return false
2238 }
2239 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2240 vctx.filesInfo = append(vctx.filesInfo, *af)
2241 }
2242 return true
2243 case javaLibTag:
2244 switch child.(type) {
2245 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2246 af := apexFileForJavaModule(ctx, child.(javaModule))
2247 if !af.ok() {
2248 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2249 return false
2250 }
2251 vctx.filesInfo = append(vctx.filesInfo, af)
2252 return true // track transitive dependencies
2253 default:
2254 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2255 }
2256 case androidAppTag:
2257 switch ap := child.(type) {
2258 case *java.AndroidApp:
2259 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2260 return true // track transitive dependencies
2261 case *java.AndroidAppImport:
2262 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2263 case *java.AndroidTestHelperApp:
2264 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2265 case *java.AndroidAppSet:
2266 appDir := "app"
2267 if ap.Privileged() {
2268 appDir = "priv-app"
2269 }
2270 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2271 // suffixed so that PackageManager correctly invalidates the
2272 // existing installed apk in favour of the new APK-in-APEX.
2273 // See bugs for more information.
2274 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2275 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2276 af.certificate = java.PresignedCertificate
2277 vctx.filesInfo = append(vctx.filesInfo, af)
2278 default:
2279 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2280 }
2281 case rroTag:
2282 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2283 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2284 } else {
2285 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2286 }
2287 case bpfTag:
2288 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2289 filesToCopy, _ := bpfProgram.OutputFiles("")
2290 apex_sub_dir := bpfProgram.SubDir()
2291 for _, bpfFile := range filesToCopy {
2292 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2293 }
2294 } else {
2295 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2296 }
2297 case fsTag:
2298 if fs, ok := child.(filesystem.Filesystem); ok {
2299 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2300 } else {
2301 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2302 }
2303 case prebuiltTag:
2304 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2305 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2306 } else {
2307 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2308 }
2309 case compatConfigTag:
2310 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2311 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2312 } else {
2313 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2314 }
2315 case testTag:
2316 if ccTest, ok := child.(*cc.Module); ok {
2317 if ccTest.IsTestPerSrcAllTestsVariation() {
2318 // Multiple-output test module (where `test_per_src: true`).
2319 //
2320 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2321 // We do not add this variation to `filesInfo`, as it has no output;
2322 // however, we do add the other variations of this module as indirect
2323 // dependencies (see below).
2324 } else {
2325 // Single-output test module (where `test_per_src: false`).
2326 af := apexFileForExecutable(ctx, ccTest)
2327 af.class = nativeTest
2328 vctx.filesInfo = append(vctx.filesInfo, af)
2329 }
2330 return true // track transitive dependencies
2331 } else {
2332 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2333 }
2334 case keyTag:
2335 if key, ok := child.(*apexKey); ok {
2336 a.privateKeyFile = key.privateKeyFile
2337 a.publicKeyFile = key.publicKeyFile
2338 } else {
2339 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2340 }
2341 case certificateTag:
2342 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2343 a.containerCertificateFile = dep.Certificate.Pem
2344 a.containerPrivateKeyFile = dep.Certificate.Key
2345 } else {
2346 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2347 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002348 }
2349 return false
2350 }
2351
2352 if a.vndkApex {
2353 return false
2354 }
2355
2356 // indirect dependencies
2357 am, ok := child.(android.ApexModule)
2358 if !ok {
2359 return false
2360 }
2361 // We cannot use a switch statement on `depTag` here as the checked
2362 // tags used below are private (e.g. `cc.sharedDepTag`).
2363 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2364 if ch, ok := child.(*cc.Module); ok {
2365 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2366 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2367 return false
2368 }
2369 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2370 af.transitiveDep = true
2371
2372 // Always track transitive dependencies for host.
2373 if a.Host() {
2374 vctx.filesInfo = append(vctx.filesInfo, af)
2375 return true
2376 }
2377
2378 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2379 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2380 // If the dependency is a stubs lib, don't include it in this APEX,
2381 // but make sure that the lib is installed on the device.
2382 // In case no APEX is having the lib, the lib is installed to the system
2383 // partition.
2384 //
2385 // Always include if we are a host-apex however since those won't have any
2386 // system libraries.
Colin Crossdf2043e2023-01-26 15:39:15 -08002387 //
2388 // Skip the dependency in unbundled builds where the device image is not
2389 // being built.
2390 if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() && !ctx.Config().UnbundledBuild() {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002391 // we need a module name for Make
2392 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
Jingwen Chen29743c82023-01-25 17:49:46 +00002393 if !android.InList(name, a.makeModulesToInstall) {
2394 a.makeModulesToInstall = append(a.makeModulesToInstall, name)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002395 }
2396 }
2397 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2398 // Don't track further
2399 return false
2400 }
2401
2402 // If the dep is not considered to be in the same
2403 // apex, don't add it to filesInfo so that it is not
2404 // included in this APEX.
2405 // TODO(jiyong): move this to at the top of the
2406 // else-if clause for the indirect dependencies.
2407 // Currently, that's impossible because we would
2408 // like to record requiredNativeLibs even when
2409 // DepIsInSameAPex is false. We also shouldn't do
2410 // this for host.
2411 //
2412 // TODO(jiyong): explain why the same module is passed in twice.
2413 // Switching the first am to parent breaks lots of tests.
2414 if !android.IsDepInSameApex(ctx, am, am) {
2415 return false
2416 }
2417
2418 vctx.filesInfo = append(vctx.filesInfo, af)
2419 return true // track transitive dependencies
2420 } else if rm, ok := child.(*rust.Module); ok {
2421 af := apexFileForRustLibrary(ctx, rm)
2422 af.transitiveDep = true
2423 vctx.filesInfo = append(vctx.filesInfo, af)
2424 return true // track transitive dependencies
2425 }
2426 } else if cc.IsTestPerSrcDepTag(depTag) {
2427 if ch, ok := child.(*cc.Module); ok {
2428 af := apexFileForExecutable(ctx, ch)
2429 // Handle modules created as `test_per_src` variations of a single test module:
2430 // use the name of the generated test binary (`fileToCopy`) instead of the name
2431 // of the original test module (`depName`, shared by all `test_per_src`
2432 // variations of that module).
2433 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2434 // these are not considered transitive dep
2435 af.transitiveDep = false
2436 vctx.filesInfo = append(vctx.filesInfo, af)
2437 return true // track transitive dependencies
2438 }
2439 } else if cc.IsHeaderDepTag(depTag) {
2440 // nothing
2441 } else if java.IsJniDepTag(depTag) {
2442 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2443 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2444 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2445 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2446 }
2447 } else if rust.IsDylibDepTag(depTag) {
2448 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2449 af := apexFileForRustLibrary(ctx, rustm)
2450 af.transitiveDep = true
2451 vctx.filesInfo = append(vctx.filesInfo, af)
2452 return true // track transitive dependencies
2453 }
2454 } else if rust.IsRlibDepTag(depTag) {
2455 // Rlib is statically linked, but it might have shared lib
2456 // dependencies. Track them.
2457 return true
2458 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2459 // Add the contents of the bootclasspath fragment to the apex.
2460 switch child.(type) {
2461 case *java.Library, *java.SdkLibrary:
2462 javaModule := child.(javaModule)
2463 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2464 if !af.ok() {
2465 ctx.PropertyErrorf("bootclasspath_fragments",
2466 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2467 return false
2468 }
2469 vctx.filesInfo = append(vctx.filesInfo, af)
2470 return true // track transitive dependencies
2471 default:
2472 ctx.PropertyErrorf("bootclasspath_fragments",
2473 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2474 }
2475 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2476 // Add the contents of the systemserverclasspath fragment to the apex.
2477 switch child.(type) {
2478 case *java.Library, *java.SdkLibrary:
2479 af := apexFileForJavaModule(ctx, child.(javaModule))
2480 vctx.filesInfo = append(vctx.filesInfo, af)
Jiakai Zhang3317ce72023-02-08 01:19:19 +08002481 if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil {
2482 vctx.filesInfo = append(vctx.filesInfo, *profileAf)
2483 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002484 return true // track transitive dependencies
2485 default:
2486 ctx.PropertyErrorf("systemserverclasspath_fragments",
2487 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2488 }
2489 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2490 // nothing
2491 } else if depTag == android.DarwinUniversalVariantTag {
2492 // nothing
2493 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2494 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2495 }
2496 return false
2497}
2498
Jooyung Han862c0d62022-12-21 10:15:37 +09002499func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
2500 // TODO(b/263308293) remove this
2501 if a.properties.IsCoverageVariant {
2502 return false
2503 }
2504 // TODO(b/263308515) remove this
2505 if a.testApex {
2506 return false
2507 }
2508 // TODO(b/263309864) remove this
2509 if a.Host() {
2510 return false
2511 }
2512 if a.Device() && ctx.DeviceConfig().DeviceArch() == "" {
2513 return false
2514 }
2515 return true
2516}
2517
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002518// Creates build rules for an APEX. It consists of the following major steps:
2519//
2520// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2521// 2) traverse the dependency tree to collect apexFile structs from them.
2522// 3) some fields in apexBundle struct are configured
2523// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002524func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002525 ////////////////////////////////////////////////////////////////////////////////////////////
2526 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002527 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002528 return
2529 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002530 ////////////////////////////////////////////////////////////////////////////////////////////
2531 // 2) traverse the dependency tree to collect apexFile structs from them.
braleeb0c1f0c2021-06-07 22:49:13 +08002532 // Collect the module directory for IDE info in java/jdeps.go.
2533 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2534
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002535 // TODO(jiyong): do this using WalkPayloadDeps
2536 // TODO(jiyong): make this clean!!!
Jooyung Han862c0d62022-12-21 10:15:37 +09002537 vctx := visitorContext{
2538 handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case),
2539 checkDuplicate: a.shouldCheckDuplicate(ctx),
2540 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002541 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
Jooyung Han862c0d62022-12-21 10:15:37 +09002542 vctx.normalizeFileInfo(ctx)
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002543 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002544 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002545 return
2546 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002547
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002548 ////////////////////////////////////////////////////////////////////////////////////////////
2549 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002550 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002551 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002552
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002553 a.setApexTypeAndSuffix(ctx)
2554 a.setPayloadFsType(ctx)
2555 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002556 if a.properties.ApexType != zipApex {
2557 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2558 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002559
2560 ////////////////////////////////////////////////////////////////////////////////////////////
2561 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002562 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002563 if a.properties.ApexType == flattenedApex {
2564 a.buildFlattenedApex(ctx)
2565 } else {
2566 a.buildUnflattenedApex(ctx)
2567 }
Jiyong Park956305c2020-01-09 12:32:06 +09002568 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002569 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002570
2571 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2572 if a.installable() {
2573 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2574 // along with other ordinary files. (Note that this is done by apexer for
2575 // non-flattened APEXes)
2576 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2577
2578 // Place the public key as apex_pubkey. This is also done by apexer for
2579 // non-flattened APEXes case.
2580 // TODO(jiyong): Why do we need this CP rule?
2581 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2582 ctx.Build(pctx, android.BuildParams{
2583 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002584 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002585 Output: copiedPubkey,
2586 })
2587 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2588 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002589}
2590
Paul Duffincc33ec82021-04-25 23:14:55 +01002591// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2592// the bootclasspath_fragment contributes to the apex.
2593func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2594 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2595 var filesToAdd []apexFile
2596
2597 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002598 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2599 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2600 dirInApex := filepath.Join("javalib", arch.String())
2601 for _, f := range files {
2602 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2603 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2604 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2605 filesToAdd = append(filesToAdd, af)
2606 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002607 }
2608 }
2609
satayev3db35472021-05-06 23:59:58 +01002610 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002611 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2612 filesToAdd = append(filesToAdd, *af)
2613 }
satayev3db35472021-05-06 23:59:58 +01002614
Ulya Trafimovichf5c548d2022-11-16 14:52:41 +00002615 pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2616 if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002617 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2618 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2619
2620 if pathOnHost != nil {
2621 // We need to copy the profile to a temporary path with the right filename because the apexer
2622 // will take the filename as is.
2623 ctx.Build(pctx, android.BuildParams{
2624 Rule: android.Cp,
2625 Input: pathOnHost,
2626 Output: tempPath,
2627 })
2628 } else {
2629 // At this point, the boot image profile cannot be generated. It is probably because the boot
2630 // image profile source file does not exist on the branch, or it is not available for the
2631 // current build target.
2632 // However, we cannot enforce the boot image profile to be generated because some build
2633 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2634 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2635 // only if the APEX is being built.
2636 ctx.Build(pctx, android.BuildParams{
2637 Rule: android.ErrorRule,
2638 Output: tempPath,
2639 Args: map[string]string{
2640 "error": "Boot image profile cannot be generated",
2641 },
2642 })
2643 }
2644
2645 androidMkModuleName := filepath.Base(pathInApex)
2646 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2647 filesToAdd = append(filesToAdd, af)
2648 }
2649
Paul Duffincc33ec82021-04-25 23:14:55 +01002650 return filesToAdd
2651}
2652
satayevb98371c2021-06-15 16:49:50 +01002653// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2654// the module contributes to the apex; or nil if the proto config was not generated.
2655func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2656 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2657 if !info.ClasspathFragmentProtoGenerated {
2658 return nil
2659 }
2660 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2661 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2662 return &af
satayev14e49132021-05-17 21:03:07 +01002663}
2664
Paul Duffincc33ec82021-04-25 23:14:55 +01002665// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2666// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002667func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2668 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2669
2670 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2671 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002672 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2673 if err != nil {
2674 ctx.ModuleErrorf("%s", err)
2675 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002676
2677 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2678 // bootclasspath_fragment.
2679 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2680 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002681}
2682
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002683///////////////////////////////////////////////////////////////////////////////////////////////////
2684// Factory functions
2685//
2686
2687func newApexBundle() *apexBundle {
2688 module := &apexBundle{}
2689
2690 module.AddProperties(&module.properties)
2691 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002692 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002693 module.AddProperties(&module.overridableProperties)
2694
2695 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2696 android.InitDefaultableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002697 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002698 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002699 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002700 return module
2701}
2702
Paul Duffineb8051d2021-10-18 17:49:39 +01002703func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002704 bundle := newApexBundle()
2705 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002706 return bundle
2707}
2708
2709// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2710// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002711func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002712 bundle := newApexBundle()
2713 bundle.testApex = true
2714 return bundle
2715}
2716
2717// apex packages other modules into an APEX file which is a packaging format for system-level
2718// components like binaries, shared libraries, etc.
2719func BundleFactory() android.Module {
2720 return newApexBundle()
2721}
2722
2723type Defaults struct {
2724 android.ModuleBase
2725 android.DefaultsModuleBase
2726}
2727
2728// apex_defaults provides defaultable properties to other apex modules.
2729func defaultsFactory() android.Module {
2730 return DefaultsFactory()
2731}
2732
2733func DefaultsFactory(props ...interface{}) android.Module {
2734 module := &Defaults{}
2735
2736 module.AddProperties(props...)
2737 module.AddProperties(
2738 &apexBundleProperties{},
2739 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002740 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002741 &overridableProperties{},
2742 )
2743
2744 android.InitDefaultsModule(module)
2745 return module
2746}
2747
2748type OverrideApex struct {
2749 android.ModuleBase
2750 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002751 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002752}
2753
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002754func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002755 // All the overrides happen in the base module.
2756}
2757
2758// override_apex is used to create an apex module based on another apex module by overriding some of
2759// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002760func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002761 m := &OverrideApex{}
2762
2763 m.AddProperties(&overridableProperties{})
2764
2765 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2766 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002767 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002768 return m
2769}
2770
Wei Li1c66fc72022-05-09 23:59:14 -07002771func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2772 if ctx.ModuleType() != "override_apex" {
2773 return
2774 }
2775
2776 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2777 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2778 if !baseApexExists {
2779 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2780 }
2781
2782 a, baseModuleIsApex := baseModule.(*apexBundle)
2783 if !baseModuleIsApex {
2784 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2785 }
2786 attrs, props := convertWithBp2build(a, ctx)
2787
Jingwen Chenc4c34e12022-11-29 12:07:45 +00002788 // We just want the name, not module reference.
2789 baseApexName := strings.TrimPrefix(baseApexModuleName, ":")
2790 attrs.Base_apex_name = &baseApexName
2791
Wei Li1c66fc72022-05-09 23:59:14 -07002792 for _, p := range o.GetProperties() {
2793 overridableProperties, ok := p.(*overridableProperties)
2794 if !ok {
2795 continue
2796 }
Wei Li40f98732022-05-20 22:08:11 -07002797
2798 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2799 // After it is converted in convertWithBp2build(baseApex, ctx),
2800 // the attrs.Manifest.Value.Label is the file path relative to the directory
2801 // of base apex. So the following code converts it to a label that looks like
2802 // <package of base apex>:<path of manifest file> if base apex and override
2803 // apex are not in the same package.
2804 baseApexPackage := ctx.OtherModuleDir(a)
2805 overrideApexPackage := ctx.ModuleDir()
2806 if baseApexPackage != overrideApexPackage {
2807 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2808 }
2809
Wei Li1c66fc72022-05-09 23:59:14 -07002810 // Key
2811 if overridableProperties.Key != nil {
2812 attrs.Key = bazel.LabelAttribute{}
2813 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2814 }
2815
2816 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002817 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002818 // If overridableProperties.Certificate is nil, clear this out as
2819 // well with zeroed structs, so the override_apex does not use the
2820 // base apex's certificate.
2821 attrs.Certificate = bazel.LabelAttribute{}
2822 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002823 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002824 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002825 }
2826
2827 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002828 if overridableProperties.Prebuilts != nil {
2829 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2830 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2831 }
Wei Li1c66fc72022-05-09 23:59:14 -07002832
2833 // Compressible
2834 if overridableProperties.Compressible != nil {
2835 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2836 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002837
2838 // Package name
2839 //
2840 // e.g. com.android.adbd's package name is com.android.adbd, but
2841 // com.google.android.adbd overrides the package name to com.google.android.adbd
2842 //
2843 // TODO: this can be overridden from the product configuration, see
2844 // getOverrideManifestPackageName and
2845 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2846 //
2847 // Instead of generating the BUILD files differently based on the product config
2848 // at the point of conversion, this should be handled by the BUILD file loading
2849 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2850 if overridableProperties.Package_name != "" {
2851 attrs.Package_name = &overridableProperties.Package_name
2852 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002853
2854 // Logging parent
2855 if overridableProperties.Logging_parent != "" {
2856 attrs.Logging_parent = &overridableProperties.Logging_parent
2857 }
Wei Li1c66fc72022-05-09 23:59:14 -07002858 }
2859
2860 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2861}
2862
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002863///////////////////////////////////////////////////////////////////////////////////////////////////
2864// Vality check routines
2865//
2866// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2867// certain conditions are not met.
2868//
2869// TODO(jiyong): move these checks to a separate go file.
2870
satayevad991492021-12-03 18:58:32 +00002871var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2872
Spandan Dasa5f39a12022-08-05 02:35:52 +00002873// 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 +09002874// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002875func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002876 if a.testApex || a.vndkApex {
2877 return
2878 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002879 // apexBundle::minSdkVersion reports its own errors.
2880 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002881 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002882}
2883
Albert Martineefabcf2022-03-21 20:11:16 +00002884// Returns apex's min_sdk_version string value, honoring overrides
2885func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2886 // Only override the minSdkVersion value on Apexes which already specify
2887 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2888 // min_sdk_version value is lower than the one to override with.
zhidou133c55b2023-01-31 19:34:10 +00002889 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.overridableProperties.Min_sdk_version))
Colin Cross56534df2022-10-04 09:58:58 -07002890 if minApiLevel.IsNone() {
2891 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002892 }
2893
Colin Cross56534df2022-10-04 09:58:58 -07002894 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2895 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2896 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2897 minApiLevel = overrideApiLevel
2898 }
2899
2900 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002901}
2902
2903// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002904func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2905 return android.SdkSpec{
2906 Kind: android.SdkNone,
2907 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002908 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002909 }
2910}
2911
Albert Martineefabcf2022-03-21 20:11:16 +00002912// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002913func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002914 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2915}
2916
2917// Construct ApiLevel object from min_sdk_version string value
2918func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2919 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002920 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002921 }
Albert Martineefabcf2022-03-21 20:11:16 +00002922 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002923 if err != nil {
2924 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2925 return android.NoneApiLevel
2926 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002927 return apiLevel
2928}
2929
2930// Ensures that a lib providing stub isn't statically linked
2931func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2932 // Practically, we only care about regular APEXes on the device.
2933 if ctx.Host() || a.testApex || a.vndkApex {
2934 return
2935 }
2936
2937 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2938
2939 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2940 if ccm, ok := to.(*cc.Module); ok {
2941 apexName := ctx.ModuleName()
2942 fromName := ctx.OtherModuleName(from)
2943 toName := ctx.OtherModuleName(to)
2944
2945 // If `to` is not actually in the same APEX as `from` then it does not need
2946 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002947 //
2948 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002949 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2950 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2951 return false
2952 }
2953
2954 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2955 // exception to this rule. It can't make the static dependencies dynamic
2956 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002957 // Same rule should be applied to linkerconfig, because it should be executed
2958 // only with static linked libraries before linker is available with ld.config.txt
2959 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002960 return false
2961 }
2962
2963 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2964 if isStubLibraryFromOtherApex && !externalDep {
2965 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2966 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2967 }
2968
2969 }
2970 return true
2971 })
2972}
2973
satayevb98371c2021-06-15 16:49:50 +01002974// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002975func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2976 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002977 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002978 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2979 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002980 if a.UsePlatformApis() {
2981 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2982 }
Daniel Norman69109112021-12-02 12:52:42 -08002983 if a.SocSpecific() || a.DeviceSpecific() {
2984 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2985 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002986 if a.FutureUpdatable() {
2987 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2988 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002989 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002990 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002991 }
2992}
2993
satayevb98371c2021-06-15 16:49:50 +01002994// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2995func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2996 ctx.VisitDirectDeps(func(module android.Module) {
2997 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2998 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2999 if !info.ClasspathFragmentProtoGenerated {
3000 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
3001 }
3002 }
3003 })
3004}
3005
3006// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01003007func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003008 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
3009 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01003010 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3011 tag := ctx.OtherModuleDependencyTag(module)
3012 switch tag {
3013 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09003014 if m, ok := module.(interface {
3015 CheckStableSdkVersion(ctx android.BaseModuleContext) error
3016 }); ok {
3017 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01003018 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
3019 }
3020 }
3021 }
3022 })
3023}
3024
satayevb98371c2021-06-15 16:49:50 +01003025// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003026func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
3027 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
3028 if ctx.Host() || a.testApex || a.vndkApex {
3029 return
3030 }
3031
3032 // Because APEXes targeting other than system/system_ext partitions can't set
3033 // apex_available, we skip checks for these APEXes
3034 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
3035 return
3036 }
3037
3038 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
3039 // Requiring them and their transitive depencies with apex_available is not right
3040 // because they just add noise.
3041 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
3042 return
3043 }
3044
3045 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
3046 // As soon as the dependency graph crosses the APEX boundary, don't go further.
3047 if externalDep {
3048 return false
3049 }
3050
3051 apexName := ctx.ModuleName()
3052 fromName := ctx.OtherModuleName(from)
3053 toName := ctx.OtherModuleName(to)
3054
3055 // If `to` is not actually in the same APEX as `from` then it does not need
3056 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00003057 //
3058 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003059 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
3060 // As soon as the dependency graph crosses the APEX boundary, don't go
3061 // further.
3062 return false
3063 }
3064
3065 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
3066 return true
3067 }
Jiyong Park767dbd92021-03-04 13:03:10 +09003068 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
3069 "\n\nDependency path:%s\n\n"+
3070 "Consider adding %q to 'apex_available' property of %q",
3071 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003072 // Visit this module's dependencies to check and report any issues with their availability.
3073 return true
3074 })
3075}
3076
Jiyong Park192600a2021-08-03 07:52:17 +00003077// checkStaticExecutable ensures that executables in an APEX are not static.
3078func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09003079 // No need to run this for host APEXes
3080 if ctx.Host() {
3081 return
3082 }
3083
Jiyong Park192600a2021-08-03 07:52:17 +00003084 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3085 if ctx.OtherModuleDependencyTag(module) != executableTag {
3086 return
3087 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09003088
3089 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00003090 apex := a.ApexVariationName()
3091 exec := ctx.OtherModuleName(module)
3092 if isStaticExecutableAllowed(apex, exec) {
3093 return
3094 }
3095 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
3096 }
3097 })
3098}
3099
3100// A small list of exceptions where static executables are allowed in APEXes.
3101func isStaticExecutableAllowed(apex string, exec string) bool {
3102 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003103 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00003104 "linker",
3105 "linkerconfig",
3106 },
3107 }
3108 execNames, ok := m[apex]
3109 return ok && android.InList(exec, execNames)
3110}
3111
braleeb0c1f0c2021-06-07 22:49:13 +08003112// Collect information for opening IDE project files in java/jdeps.go.
3113func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09003114 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
3115 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
3116 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08003117 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
3118}
3119
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003120var (
3121 apexAvailBaseline = makeApexAvailableBaseline()
3122 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
3123)
3124
Colin Cross440e0d02020-06-11 11:32:11 -07003125func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003126 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003127 moduleName = normalizeModuleName(moduleName)
3128
Colin Cross440e0d02020-06-11 11:32:11 -07003129 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003130 return true
3131 }
3132
3133 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07003134 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003135 return true
3136 }
3137
3138 return false
3139}
3140
3141func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09003142 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
3143 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00003144 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09003145 if strings.HasPrefix(moduleName, "libclang_rt.") {
3146 // This module has many arch variants that depend on the product being built.
3147 // We don't want to list them all
3148 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003149 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003150 if strings.HasPrefix(moduleName, "androidx.") {
3151 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3152 moduleName = "androidx"
3153 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003154 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003155}
3156
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003157// Transform the map of apex -> modules to module -> apexes.
3158func invertApexBaseline(m map[string][]string) map[string][]string {
3159 r := make(map[string][]string)
3160 for apex, modules := range m {
3161 for _, module := range modules {
3162 r[module] = append(r[module], apex)
3163 }
3164 }
3165 return r
3166}
3167
3168// Retrieve the baseline of apexes to which the supplied module belongs.
3169func BaselineApexAvailable(moduleName string) []string {
3170 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3171}
3172
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003173// This is a map from apex to modules, which overrides the apex_available setting for that
3174// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003175// TODO(b/147364041): remove this
3176func makeApexAvailableBaseline() map[string][]string {
3177 // The "Module separator"s below are employed to minimize merge conflicts.
3178 m := make(map[string][]string)
3179 //
3180 // Module separator
3181 //
3182 m["com.android.appsearch"] = []string{
3183 "icing-java-proto-lite",
3184 "libprotobuf-java-lite",
3185 }
3186 //
3187 // Module separator
3188 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003189 m["com.android.btservices"] = []string{
William Escande89bca3f2022-06-28 18:03:30 -07003190 // empty
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003191 }
3192 //
3193 // Module separator
3194 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003195 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3196 //
3197 // Module separator
3198 //
3199 m["com.android.extservices"] = []string{
3200 "error_prone_annotations",
3201 "ExtServices-core",
3202 "ExtServices",
3203 "libtextclassifier-java",
3204 "libz_current",
3205 "textclassifier-statsd",
3206 "TextClassifierNotificationLibNoManifest",
3207 "TextClassifierServiceLibNoManifest",
3208 }
3209 //
3210 // Module separator
3211 //
3212 m["com.android.neuralnetworks"] = []string{
3213 "android.hardware.neuralnetworks@1.0",
3214 "android.hardware.neuralnetworks@1.1",
3215 "android.hardware.neuralnetworks@1.2",
3216 "android.hardware.neuralnetworks@1.3",
3217 "android.hidl.allocator@1.0",
3218 "android.hidl.memory.token@1.0",
3219 "android.hidl.memory@1.0",
3220 "android.hidl.safe_union@1.0",
3221 "libarect",
3222 "libbuildversion",
3223 "libmath",
3224 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003225 }
3226 //
3227 // Module separator
3228 //
3229 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003230 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003231 }
3232 //
3233 // Module separator
3234 //
3235 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003236 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003237 }
3238 //
3239 // Module separator
3240 //
3241 m["com.android.mediaprovider"] = []string{
3242 "MediaProvider",
3243 "MediaProviderGoogle",
3244 "fmtlib_ndk",
3245 "libbase_ndk",
3246 "libfuse",
3247 "libfuse_jni",
3248 }
3249 //
3250 // Module separator
3251 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003252 m["com.android.runtime"] = []string{
3253 "bionic_libc_platform_headers",
3254 "libarm-optimized-routines-math",
3255 "libc_aeabi",
3256 "libc_bionic",
3257 "libc_bionic_ndk",
3258 "libc_bootstrap",
3259 "libc_common",
3260 "libc_common_shared",
3261 "libc_common_static",
3262 "libc_dns",
3263 "libc_dynamic_dispatch",
3264 "libc_fortify",
3265 "libc_freebsd",
3266 "libc_freebsd_large_stack",
3267 "libc_gdtoa",
3268 "libc_init_dynamic",
3269 "libc_init_static",
3270 "libc_jemalloc_wrapper",
3271 "libc_netbsd",
3272 "libc_nomalloc",
3273 "libc_nopthread",
3274 "libc_openbsd",
3275 "libc_openbsd_large_stack",
3276 "libc_openbsd_ndk",
3277 "libc_pthread",
3278 "libc_static_dispatch",
3279 "libc_syscalls",
3280 "libc_tzcode",
3281 "libc_unwind_static",
3282 "libdebuggerd",
3283 "libdebuggerd_common_headers",
3284 "libdebuggerd_handler_core",
3285 "libdebuggerd_handler_fallback",
3286 "libdl_static",
3287 "libjemalloc5",
3288 "liblinker_main",
3289 "liblinker_malloc",
3290 "liblz4",
3291 "liblzma",
3292 "libprocinfo",
3293 "libpropertyinfoparser",
3294 "libscudo",
3295 "libstdc++",
3296 "libsystemproperties",
3297 "libtombstoned_client_static",
3298 "libunwindstack",
3299 "libz",
3300 "libziparchive",
3301 }
3302 //
3303 // Module separator
3304 //
3305 m["com.android.tethering"] = []string{
3306 "android.hardware.tetheroffload.config-V1.0-java",
3307 "android.hardware.tetheroffload.control-V1.0-java",
3308 "android.hidl.base-V1.0-java",
3309 "libcgrouprc",
3310 "libcgrouprc_format",
3311 "libtetherutilsjni",
3312 "libvndksupport",
3313 "net-utils-framework-common",
3314 "netd_aidl_interface-V3-java",
3315 "netlink-client",
3316 "networkstack-aidl-interfaces-java",
3317 "tethering-aidl-interfaces-java",
3318 "TetheringApiCurrentLib",
3319 }
3320 //
3321 // Module separator
3322 //
3323 m["com.android.wifi"] = []string{
3324 "PlatformProperties",
3325 "android.hardware.wifi-V1.0-java",
3326 "android.hardware.wifi-V1.0-java-constants",
3327 "android.hardware.wifi-V1.1-java",
3328 "android.hardware.wifi-V1.2-java",
3329 "android.hardware.wifi-V1.3-java",
3330 "android.hardware.wifi-V1.4-java",
3331 "android.hardware.wifi.hostapd-V1.0-java",
3332 "android.hardware.wifi.hostapd-V1.1-java",
3333 "android.hardware.wifi.hostapd-V1.2-java",
3334 "android.hardware.wifi.supplicant-V1.0-java",
3335 "android.hardware.wifi.supplicant-V1.1-java",
3336 "android.hardware.wifi.supplicant-V1.2-java",
3337 "android.hardware.wifi.supplicant-V1.3-java",
3338 "android.hidl.base-V1.0-java",
3339 "android.hidl.manager-V1.0-java",
3340 "android.hidl.manager-V1.1-java",
3341 "android.hidl.manager-V1.2-java",
3342 "bouncycastle-unbundled",
3343 "dnsresolver_aidl_interface-V2-java",
3344 "error_prone_annotations",
3345 "framework-wifi-pre-jarjar",
3346 "framework-wifi-util-lib",
3347 "ipmemorystore-aidl-interfaces-V3-java",
3348 "ipmemorystore-aidl-interfaces-java",
3349 "ksoap2",
3350 "libnanohttpd",
3351 "libwifi-jni",
3352 "net-utils-services-common",
3353 "netd_aidl_interface-V2-java",
3354 "netd_aidl_interface-unstable-java",
3355 "netd_event_listener_interface-java",
3356 "netlink-client",
3357 "networkstack-client",
3358 "services.net",
3359 "wifi-lite-protos",
3360 "wifi-nano-protos",
3361 "wifi-service-pre-jarjar",
3362 "wifi-service-resources",
3363 }
3364 //
3365 // Module separator
3366 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003367 m["com.android.os.statsd"] = []string{
3368 "libstatssocket",
3369 }
3370 //
3371 // Module separator
3372 //
3373 m[android.AvailableToAnyApex] = []string{
3374 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3375 "androidx",
3376 "androidx-constraintlayout_constraintlayout",
3377 "androidx-constraintlayout_constraintlayout-nodeps",
3378 "androidx-constraintlayout_constraintlayout-solver",
3379 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3380 "com.google.android.material_material",
3381 "com.google.android.material_material-nodeps",
3382
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003383 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003384 "libprofile-clang-extras",
3385 "libprofile-clang-extras_ndk",
3386 "libprofile-extras",
3387 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003388 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003389 }
3390 return m
3391}
3392
3393func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003394 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3395 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003396}
3397
Spandan Dasf14e2542021-11-12 00:01:37 +00003398func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3399 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3400 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003401 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003402 With("name", jar).
3403 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3404 Because(jar +
3405 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003406 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003407 " 1. If the offending code is from a statically linked library, consider " +
3408 "removing that dependency and using an alternative already in the " +
3409 "bootclasspath, or perhaps a shared library." +
3410 " 2. Move the offending code into an allowed package.\n" +
3411 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3412 "health implications of bundling that code, particularly if the offending jar " +
3413 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003414
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003415 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003416 }
3417 return rules
3418}
3419
Anton Hanssone1b18362021-12-23 15:05:38 +00003420// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003421// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003422func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003423 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003424 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003425 "android.net.ssl",
3426 "com.android.org.conscrypt",
3427 },
Wei Li40f98732022-05-20 22:08:11 -07003428 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003429 "android.media",
3430 },
3431 }
3432}
3433
Anton Hanssone1b18362021-12-23 15:05:38 +00003434// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003435// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003436func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003437 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003438 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003439 "android.provider",
3440 },
Wei Li40f98732022-05-20 22:08:11 -07003441 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003442 "android.permission",
3443 "android.app.role",
3444 "com.android.permission",
3445 "com.android.role",
3446 },
Wei Li40f98732022-05-20 22:08:11 -07003447 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003448 "android.os.ext",
3449 },
Wei Li40f98732022-05-20 22:08:11 -07003450 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003451 "android.app",
3452 "android.os",
3453 "android.util",
3454 "com.android.internal.statsd",
3455 "com.android.server.stats",
3456 },
Wei Li40f98732022-05-20 22:08:11 -07003457 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003458 "com.android.server.wifi",
3459 "com.android.wifi.x",
3460 "android.hardware.wifi",
3461 "android.net.wifi",
3462 },
Wei Li40f98732022-05-20 22:08:11 -07003463 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003464 "android.net",
3465 },
3466 }
3467}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003468
3469// For Bazel / bp2build
3470
3471type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003472 Manifest bazel.LabelAttribute
3473 Android_manifest bazel.LabelAttribute
3474 File_contexts bazel.LabelAttribute
3475 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003476 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3477 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Liz Kammerb83b7b02022-12-21 14:53:41 -05003478 Min_sdk_version bazel.StringAttribute
Yu Liu4ae55d12022-01-05 17:17:23 -08003479 Updatable bazel.BoolAttribute
3480 Installable bazel.BoolAttribute
3481 Binaries bazel.LabelListAttribute
3482 Prebuilts bazel.LabelListAttribute
3483 Native_shared_libs_32 bazel.LabelListAttribute
3484 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003485 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003486 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003487 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003488 Tests bazel.LabelListAttribute
Jingwen Chenc4c34e12022-11-29 12:07:45 +00003489 Base_apex_name *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003490}
3491
3492type convertedNativeSharedLibs struct {
3493 Native_shared_libs_32 bazel.LabelListAttribute
3494 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003495}
3496
Liz Kammerb83b7b02022-12-21 14:53:41 -05003497const (
3498 minSdkVersionPropName = "Min_sdk_version"
3499)
3500
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003501// ConvertWithBp2build performs bp2build conversion of an apex
3502func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003503 // We only convert apex and apex_test modules at this time
3504 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003505 return
3506 }
3507
Wei Li1c66fc72022-05-09 23:59:14 -07003508 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003509 commonAttrs := android.CommonAttributes{
3510 Name: a.Name(),
3511 }
3512 if a.testApex {
3513 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3514 }
3515 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003516}
3517
3518func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003519 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003520 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003521
3522 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003523 if a.properties.AndroidManifest != nil {
3524 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003525 }
3526
3527 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003528 if a.properties.File_contexts == nil {
3529 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3530 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3531 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3532 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003533 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003534 } else {
3535 // File_contexts is a file
3536 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003537 }
3538
Liz Kammerb83b7b02022-12-21 14:53:41 -05003539 productVariableProps := android.ProductVariableProperties(ctx)
Albert Martineefabcf2022-03-21 20:11:16 +00003540 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3541 // given it's coming via config, we probably don't want to put it in here.
Liz Kammerb83b7b02022-12-21 14:53:41 -05003542 var minSdkVersion bazel.StringAttribute
zhidou133c55b2023-01-31 19:34:10 +00003543 if a.overridableProperties.Min_sdk_version != nil {
3544 minSdkVersion.SetValue(*a.overridableProperties.Min_sdk_version)
Liz Kammerb83b7b02022-12-21 14:53:41 -05003545 }
3546 if props, ok := productVariableProps[minSdkVersionPropName]; ok {
3547 for c, p := range props {
3548 if val, ok := p.(*string); ok {
3549 minSdkVersion.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val)
3550 }
3551 }
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003552 }
3553
3554 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003555 if a.overridableProperties.Key != nil {
3556 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003557 }
3558
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003559 // Certificate
3560 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003561
Yu Liu4ae55d12022-01-05 17:17:23 -08003562 nativeSharedLibs := &convertedNativeSharedLibs{
3563 Native_shared_libs_32: bazel.LabelListAttribute{},
3564 Native_shared_libs_64: bazel.LabelListAttribute{},
3565 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003566
3567 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3568 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3569 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3570 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3571 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003572 if a.CompileMultilib() != nil {
3573 compileMultilib = *a.CompileMultilib()
3574 }
3575
3576 // properties.Native_shared_libs is treated as "both"
3577 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3578 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3579 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3580 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3581 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003582
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003583 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003584 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3585 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3586
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003587 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003588 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003589
Yu Liu4c212ce2022-10-14 12:20:20 -07003590 var testsAttrs bazel.LabelListAttribute
3591 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3592 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3593 testsAttrs = bazel.MakeLabelListAttribute(tests)
3594 }
3595
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003596 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003597 if a.properties.Updatable != nil {
3598 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003599 }
3600
3601 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003602 if a.properties.Installable != nil {
3603 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003604 }
3605
Wei Lif034cb42022-01-19 15:54:31 -08003606 var compressibleAttribute bazel.BoolAttribute
3607 if a.overridableProperties.Compressible != nil {
3608 compressibleAttribute.Value = a.overridableProperties.Compressible
3609 }
3610
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003611 var packageName *string
3612 if a.overridableProperties.Package_name != "" {
3613 packageName = &a.overridableProperties.Package_name
3614 }
3615
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003616 var loggingParent *string
3617 if a.overridableProperties.Logging_parent != "" {
3618 loggingParent = &a.overridableProperties.Logging_parent
3619 }
3620
Wei Li1c66fc72022-05-09 23:59:14 -07003621 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003622 Manifest: manifestLabelAttribute,
3623 Android_manifest: androidManifestLabelAttribute,
3624 File_contexts: fileContextsLabelAttribute,
3625 Min_sdk_version: minSdkVersion,
3626 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003627 Certificate: certificate,
3628 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003629 Updatable: updatableAttribute,
3630 Installable: installableAttribute,
3631 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3632 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3633 Binaries: binariesLabelListAttribute,
3634 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003635 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003636 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003637 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003638 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003639 }
3640
3641 props := bazel.BazelTargetModuleProperties{
3642 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003643 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003644 }
3645
Wei Li1c66fc72022-05-09 23:59:14 -07003646 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003647}
Yu Liu4ae55d12022-01-05 17:17:23 -08003648
3649// The following conversions are based on this table where the rows are the compile_multilib
3650// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3651// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3652// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3653// should not be compiled.
3654// multib/compile_multilib, 32, 64, both, first
3655// 32, 32/32, none/none, 32/32, none/32
3656// 64, none/none, 64/none, 64/none, 64/none
3657// both, 32/32, 64/none, 32&64/32, 64/32
3658// first, 32/32, 64/none, 64/32, 64/32
3659
3660func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3661 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3662 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3663 switch compileMultilb {
3664 case "both", "32":
3665 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3666 case "first":
3667 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3668 case "64":
3669 // Incompatible, ignore
3670 default:
3671 invalidCompileMultilib(ctx, compileMultilb)
3672 }
3673}
3674
3675func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3676 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3677 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3678 switch compileMultilb {
3679 case "both", "64", "first":
3680 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3681 case "32":
3682 // Incompatible, ignore
3683 default:
3684 invalidCompileMultilib(ctx, compileMultilb)
3685 }
3686}
3687
3688func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3689 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3690 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3691 switch compileMultilb {
3692 case "both":
3693 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3694 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3695 case "first":
3696 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3697 case "32":
3698 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3699 case "64":
3700 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3701 default:
3702 invalidCompileMultilib(ctx, compileMultilb)
3703 }
3704}
3705
3706func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3707 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3708 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3709 switch compileMultilb {
3710 case "both", "first":
3711 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3712 case "32":
3713 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3714 case "64":
3715 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3716 default:
3717 invalidCompileMultilib(ctx, compileMultilb)
3718 }
3719}
3720
3721func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3722 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3723 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3724}
3725
3726func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3727 list := bazel.LabelListAttribute{}
3728 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3729 nativeSharedLibs.Native_shared_libs_32.Append(list)
3730}
3731
3732func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3733 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3734 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3735}
3736
3737func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3738 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3739 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3740}
3741
3742func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3743 labelListAttr *bazel.LabelListAttribute) {
3744 list := bazel.LabelListAttribute{}
3745 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3746 labelListAttr.Append(list)
3747}
3748
3749func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3750 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3751}