blob: b039d0dadc2f24888d440f453219a8affe4170c9 [file] [log] [blame]
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090015// package apex implements build rules for creating the APEX files which are container for
16// lower-level system components. See https://source.android.com/devices/tech/ota/apex
Jiyong Park48ca7dc2018-10-10 14:01:00 +090017package apex
18
19import (
20 "fmt"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090021 "path/filepath"
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +000022 "regexp"
Jiyong Parkab3ceb32018-10-10 14:05:29 +090023 "sort"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090024 "strings"
25
Yu Liu4c212ce2022-10-14 12:20:20 -070026 "android/soong/bazel/cquery"
27
Jiyong Park48ca7dc2018-10-10 14:01:00 +090028 "github.com/google/blueprint"
Alex Light778127a2019-02-27 14:19:50 -080029 "github.com/google/blueprint/bootstrap"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090030 "github.com/google/blueprint/proptools"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070031
32 "android/soong/android"
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -040033 "android/soong/bazel"
markchien2f59ec92020-09-02 16:23:38 +080034 "android/soong/bpf"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070035 "android/soong/cc"
36 prebuilt_etc "android/soong/etc"
Jiyong Park12a719c2021-01-07 15:31:24 +090037 "android/soong/filesystem"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070038 "android/soong/java"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090039 "android/soong/multitree"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070040 "android/soong/python"
Jiyong Park99644e92020-11-17 22:21:02 +090041 "android/soong/rust"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070042 "android/soong/sh"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090043)
44
Jiyong Park8e6d52f2020-11-19 14:37:47 +090045func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000046 registerApexBuildComponents(android.InitRegistrationContext)
47}
Jiyong Park8e6d52f2020-11-19 14:37:47 +090048
Paul Duffin667893c2021-03-09 22:34:13 +000049func registerApexBuildComponents(ctx android.RegistrationContext) {
50 ctx.RegisterModuleType("apex", BundleFactory)
Yu Liu4c212ce2022-10-14 12:20:20 -070051 ctx.RegisterModuleType("apex_test", TestApexBundleFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000052 ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
53 ctx.RegisterModuleType("apex_defaults", defaultsFactory)
54 ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
Wei Li1c66fc72022-05-09 23:59:14 -070055 ctx.RegisterModuleType("override_apex", OverrideApexFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000056 ctx.RegisterModuleType("apex_set", apexSetFactory)
57
Paul Duffin5dda3e32021-05-05 14:13:27 +010058 ctx.PreArchMutators(registerPreArchMutators)
Paul Duffin667893c2021-03-09 22:34:13 +000059 ctx.PreDepsMutators(RegisterPreDepsMutators)
60 ctx.PostDepsMutators(RegisterPostDepsMutators)
Jiyong Park8e6d52f2020-11-19 14:37:47 +090061}
62
Paul Duffin5dda3e32021-05-05 14:13:27 +010063func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
64 ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
65}
66
Jiyong Park8e6d52f2020-11-19 14:37:47 +090067func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
68 ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
69 ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
70}
71
72func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
Paul Duffin949abc02020-12-08 10:34:30 +000073 ctx.TopDown("apex_info", apexInfoMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090074 ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
75 ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
76 ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
Paul Duffin28bf7ee2021-05-12 16:41:35 +010077 // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
78 // it should create a platform variant.
79 ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090080 ctx.BottomUp("apex", apexMutator).Parallel()
81 ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
82 ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
Spandan Das66773252022-01-15 00:23:18 +000083 // Register after apex_info mutator so that it can use ApexVariationName
84 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090085}
86
87type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090088 // Json manifest file describing meta info of this APEX bundle. Refer to
89 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090090 Manifest *string `android:"path"`
91
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090092 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
93 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090094 AndroidManifest *string `android:"path"`
95
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090096 // Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
97 // device (/apex/<apex_name>). If unspecified, follows the name property.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090098 Apex_name *string
99
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900100 // Determines the file contexts file for setting the security contexts to files in this APEX
101 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
102 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900103 File_contexts *string `android:"path"`
104
Jiyong Park038e8522021-12-13 23:56:35 +0900105 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
106 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
107 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
108 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
109 // capability. If this property is not set, or a file is missing in the file, default config
110 // is used.
111 Canned_fs_config *string `android:"path"`
112
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900113 ApexNativeDependencies
114
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900115 Multilib apexMultilibProperties
116
Sundong Ahn80c04892021-11-23 00:57:19 +0000117 // List of sh binaries that are embedded inside this APEX bundle.
118 Sh_binaries []string
119
Paul Duffin3abc1742021-03-15 19:32:23 +0000120 // List of platform_compat_config files that are embedded inside this APEX bundle.
121 Compat_configs []string
122
Jiyong Park12a719c2021-01-07 15:31:24 +0900123 // List of filesystem images that are embedded inside this APEX bundle.
124 Filesystems []string
125
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900126 // The minimum SDK version that this APEX must support at minimum. This is usually set to
127 // the SDK version that the APEX was first introduced.
128 Min_sdk_version *string
129
130 // Whether this APEX is considered updatable or not. When set to true, this will enforce
131 // additional rules for making sure that the APEX is truly updatable. To be updatable,
132 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000133 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900134 Updatable *bool
135
Jiyong Parkf4020582021-11-29 12:37:10 +0900136 // Marks that this APEX is designed to be updatable in the future, although it's not
137 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
138 // updatable APEXes. Currently, this disables the size optimization, so that the size of
139 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
140 // false.
141 Future_updatable *bool
142
Jiyong Park1bc84122021-06-22 20:23:05 +0900143 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
144 // false`. Default is false.
145 Platform_apis *bool
146
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900147 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
148 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900149 Installable *bool
150
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900151 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
152 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
153 Use_vndk_as_stable *bool
154
Daniel Norman6cfb37af2021-11-16 20:28:29 +0000155 // Whether this is multi-installed APEX should skip installing symbol files.
156 // Multi-installed APEXes share the same apex_name and are installed at the same time.
157 // Default is false.
158 //
159 // Should be set to true for all multi-installed APEXes except the singular
160 // default version within the multi-installed group.
161 // Only the default version can install symbol files in $(PRODUCT_OUT}/apex,
162 // or else conflicting build rules may be created.
163 Multi_install_skip_symbol_files *bool
164
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900165 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
166 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
167 // container. When set to zip, contents are stored in a zip container directly. This type is
168 // mostly for host-side debugging. When set to both, the two types are both built. Default
169 // is 'image'.
170 Payload_type *string
171
Huang Jianan13cac632021-08-02 15:02:17 +0800172 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
173 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900174 Payload_fs_type *string
175
176 // For telling the APEX to ignore special handling for system libraries such as bionic.
177 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900178 Ignore_system_library_special_case *bool
179
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100180 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100181 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100182 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900183
184 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
185 // used in tests.
186 Test_only_unsigned_payload *bool
187
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000188 // Whenever apex should be compressed, regardless of product flag used. Should be only
189 // used in tests.
190 Test_only_force_compression *bool
191
Jooyung Han09c11ad2021-10-27 03:45:31 +0900192 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
193 // with the tool to sign payload contents.
194 Custom_sign_tool *string
195
Dennis Shenaf41bc12022-08-03 16:46:43 +0000196 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
197 // in a special way that include the digest of the lib file under /lib(64)?
198 Dynamic_common_lib_apex *bool
199
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100200 // Canonical name of this APEX bundle. Used to determine the path to the
201 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
202 // apex mutator variations. For override_apex modules, this is the name of the
203 // overridden base module.
204 ApexVariationName string `blueprint:"mutated"`
205
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900206 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900207
208 // List of sanitizer names that this APEX is enabled for
209 SanitizerNames []string `blueprint:"mutated"`
210
211 PreventInstall bool `blueprint:"mutated"`
212
213 HideFromMake bool `blueprint:"mutated"`
214
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900215 // Internal package method for this APEX. When payload_type is image, this can be either
216 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
217 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900218 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900219}
220
221type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900222 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900223 Native_shared_libs []string
224
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900225 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900226 Jni_libs []string
227
Jiyong Park99644e92020-11-17 22:21:02 +0900228 // List of rust dyn libraries
229 Rust_dyn_libs []string
230
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900231 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900232 Binaries []string
233
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900234 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900235 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900236
237 // List of filesystem images that are embedded inside this APEX bundle.
238 Filesystems []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900239}
240
241type apexMultilibProperties struct {
242 // Native dependencies whose compile_multilib is "first"
243 First ApexNativeDependencies
244
245 // Native dependencies whose compile_multilib is "both"
246 Both ApexNativeDependencies
247
248 // Native dependencies whose compile_multilib is "prefer32"
249 Prefer32 ApexNativeDependencies
250
251 // Native dependencies whose compile_multilib is "32"
252 Lib32 ApexNativeDependencies
253
254 // Native dependencies whose compile_multilib is "64"
255 Lib64 ApexNativeDependencies
256}
257
258type apexTargetBundleProperties struct {
259 Target struct {
260 // Multilib properties only for android.
261 Android struct {
262 Multilib apexMultilibProperties
263 }
264
265 // Multilib properties only for host.
266 Host struct {
267 Multilib apexMultilibProperties
268 }
269
270 // Multilib properties only for host linux_bionic.
271 Linux_bionic struct {
272 Multilib apexMultilibProperties
273 }
274
275 // Multilib properties only for host linux_glibc.
276 Linux_glibc struct {
277 Multilib apexMultilibProperties
278 }
279 }
280}
281
Jiyong Park59140302020-12-14 18:44:04 +0900282type apexArchBundleProperties struct {
283 Arch struct {
284 Arm struct {
285 ApexNativeDependencies
286 }
287 Arm64 struct {
288 ApexNativeDependencies
289 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700290 Riscv64 struct {
291 ApexNativeDependencies
292 }
Jiyong Park59140302020-12-14 18:44:04 +0900293 X86 struct {
294 ApexNativeDependencies
295 }
296 X86_64 struct {
297 ApexNativeDependencies
298 }
299 }
300}
301
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900302// These properties can be used in override_apex to override the corresponding properties in the
303// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900304type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900305 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900306 Apps []string
307
Daniel Norman5a3ce132021-08-26 15:44:43 -0700308 // List of prebuilt files that are embedded inside this APEX bundle.
309 Prebuilts []string
310
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900311 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900312 Rros []string
313
markchien7c803b82021-08-26 22:10:06 +0800314 // List of BPF programs inside this APEX bundle.
315 Bpfs []string
316
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900317 // List of bootclasspath fragments that are embedded inside this APEX bundle.
318 Bootclasspath_fragments []string
319
320 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
321 Systemserverclasspath_fragments []string
322
323 // List of java libraries that are embedded inside this APEX bundle.
324 Java_libs []string
325
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900326 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
327 // Soong). This does not completely prevent installation of the overridden binaries, but if
328 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
329 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900330 Overrides []string
331
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900332 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900333 Logging_parent string
334
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900335 // Apex Container package name. Override value for attribute package:name in
336 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900337 Package_name string
338
339 // A txt file containing list of files that are allowed to be included in this APEX.
340 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700341
342 // Name of the apex_key module that provides the private key to sign this APEX bundle.
343 Key *string
344
345 // Specifies the certificate and the private key to sign the zip container of this APEX. If
346 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
347 // as the certificate and the private key, respectively. If this is ":module", then the
348 // certificate and the private key are provided from the android_app_certificate module
349 // named "module".
350 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400351
352 // Whether this APEX can be compressed or not. Setting this property to false means this
353 // APEX will never be compressed. When set to true, APEX will be compressed if other
354 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
355 // Default: false.
356 Compressible *bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900357}
358
359type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900360 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900361 android.ModuleBase
362 android.DefaultableModuleBase
363 android.OverridableModuleBase
364 android.SdkBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400365 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900366 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900367
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900368 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900369 properties apexBundleProperties
370 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900371 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900372 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900373 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900374
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900375 ///////////////////////////////////////////////////////////////////////////////////////////
376 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900377
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900378 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800379 publicKeyFile android.Path
380 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900381
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900382 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800383 containerCertificateFile android.Path
384 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900385
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900386 // Flags for special variants of APEX
387 testApex bool
388 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900389
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900390 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
391 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900392 primaryApexType bool
393
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900394 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900395 suffix string
396
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900397 // File system type of apex_payload.img
398 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900399
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900400 // Whether to create symlink to the system file instead of having a file inside the apex or
401 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900402 linkToSystemLib bool
403
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900404 // List of files to be included in this APEX. This is filled in the first part of
405 // GenerateAndroidBuildActions.
406 filesInfo []apexFile
407
408 // List of other module names that should be installed when this APEX gets installed.
409 requiredDeps []string
410
411 ///////////////////////////////////////////////////////////////////////////////////////////
412 // Outputs (final and intermediates)
413
414 // Processed apex manifest in JSONson format (for Q)
415 manifestJsonOut android.WritablePath
416
417 // Processed apex manifest in PB format (for R+)
418 manifestPbOut android.WritablePath
419
420 // Processed file_contexts files
421 fileContexts android.WritablePath
422
Bob Badourde6a0872022-04-01 18:00:00 +0000423 // Path to notice file in html.gz format.
424 htmlGzNotice android.WritablePath
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900425
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900426 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900427 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900428 outputFile android.WritablePath
429
Jooyung Hana6d36672022-02-24 13:58:07 +0900430 // The built uncompressed .apex file.
431 outputApexFile android.WritablePath
432
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900433 // The built APEX file in app bundle format. This file is not directly installed to the
434 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
435 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
436 // system) to be merged into a single app bundle file that Play accepts. See
437 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
438 bundleModuleFile android.WritablePath
439
Colin Cross6340ea52021-11-04 12:01:18 -0700440 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900441 installDir android.InstallPath
442
Colin Cross6340ea52021-11-04 12:01:18 -0700443 // Path where this APEX was installed.
444 installedFile android.InstallPath
445
446 // Installed locations of symlinks for backward compatibility.
447 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900448
449 // Text file having the list of individual files that are included in this APEX. Used for
450 // debugging purpose.
451 installedFilesFile android.WritablePath
452
453 // List of module names that this APEX is including (to be shown via *-deps-info target).
454 // Used for debugging purpose.
455 android.ApexBundleDepsInfo
456
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900457 // Optional list of lint report zip files for apexes that contain java or app modules
458 lintReports android.Paths
459
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900460 prebuiltFileToDelete string
sophiezc80a2b32020-11-12 16:39:19 +0000461
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000462 isCompressed bool
463
sophiezc80a2b32020-11-12 16:39:19 +0000464 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700465 nativeApisUsedByModuleFile android.ModuleOutPath
466 nativeApisBackedByModuleFile android.ModuleOutPath
467 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800468
469 // Collect the module directory for IDE info in java/jdeps.go.
470 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900471}
472
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900473// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900474type apexFileClass int
475
Jooyung Han72bd2f82019-10-23 16:46:38 +0900476const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900477 app apexFileClass = iota
478 appSet
479 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900480 goBinary
481 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900482 nativeExecutable
483 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900484 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900485 pyBinary
486 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900487)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900488
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900489// apexFile represents a file in an APEX bundle. This is created during the first half of
490// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
491// of the function, this is used to create commands that copies the files into a staging directory,
492// where they are packaged into the APEX file. This struct is also used for creating Make modules
493// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900494type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900495 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000496 builtFile android.Path
497 installDir string
498 customStem string
499 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900500
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900501 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
502 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
503 // suffix>]
504 androidMkModuleName string // becomes LOCAL_MODULE
505 class apexFileClass // becomes LOCAL_MODULE_CLASS
506 moduleDir string // becomes LOCAL_PATH
507 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
508 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
509 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
510 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900511
512 jacocoReportClassesFile android.Path // only for javalibs and apps
513 lintDepSets java.LintDepSets // only for javalibs and apps
514 certificate java.Certificate // only for apps
515 overriddenPackageName string // only for apps
516
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900517 transitiveDep bool
518 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900519
Jiyong Park57621b22021-01-20 20:33:11 +0900520 multilib string
521
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900522 // TODO(jiyong): remove this
523 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900524}
525
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900526// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900527func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
528 ret := apexFile{
529 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900530 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900531 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900532 class: class,
533 module: module,
534 }
535 if module != nil {
536 ret.moduleDir = ctx.OtherModuleDir(module)
537 ret.requiredModuleNames = module.RequiredModuleNames()
538 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
539 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900540 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900541 }
542 return ret
543}
544
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900545func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900546 return af.builtFile != nil && af.builtFile.String() != ""
547}
548
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900549// apexRelativePath returns the relative path of the given path from the install directory of this
550// apexFile.
551// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900552func (af *apexFile) apexRelativePath(path string) string {
553 return filepath.Join(af.installDir, path)
554}
555
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900556// path returns path of this apex file relative to the APEX root
557func (af *apexFile) path() string {
558 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900559}
560
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900561// stem returns the base filename of this apex file
562func (af *apexFile) stem() string {
563 if af.customStem != "" {
564 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900565 }
566 return af.builtFile.Base()
567}
568
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900569// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
570func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900571 var ret []string
572 for _, symlink := range af.symlinks {
573 ret = append(ret, af.apexRelativePath(symlink))
574 }
575 return ret
576}
577
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900578// availableToPlatform tests whether this apexFile is from a module that can be installed to the
579// platform.
580func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900581 if af.module == nil {
582 return false
583 }
584 if am, ok := af.module.(android.ApexModule); ok {
585 return am.AvailableFor(android.AvailableToPlatform)
586 }
587 return false
588}
589
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900590////////////////////////////////////////////////////////////////////////////////////////////////////
591// Mutators
592//
593// Brief description about mutators for APEX. The following three mutators are the most important
594// ones.
595//
596// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
597// to the (direct) dependencies of this APEX bundle.
598//
Paul Duffin949abc02020-12-08 10:34:30 +0000599// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900600// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
601// modules are marked as being included in the APEX via BuildForApex().
602//
Paul Duffin949abc02020-12-08 10:34:30 +0000603// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
604// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900605
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900606type dependencyTag struct {
607 blueprint.BaseDependencyTag
608 name string
609
610 // Determines if the dependent will be part of the APEX payload. Can be false for the
611 // dependencies to the signing key module, etc.
612 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000613
614 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
615 // replacement. This is needed because some prebuilt modules do not provide all the information
616 // needed by the apex.
617 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000618
619 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
620 // also be added as exported members of that SDK.
621 memberType android.SdkMemberType
622}
623
624func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
625 return d.memberType
626}
627
628func (d *dependencyTag) ExportMember() bool {
629 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900630}
631
Paul Duffin520917a2022-05-13 13:01:59 +0000632func (d *dependencyTag) String() string {
633 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
634}
635
636func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000637 return !d.sourceOnly
638}
639
640var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000641var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000642
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900643var (
Paul Duffin520917a2022-05-13 13:01:59 +0000644 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
645 bpfTag = &dependencyTag{name: "bpf", payload: true}
646 certificateTag = &dependencyTag{name: "certificate"}
647 executableTag = &dependencyTag{name: "executable", payload: true}
648 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000649 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
650 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000651 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000652 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
653 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
654 keyTag = &dependencyTag{name: "key"}
655 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
656 rroTag = &dependencyTag{name: "rro", payload: true}
657 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
658 testForTag = &dependencyTag{name: "test for"}
659 testTag = &dependencyTag{name: "test", payload: true}
660 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900661)
662
663// TODO(jiyong): shorten this function signature
664func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900665 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900666 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900667 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900668
669 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900670 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900671 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
672 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900673 }
674
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900675 // Use *FarVariation* to be able to depend on modules having conflicting variations with
676 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
677 // 'arm' or 'arm64' for native shared libs.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900678 ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900679 ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900680 ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
681 ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
Jiyong Park99644e92020-11-17 22:21:02 +0900682 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
Jiyong Park06711462021-02-15 17:54:43 +0900683 ctx.AddFarVariationDependencies(target.Variations(), fsTag, nativeModules.Filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900684}
685
686func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900687 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900688 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
689 } else {
690 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
691 if ctx.Os().Bionic() {
692 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
693 } else {
694 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
695 }
696 }
697}
698
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900699// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
700// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
701func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
702 deviceConfig := ctx.DeviceConfig()
703 if a.vndkApex {
704 return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900705 }
706
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900707 var prefix string
708 var vndkVersion string
709 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000710 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900711 prefix = cc.VendorVariationPrefix
712 vndkVersion = deviceConfig.VndkVersion()
713 } else if a.ProductSpecific() {
714 prefix = cc.ProductVariationPrefix
715 vndkVersion = deviceConfig.ProductVndkVersion()
716 }
717 }
718 if vndkVersion == "current" {
719 vndkVersion = deviceConfig.PlatformVndkVersion()
720 }
721 if vndkVersion != "" {
722 return prefix + vndkVersion
723 }
724
725 return android.CoreVariation // The usual case
726}
727
728func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900729 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
730 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
731 // each target os/architectures, appropriate dependencies are selected by their
732 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900733 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900734 imageVariation := a.getImageVariation(ctx)
735
736 a.combineProperties(ctx)
737
738 has32BitTarget := false
739 for _, target := range targets {
740 if target.Arch.ArchType.Multilib == "lib32" {
741 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000742 }
743 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900744 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900745 // Don't include artifacts for the host cross targets because there is no way for us
746 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900747 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900748 continue
749 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000750
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900751 var depsList []ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000752
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900753 // Add native modules targeting both ABIs. When multilib.* is omitted for
754 // native_shared_libs/jni_libs/tests, it implies multilib.both
755 depsList = append(depsList, a.properties.Multilib.Both)
756 depsList = append(depsList, ApexNativeDependencies{
757 Native_shared_libs: a.properties.Native_shared_libs,
758 Tests: a.properties.Tests,
759 Jni_libs: a.properties.Jni_libs,
760 Binaries: nil,
761 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900762
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900763 // Add native modules targeting the first ABI When multilib.* is omitted for
764 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900765 isPrimaryAbi := i == 0
766 if isPrimaryAbi {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900767 depsList = append(depsList, a.properties.Multilib.First)
768 depsList = append(depsList, ApexNativeDependencies{
769 Native_shared_libs: nil,
770 Tests: nil,
771 Jni_libs: nil,
772 Binaries: a.properties.Binaries,
773 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900774 }
775
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900776 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900777 switch target.Arch.ArchType.Multilib {
778 case "lib32":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900779 depsList = append(depsList, a.properties.Multilib.Lib32)
780 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900781 case "lib64":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900782 depsList = append(depsList, a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900783 if !has32BitTarget {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900784 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900785 }
786 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900787
Jiyong Park59140302020-12-14 18:44:04 +0900788 // Add native modules targeting a specific arch variant
789 switch target.Arch.ArchType {
790 case android.Arm:
791 depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
792 case android.Arm64:
793 depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700794 case android.Riscv64:
795 depsList = append(depsList, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900796 case android.X86:
797 depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
798 case android.X86_64:
799 depsList = append(depsList, a.archProperties.Arch.X86_64.ApexNativeDependencies)
800 default:
801 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
802 }
803
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900804 for _, d := range depsList {
805 addDependenciesForNativeModules(ctx, d, target, imageVariation)
806 }
Sundong Ahn80c04892021-11-23 00:57:19 +0000807 ctx.AddFarVariationDependencies([]blueprint.Variation{
808 {Mutator: "os", Variation: target.OsVariation()},
809 {Mutator: "arch", Variation: target.ArchVariation()},
810 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900811 }
812
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900813 // Common-arch dependencies come next
814 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900815 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000816 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100817}
818
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900819// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900820func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
821 if a.overridableProperties.Allowed_files != nil {
822 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100823 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900824
825 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
826 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800827 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900828 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900829 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
830 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
831 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700832 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
833 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
834 // regardless of the TARGET_PREFER_* setting. See b/144532908
835 arches := ctx.DeviceConfig().Arches()
836 if len(arches) != 0 {
837 archForPrebuiltEtc := arches[0]
838 for _, arch := range arches {
839 // Prefer 64-bit arch if there is any
840 if arch.ArchType.Multilib == "lib64" {
841 archForPrebuiltEtc = arch
842 break
843 }
844 }
845 ctx.AddFarVariationDependencies([]blueprint.Variation{
846 {Mutator: "os", Variation: ctx.Os().String()},
847 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
848 }, prebuiltTag, prebuilts...)
849 }
850 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700851
852 // Dependencies for signing
853 if String(a.overridableProperties.Key) == "" {
854 ctx.PropertyErrorf("key", "missing")
855 return
856 }
857 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
858
859 cert := android.SrcIsModule(a.getCertString(ctx))
860 if cert != "" {
861 ctx.AddDependency(ctx.Module(), certificateTag, cert)
862 // empty cert is not an error. Cert and private keys will be directly found under
863 // PRODUCT_DEFAULT_DEV_CERTIFICATE
864 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100865}
866
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900867type ApexBundleInfo struct {
868 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100869}
870
Paul Duffin949abc02020-12-08 10:34:30 +0000871var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900872
Paul Duffina7d6a892020-12-07 17:39:59 +0000873var _ ApexInfoMutator = (*apexBundle)(nil)
874
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100875func (a *apexBundle) ApexVariationName() string {
876 return a.properties.ApexVariationName
877}
878
Paul Duffina7d6a892020-12-07 17:39:59 +0000879// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900880// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
881// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
882// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
883// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000884//
885// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
886// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
887// The apexMutator uses that list to create module variants for the apexes to which it belongs.
888// The relationship between module variants and apexes is not one-to-one as variants will be
889// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000890func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900891
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900892 // The VNDK APEX is special. For the APEX, the membership is described in a very different
893 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
894 // libraries are self-identified by their vndk.enabled properties. There is no need to run
895 // this mutator for the APEX as nothing will be collected. So, let's return fast.
896 if a.vndkApex {
897 return
898 }
899
900 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
901 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
902 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
903 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
904 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900905 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
906 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900907 if proptools.Bool(a.properties.Use_vndk_as_stable) {
908 if !useVndk {
909 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
910 }
911 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
912 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
913 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
914 }
915 })
916 if mctx.Failed() {
917 return
918 }
Jooyung Handf78e212020-07-22 15:54:47 +0900919 }
920
Colin Cross56a83212020-09-15 18:30:11 -0700921 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900922 am, ok := child.(android.ApexModule)
923 if !ok || !am.CanHaveApexVariants() {
924 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900925 }
Paul Duffin573989d2021-03-17 13:25:29 +0000926 depTag := mctx.OtherModuleDependencyTag(child)
927
928 // Check to see if the tag always requires that the child module has an apex variant for every
929 // apex variant of the parent module. If it does not then it is still possible for something
930 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
931 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
932 return true
933 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000934 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900935 return false
936 }
Jooyung Handf78e212020-07-22 15:54:47 +0900937 if excludeVndkLibs {
938 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
939 return false
940 }
941 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900942 // By default, all the transitive dependencies are collected, unless filtered out
943 // above.
Colin Cross56a83212020-09-15 18:30:11 -0700944 return true
945 }
946
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900947 // Records whether a certain module is included in this apexBundle via direct dependency or
948 // inndirect dependency.
949 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -0700950 mctx.WalkDeps(func(child, parent android.Module) bool {
951 if !continueApexDepsWalk(child, parent) {
952 return false
953 }
Jooyung Han698dd9f2020-07-22 15:17:19 +0900954 // If the parent is apexBundle, this child is directly depended.
955 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900956 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -0700957 contents[depName] = contents[depName].Add(directDep)
958 return true
959 })
960
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900961 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +0900962 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -0700963 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
964 Contents: apexContents,
965 })
966
Jooyung Haned124c32021-01-26 11:43:46 +0900967 minSdkVersion := a.minSdkVersion(mctx)
968 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
969 if minSdkVersion.IsNone() {
970 minSdkVersion = android.FutureApiLevel
971 }
972
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900973 // This is the main part of this mutator. Mark the collected dependencies that they need to
974 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +0900975
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100976 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
977 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -0700978 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100979 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +0900980 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -0700981 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +0900982 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100983 InApexVariants: []string{apexVariationName},
984 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -0700985 ApexContents: []*android.ApexContents{apexContents},
986 }
Colin Cross56a83212020-09-15 18:30:11 -0700987 mctx.WalkDeps(func(child, parent android.Module) bool {
988 if !continueApexDepsWalk(child, parent) {
989 return false
990 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900991 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +0900992 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +0900993 })
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900994}
995
Paul Duffina7d6a892020-12-07 17:39:59 +0000996type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100997 // ApexVariationName returns the name of the APEX variation to use in the apex
998 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
999 ApexVariationName() string
1000
Paul Duffina7d6a892020-12-07 17:39:59 +00001001 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1002 // depended upon by an apex and which require an apex specific variant.
1003 ApexInfoMutator(android.TopDownMutatorContext)
1004}
1005
1006// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1007// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001008// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001009func apexInfoMutator(mctx android.TopDownMutatorContext) {
1010 if !mctx.Module().Enabled() {
1011 return
1012 }
1013
1014 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1015 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001016 }
Spandan Das42e89502022-05-06 22:12:55 +00001017 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001018}
1019
Spandan Das66773252022-01-15 00:23:18 +00001020// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1021// This check is enforced for updatable modules
1022func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1023 if !mctx.Module().Enabled() {
1024 return
1025 }
Spandan Das08c911f2022-01-21 22:07:26 +00001026 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001027 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001028 // b/208656169 Do not propagate strict updatability linting to libcore/
1029 // These libs are available on the classpath during compilation
1030 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1031 // Only skip libraries defined in libcore root, not subdirectories
1032 if mctx.OtherModuleDir(child) == "libcore" {
1033 // Do not traverse transitive deps of libcore/ libs
1034 return false
1035 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001036 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1037 return false
1038 }
Spandan Das66773252022-01-15 00:23:18 +00001039 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1040 lintable.SetStrictUpdatabilityLinting(true)
1041 }
1042 // visit transitive deps
1043 return true
1044 })
1045 }
1046}
1047
Spandan Das42e89502022-05-06 22:12:55 +00001048// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1049func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1050 if !mctx.Module().Enabled() {
1051 return
1052 }
1053 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1054 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1055 mctx.VisitDirectDeps(func(module android.Module) {
1056 // ignore android_test_app
1057 if app, ok := module.(*java.AndroidApp); ok {
1058 app.SetUpdatable(true)
1059 }
1060 })
1061 }
1062}
1063
Spandan Das08c911f2022-01-21 22:07:26 +00001064// TODO: b/215736885 Whittle the denylist
1065// Transitive deps of certain mainline modules baseline NewApi errors
1066// Skip these mainline modules for now
1067var (
1068 skipStrictUpdatabilityLintAllowlist = []string{
1069 "com.android.art",
1070 "com.android.art.debug",
1071 "com.android.conscrypt",
1072 "com.android.media",
1073 // test apexes
1074 "test_com.android.art",
1075 "test_com.android.conscrypt",
1076 "test_com.android.media",
1077 "test_jitzygote_com.android.art",
1078 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001079
1080 // TODO: b/215736885 Remove this list
1081 skipLintJavalibAllowlist = []string{
1082 "conscrypt.module.platform.api.stubs",
1083 "conscrypt.module.public.api.stubs",
1084 "conscrypt.module.public.api.stubs.system",
1085 "conscrypt.module.public.api.stubs.module_lib",
1086 "framework-media.stubs",
1087 "framework-media.stubs.system",
1088 "framework-media.stubs.module_lib",
1089 }
Spandan Das08c911f2022-01-21 22:07:26 +00001090)
1091
1092func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1093 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1094}
1095
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001096// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1097// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1098// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001099func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1100 if !mctx.Module().Enabled() {
1101 return
1102 }
1103 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001104 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1105 }
1106}
1107
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001108// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1109// the apex in order to retrieve its contents later.
1110// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001111func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1112 if !mctx.Module().Enabled() {
1113 return
1114 }
Colin Cross56a83212020-09-15 18:30:11 -07001115 if am, ok := mctx.Module().(android.ApexModule); ok {
1116 if testFor := am.TestFor(); len(testFor) > 0 {
1117 mctx.AddFarVariationDependencies([]blueprint.Variation{
1118 {Mutator: "os", Variation: am.Target().OsVariation()},
1119 {"arch", "common"},
1120 }, testForTag, testFor...)
1121 }
1122 }
1123}
1124
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001125// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001126func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1127 if !mctx.Module().Enabled() {
1128 return
1129 }
Colin Cross56a83212020-09-15 18:30:11 -07001130 if _, ok := mctx.Module().(android.ApexModule); ok {
1131 var contents []*android.ApexContents
1132 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1133 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1134 contents = append(contents, abInfo.Contents)
1135 }
1136 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1137 ApexContents: contents,
1138 })
Colin Crossaede88c2020-08-11 12:17:01 -07001139 }
1140}
1141
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001142// markPlatformAvailability marks whether or not a module can be available to platform. A module
1143// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1144// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1145// be) available to platform
1146// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001147func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1148 // Host and recovery are not considered as platform
1149 if mctx.Host() || mctx.Module().InstallInRecovery() {
1150 return
1151 }
1152
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001153 am, ok := mctx.Module().(android.ApexModule)
1154 if !ok {
1155 return
1156 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001157
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001158 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001159
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001160 // If any of the dep is not available to platform, this module is also considered as being
1161 // not available to platform even if it has "//apex_available:platform"
1162 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001163 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001164 // if the dependency crosses apex boundary, don't consider it
1165 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001166 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001167 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1168 availableToPlatform = false
1169 // TODO(b/154889534) trigger an error when 'am' has
1170 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001171 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001172 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001173
Paul Duffinb5769c12021-05-12 16:16:51 +01001174 // Exception 1: check to see if the module always requires it.
1175 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001176 availableToPlatform = true
1177 }
1178
1179 // Exception 2: bootstrap bionic libraries are also always available to platform
1180 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1181 availableToPlatform = true
1182 }
1183
1184 if !availableToPlatform {
1185 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001186 }
1187}
1188
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001189// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001190// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001191func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001192 if !mctx.Module().Enabled() {
1193 return
1194 }
Colin Cross56a83212020-09-15 18:30:11 -07001195
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001196 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001197 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001198 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001199 return
1200 }
1201
1202 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001203 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1204 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001205 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001206 if strings.HasPrefix(apexBundleName, "com.android.art") {
1207 // Create an alias from the platform variant. This is done to make
1208 // test_for dependencies work for modules that are split by the APEX
1209 // mutator, since test_for dependencies always go to the platform variant.
1210 // This doesn't happen for normal APEXes that are disjunct, so only do
1211 // this for the overlapping ART APEXes.
1212 // TODO(b/183882457): Remove this if the test_for functionality is
1213 // refactored to depend on the proper APEX variants instead of platform.
1214 mctx.CreateAliasVariation("", apexBundleName)
1215 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001216 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1217 apexBundleName := o.GetOverriddenModuleName()
1218 if apexBundleName == "" {
1219 mctx.ModuleErrorf("base property is not set")
1220 return
1221 }
1222 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001223 if strings.HasPrefix(apexBundleName, "com.android.art") {
1224 // TODO(b/183882457): See note for CreateAliasVariation above.
1225 mctx.CreateAliasVariation("", apexBundleName)
1226 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001227 }
1228}
Sundong Ahne9b55722019-09-06 17:37:42 +09001229
Paul Duffin6717d882021-06-15 19:09:41 +01001230// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1231// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001232func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001233 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001234 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001235 return !a.vndkApex
1236 }
1237
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001238 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001239}
1240
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001241// See android.UpdateDirectlyInAnyApex
1242// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001243func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1244 if !mctx.Module().Enabled() {
1245 return
1246 }
1247 if am, ok := mctx.Module().(android.ApexModule); ok {
1248 android.UpdateDirectlyInAnyApex(mctx, am)
1249 }
1250}
1251
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001252// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001253type apexPackaging int
1254
1255const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001256 // imageApex is a packaging method where contents are included in a filesystem image which
1257 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001258 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001259
1260 // zipApex is a packaging method where contents are directly included in the zip container.
1261 // This is used for host-side testing - because the contents are easily accessible by
1262 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001263 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001264
1265 // flattendApex is a packaging method where contents are not included in the APEX file, but
1266 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1267 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001268 flattenedApex
1269)
1270
1271const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001272 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001273 imageApexSuffix = ".apex"
1274 imageCapexSuffix = ".capex"
1275 zipApexSuffix = ".zipapex"
1276 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001277
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001278 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001279 imageApexType = "image"
1280 zipApexType = "zip"
1281 flattenedApexType = "flattened"
1282
Dan Willemsen47e1a752021-10-16 18:36:13 -07001283 ext4FsType = "ext4"
1284 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001285 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001286)
1287
1288// The suffix for the output "file", not the module
1289func (a apexPackaging) suffix() string {
1290 switch a {
1291 case imageApex:
1292 return imageApexSuffix
1293 case zipApex:
1294 return zipApexSuffix
1295 default:
1296 panic(fmt.Errorf("unknown APEX type %d", a))
1297 }
1298}
1299
1300func (a apexPackaging) name() string {
1301 switch a {
1302 case imageApex:
1303 return imageApexType
1304 case zipApex:
1305 return zipApexType
1306 default:
1307 panic(fmt.Errorf("unknown APEX type %d", a))
1308 }
1309}
1310
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001311// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1312// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001313func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001314 if !mctx.Module().Enabled() {
1315 return
1316 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001317 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001318 var variants []string
1319 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1320 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001321 // This is the normal case. Note that both image and flattend APEXes are
1322 // created. The image type is installed to the system partition, while the
1323 // flattened APEX is (optionally) installed to the system_ext partition.
1324 // This is mostly for GSI which has to support wide range of devices. If GSI
1325 // is installed on a newer (APEX-capable) device, the image APEX in the
1326 // system will be used. However, if the same GSI is installed on an old
1327 // device which can't support image APEX, the flattened APEX in the
1328 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001329 variants = append(variants, imageApexType, flattenedApexType)
1330 case "zip":
1331 variants = append(variants, zipApexType)
1332 case "both":
1333 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1334 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001335 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001336 return
1337 }
1338
1339 modules := mctx.CreateLocalVariations(variants...)
1340
1341 for i, v := range variants {
1342 switch v {
1343 case imageApexType:
1344 modules[i].(*apexBundle).properties.ApexType = imageApex
1345 case zipApexType:
1346 modules[i].(*apexBundle).properties.ApexType = zipApex
1347 case flattenedApexType:
1348 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001349 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001350 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001351 modules[i].(*apexBundle).MakeAsSystemExt()
1352 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001353 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001354 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001355 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001356 // payload_type is forcibly overridden to "image"
1357 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001358 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001359 }
1360}
1361
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001362var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001363
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001364// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001365func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001366 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001367 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001368 return true
1369}
1370
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001371var _ android.OutputFileProducer = (*apexBundle)(nil)
1372
1373// Implements android.OutputFileProducer
1374func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1375 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001376 case "", android.DefaultDistTag:
1377 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001378 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001379 case imageApexSuffix:
1380 // uncompressed one
1381 if a.outputApexFile != nil {
1382 return android.Paths{a.outputApexFile}, nil
1383 }
1384 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001385 default:
1386 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1387 }
1388}
1389
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001390var _ multitree.Exportable = (*apexBundle)(nil)
1391
1392func (a *apexBundle) Exportable() bool {
1393 if a.properties.ApexType == flattenedApex {
1394 return false
1395 }
1396 return true
1397}
1398
1399func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1400 ret := make(map[string]android.Paths)
1401 ret["apex"] = android.Paths{a.outputFile}
1402 return ret
1403}
1404
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001405var _ cc.Coverage = (*apexBundle)(nil)
1406
1407// Implements cc.Coverage
1408func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1409 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1410}
1411
1412// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001413func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001414 a.properties.PreventInstall = true
1415}
1416
1417// Implements cc.Coverage
1418func (a *apexBundle) HideFromMake() {
1419 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001420 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1421 // TODO(ccross): untangle these
1422 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001423}
1424
1425// Implements cc.Coverage
1426func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1427 a.properties.IsCoverageVariant = coverage
1428}
1429
1430// Implements cc.Coverage
1431func (a *apexBundle) EnableCoverageIfNeeded() {}
1432
1433var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1434
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001435// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001436func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001437 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001438}
1439
Jiyong Parkf4020582021-11-29 12:37:10 +09001440func (a *apexBundle) FutureUpdatable() bool {
1441 return proptools.BoolDefault(a.properties.Future_updatable, false)
1442}
1443
Jiyong Park1bc84122021-06-22 20:23:05 +09001444func (a *apexBundle) UsePlatformApis() bool {
1445 return proptools.BoolDefault(a.properties.Platform_apis, false)
1446}
1447
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001448// getCertString returns the name of the cert that should be used to sign this APEX. This is
1449// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001450func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001451 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001452 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1453 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1454 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001455 if a.vndkApex {
1456 moduleName = vndkApexName
1457 }
1458 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001459 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001460 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001461 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001462 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001463}
1464
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001465// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001466func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001467 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001468}
1469
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001470// See the generate_hashtree property
1471func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001472 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001473}
1474
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001475// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001476func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1477 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1478}
1479
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001480// See the test_only_force_compression property
1481func (a *apexBundle) testOnlyShouldForceCompression() bool {
1482 return proptools.Bool(a.properties.Test_only_force_compression)
1483}
1484
Dennis Shenaf41bc12022-08-03 16:46:43 +00001485// See the dynamic_common_lib_apex property
1486func (a *apexBundle) dynamic_common_lib_apex() bool {
1487 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1488}
1489
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001490// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1491// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1492// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001493
Jiyong Parkf97782b2019-02-13 20:28:58 +09001494func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1495 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1496 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1497 }
1498}
1499
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001500func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001501 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1502 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001503 }
1504
1505 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001506 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001507 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001508 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001509 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001510 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001511 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001512 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001513 }
1514 }
1515 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001516}
1517
Jooyung Han8ce8db92020-05-15 19:05:05 +09001518func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001519 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1520 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001521 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001522 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001523 for _, target := range ctx.MultiTargets() {
1524 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001525 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001526 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001527 Tests: nil,
1528 Jni_libs: nil,
1529 Binaries: nil,
1530 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001531 break
1532 }
1533 }
1534 }
1535}
1536
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001537// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1538// returned apexFile saves information about the Soong module that will be used for creating the
1539// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001540func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001541 // Decide the APEX-local directory by the multilib of the library In the future, we may
1542 // query this to the module.
1543 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001544 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001545 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001546 case "lib32":
1547 dirInApex = "lib"
1548 case "lib64":
1549 dirInApex = "lib64"
1550 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001551 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001552 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001553 }
Jooyung Han35155c42020-02-06 17:33:20 +09001554 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001555 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001556 // Special case for Bionic libs and other libs installed with them. This is to
1557 // prevent those libs from being included in the search path
1558 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1559 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1560 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1561 // will be loaded into the default linker namespace (aka "platform" namespace). If
1562 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1563 // be loaded again into the runtime linker namespace, which will result in double
1564 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001565 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001566 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001567
Colin Cross1d487152022-10-03 19:14:46 -07001568 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001569 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1570 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001571}
1572
Jiyong Park1833cef2019-12-13 13:28:36 +09001573func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001574 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001575 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001576 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001577 }
Jooyung Han35155c42020-02-06 17:33:20 +09001578 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001579 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001580 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1581 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001582 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001583 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001584 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001585}
1586
Jiyong Park99644e92020-11-17 22:21:02 +09001587func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1588 dirInApex := "bin"
1589 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1590 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1591 }
Colin Cross1d487152022-10-03 19:14:46 -07001592 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001593 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1594 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1595 return af
1596}
1597
1598func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1599 // Decide the APEX-local directory by the multilib of the library
1600 // In the future, we may query this to the module.
1601 var dirInApex string
1602 switch rustm.Arch().ArchType.Multilib {
1603 case "lib32":
1604 dirInApex = "lib"
1605 case "lib64":
1606 dirInApex = "lib64"
1607 }
1608 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1609 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1610 }
Colin Cross1d487152022-10-03 19:14:46 -07001611 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001612 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1613 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1614}
1615
Jiyong Park1833cef2019-12-13 13:28:36 +09001616func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001617 dirInApex := "bin"
1618 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001619 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001620}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001621
Jiyong Park1833cef2019-12-13 13:28:36 +09001622func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001623 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001624 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001625 // NB: Since go binaries are static we don't need the module for anything here, which is
1626 // good since the go tool is a blueprint.Module not an android.Module like we would
1627 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001628 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001629}
1630
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001631func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001632 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001633 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1634 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1635 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001636 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001637 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001638 af.symlinks = sh.Symlinks()
1639 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001640}
1641
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001642func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001643 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001644 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001645 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001646}
1647
atrost6e126252020-01-27 17:01:16 +00001648func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1649 dirInApex := filepath.Join("etc", config.SubDir())
1650 fileToCopy := config.CompatConfig()
1651 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1652}
1653
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001654// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1655// way.
1656type javaModule interface {
1657 android.Module
1658 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001659 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001660 JacocoReportClassesFile() android.Path
1661 LintDepSets() java.LintDepSets
1662 Stem() string
1663}
1664
1665var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001666var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001667var _ javaModule = (*java.SdkLibrary)(nil)
1668var _ javaModule = (*java.DexImport)(nil)
1669var _ javaModule = (*java.SdkLibraryImport)(nil)
1670
Paul Duffin190fdef2021-04-26 10:33:59 +01001671// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001672func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001673 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001674}
1675
1676// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1677func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001678 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001679 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001680 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1681 af.lintDepSets = module.LintDepSets()
1682 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001683 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1684 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1685 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1686 }
1687 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001688 return af
1689}
1690
1691// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1692// the same way.
1693type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001694 android.Module
1695 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001696 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001697 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001698 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001699 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001700 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001701 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001702}
1703
1704var _ androidApp = (*java.AndroidApp)(nil)
1705var _ androidApp = (*java.AndroidAppImport)(nil)
1706
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001707func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1708 buildId := ctx.Config().BuildId()
1709
1710 // The build ID is used as a suffix for a filename, so ensure that
1711 // the set of characters being used are sanitized.
1712 // - any word character: [a-zA-Z0-9_]
1713 // - dots: .
1714 // - dashes: -
1715 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1716 if !validRegex.MatchString(buildId) {
1717 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1718 }
1719 return buildId
1720}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001721
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001722func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001723 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001724 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001725 appDir = "priv-app"
1726 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001727
1728 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1729 // so that PackageManager correctly invalidates the existing installed apk
1730 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001731 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001732 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001733
Yo Chiange8128052020-07-23 20:09:18 +08001734 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001735 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001736 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001737 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001738
1739 if app, ok := aapp.(interface {
1740 OverriddenManifestPackageName() string
1741 }); ok {
1742 af.overriddenPackageName = app.OverriddenManifestPackageName()
1743 }
Jiyong Park618922e2020-01-08 13:35:43 +09001744 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001745}
1746
Jiyong Park69aeba92020-04-24 21:16:36 +09001747func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1748 rroDir := "overlay"
1749 dirInApex := filepath.Join(rroDir, rro.Theme())
1750 fileToCopy := rro.OutputFile()
1751 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1752 af.certificate = rro.Certificate()
1753
1754 if a, ok := rro.(interface {
1755 OverriddenManifestPackageName() string
1756 }); ok {
1757 af.overriddenPackageName = a.OverriddenManifestPackageName()
1758 }
1759 return af
1760}
1761
Ken Chenfad7f9d2021-11-10 22:02:57 +08001762func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1763 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001764 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1765}
1766
Jiyong Park12a719c2021-01-07 15:31:24 +09001767func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1768 dirInApex := filepath.Join("etc", "fs")
1769 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1770}
1771
Paul Duffin064b70c2020-11-02 17:32:38 +00001772// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001773// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1774// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1775// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001776func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001777 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001778 am, ok := child.(android.ApexModule)
1779 if !ok || !am.CanHaveApexVariants() {
1780 return false
1781 }
1782
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001783 // Filter-out unwanted depedendencies
1784 depTag := ctx.OtherModuleDependencyTag(child)
1785 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1786 return false
1787 }
Paul Duffin520917a2022-05-13 13:01:59 +00001788 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001789 return false
1790 }
1791
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001792 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001793 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001794
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001795 // Visit actually
1796 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001797 })
1798}
1799
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001800// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1801type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001802
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001803const (
1804 ext4 fsType = iota
1805 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001806 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001807)
Artur Satayev849f8442020-04-28 14:57:42 +01001808
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001809func (f fsType) string() string {
1810 switch f {
1811 case ext4:
1812 return ext4FsType
1813 case f2fs:
1814 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001815 case erofs:
1816 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001817 default:
1818 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001819 }
1820}
1821
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001822var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1823
1824func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1825 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1826}
1827
1828func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1829 bazelCtx := ctx.Config().BazelContext
1830 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1831}
1832
1833func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1834 if !a.commonBuildActions(ctx) {
1835 return
1836 }
1837
1838 a.setApexTypeAndSuffix(ctx)
1839 a.setPayloadFsType(ctx)
1840 a.setSystemLibLink(ctx)
1841
1842 if a.properties.ApexType != zipApex {
1843 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1844 }
1845
1846 bazelCtx := ctx.Config().BazelContext
1847 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1848 if err != nil {
1849 ctx.ModuleErrorf(err.Error())
1850 return
1851 }
1852 a.installDir = android.PathForModuleInstall(ctx, "apex")
1853 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1854 a.outputFile = a.outputApexFile
1855 a.setCompression(ctx)
1856
Wei Li32dcdf92022-10-26 22:30:48 -07001857 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1858 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1859 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1860 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001861 apexType := a.properties.ApexType
1862 switch apexType {
1863 case imageApex:
1864 // TODO(asmundak): Bazel does not create these files yet.
1865 // b/190817312
1866 a.htmlGzNotice = android.PathForBazelOut(ctx, "NOTICE.html.gz")
1867 // b/239081457
1868 a.bundleModuleFile = android.PathForBazelOut(ctx, a.Name()+apexType.suffix()+"-base.zip")
1869 // b/239081455
1870 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.txt"))
1871 // b/239081456
1872 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_backing.txt"))
1873 // b/239084755
1874 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.xml"))
1875 installSuffix := imageApexSuffix
1876 if a.isCompressed {
1877 installSuffix = imageCapexSuffix
1878 }
1879 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1880 a.compatSymlinks.Paths()...)
1881 default:
1882 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1883 }
1884
1885 /*
1886 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1887 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1888 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1889 To find out what Soong build puts there, run:
1890 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1891 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1892 return a.depVisitor(&vctx, ctx, child, parent)
1893 })
1894 vctx.normalizeFileInfo()
1895 */
1896
1897}
1898
1899func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1900 if a.properties.ApexType != imageApex {
1901 a.isCompressed = false
1902 } else if a.testOnlyShouldForceCompression() {
1903 a.isCompressed = true
1904 } else {
1905 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1906 }
1907}
1908
1909func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1910 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1911 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1912 // the same library in the system partition, thus effectively sharing the same libraries
1913 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1914 // in the APEX.
1915 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1916
1917 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1918 // So we can't link them to /system/lib libs which are core variants.
1919 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1920 a.linkToSystemLib = false
1921 }
1922
1923 forced := ctx.Config().ForceApexSymlinkOptimization()
1924 updatable := a.Updatable() || a.FutureUpdatable()
1925
1926 // We don't need the optimization for updatable APEXes, as it might give false signal
1927 // to the system health when the APEXes are still bundled (b/149805758).
1928 if !forced && updatable && a.properties.ApexType == imageApex {
1929 a.linkToSystemLib = false
1930 }
1931
1932 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1933 if ctx.Host() {
1934 a.linkToSystemLib = false
1935 }
1936}
1937
1938func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1939 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
1940 case ext4FsType:
1941 a.payloadFsType = ext4
1942 case f2fsFsType:
1943 a.payloadFsType = f2fs
1944 case erofsFsType:
1945 a.payloadFsType = erofs
1946 default:
1947 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
1948 }
1949}
1950
1951func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
1952 // Set suffix and primaryApexType depending on the ApexType
1953 buildFlattenedAsDefault := ctx.Config().FlattenApex()
1954 switch a.properties.ApexType {
1955 case imageApex:
1956 if buildFlattenedAsDefault {
1957 a.suffix = imageApexSuffix
1958 } else {
1959 a.suffix = ""
1960 a.primaryApexType = true
1961
1962 if ctx.Config().InstallExtraFlattenedApexes() {
1963 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
1964 }
1965 }
1966 case zipApex:
1967 if proptools.String(a.properties.Payload_type) == "zip" {
1968 a.suffix = ""
1969 a.primaryApexType = true
1970 } else {
1971 a.suffix = zipApexSuffix
1972 }
1973 case flattenedApex:
1974 if buildFlattenedAsDefault {
1975 a.suffix = ""
1976 a.primaryApexType = true
1977 } else {
1978 a.suffix = flattenedSuffix
1979 }
1980 }
1981}
1982
1983func (a apexBundle) isCompressable() bool {
1984 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
1985}
1986
1987func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
1988 a.checkApexAvailability(ctx)
1989 a.checkUpdatable(ctx)
1990 a.CheckMinSdkVersion(ctx)
1991 a.checkStaticLinkingToStubLibraries(ctx)
1992 a.checkStaticExecutables(ctx)
1993 if len(a.properties.Tests) > 0 && !a.testApex {
1994 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
1995 return false
1996 }
1997 return true
1998}
1999
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002000type visitorContext struct {
2001 // all the files that will be included in this APEX
2002 filesInfo []apexFile
2003
2004 // native lib dependencies
2005 provideNativeLibs []string
2006 requireNativeLibs []string
2007
2008 handleSpecialLibs bool
2009}
2010
2011func (vctx *visitorContext) normalizeFileInfo() {
2012 encountered := make(map[string]apexFile)
2013 for _, f := range vctx.filesInfo {
2014 dest := filepath.Join(f.installDir, f.builtFile.Base())
2015 if e, ok := encountered[dest]; !ok {
2016 encountered[dest] = f
2017 } else {
2018 // If a module is directly included and also transitively depended on
2019 // consider it as directly included.
2020 e.transitiveDep = e.transitiveDep && f.transitiveDep
2021 encountered[dest] = e
2022 }
2023 }
2024 vctx.filesInfo = vctx.filesInfo[:0]
2025 for _, v := range encountered {
2026 vctx.filesInfo = append(vctx.filesInfo, v)
2027 }
2028 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2029 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2030 // changes.
2031 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2032 })
2033}
2034
2035func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2036 depTag := ctx.OtherModuleDependencyTag(child)
2037 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2038 return false
2039 }
2040 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2041 return false
2042 }
2043 depName := ctx.OtherModuleName(child)
2044 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2045 switch depTag {
2046 case sharedLibTag, jniLibTag:
2047 isJniLib := depTag == jniLibTag
2048 switch ch := child.(type) {
2049 case *cc.Module:
2050 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2051 fi.isJniLib = isJniLib
2052 vctx.filesInfo = append(vctx.filesInfo, fi)
2053 // Collect the list of stub-providing libs except:
2054 // - VNDK libs are only for vendors
2055 // - bootstrap bionic libs are treated as provided by system
2056 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2057 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2058 }
2059 return true // track transitive dependencies
2060 case *rust.Module:
2061 fi := apexFileForRustLibrary(ctx, ch)
2062 fi.isJniLib = isJniLib
2063 vctx.filesInfo = append(vctx.filesInfo, fi)
2064 return true // track transitive dependencies
2065 default:
2066 propertyName := "native_shared_libs"
2067 if isJniLib {
2068 propertyName = "jni_libs"
2069 }
2070 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2071 }
2072 case executableTag:
2073 switch ch := child.(type) {
2074 case *cc.Module:
2075 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2076 return true // track transitive dependencies
2077 case *python.Module:
2078 if ch.HostToolPath().Valid() {
2079 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2080 }
2081 case bootstrap.GoBinaryTool:
2082 if a.Host() {
2083 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2084 }
2085 case *rust.Module:
2086 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2087 return true // track transitive dependencies
2088 default:
2089 ctx.PropertyErrorf("binaries",
2090 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2091 }
2092 case shBinaryTag:
2093 if csh, ok := child.(*sh.ShBinary); ok {
2094 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2095 } else {
2096 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2097 }
2098 case bcpfTag:
2099 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2100 if !ok {
2101 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2102 return false
2103 }
2104
2105 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2106 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2107 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2108 }
2109 return true
2110 case sscpfTag:
2111 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2112 ctx.PropertyErrorf("systemserverclasspath_fragments",
2113 "%q is not a systemserverclasspath_fragment module", depName)
2114 return false
2115 }
2116 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2117 vctx.filesInfo = append(vctx.filesInfo, *af)
2118 }
2119 return true
2120 case javaLibTag:
2121 switch child.(type) {
2122 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2123 af := apexFileForJavaModule(ctx, child.(javaModule))
2124 if !af.ok() {
2125 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2126 return false
2127 }
2128 vctx.filesInfo = append(vctx.filesInfo, af)
2129 return true // track transitive dependencies
2130 default:
2131 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2132 }
2133 case androidAppTag:
2134 switch ap := child.(type) {
2135 case *java.AndroidApp:
2136 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2137 return true // track transitive dependencies
2138 case *java.AndroidAppImport:
2139 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2140 case *java.AndroidTestHelperApp:
2141 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2142 case *java.AndroidAppSet:
2143 appDir := "app"
2144 if ap.Privileged() {
2145 appDir = "priv-app"
2146 }
2147 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2148 // suffixed so that PackageManager correctly invalidates the
2149 // existing installed apk in favour of the new APK-in-APEX.
2150 // See bugs for more information.
2151 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2152 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2153 af.certificate = java.PresignedCertificate
2154 vctx.filesInfo = append(vctx.filesInfo, af)
2155 default:
2156 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2157 }
2158 case rroTag:
2159 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2160 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2161 } else {
2162 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2163 }
2164 case bpfTag:
2165 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2166 filesToCopy, _ := bpfProgram.OutputFiles("")
2167 apex_sub_dir := bpfProgram.SubDir()
2168 for _, bpfFile := range filesToCopy {
2169 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2170 }
2171 } else {
2172 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2173 }
2174 case fsTag:
2175 if fs, ok := child.(filesystem.Filesystem); ok {
2176 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2177 } else {
2178 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2179 }
2180 case prebuiltTag:
2181 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2182 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2183 } else {
2184 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2185 }
2186 case compatConfigTag:
2187 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2188 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2189 } else {
2190 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2191 }
2192 case testTag:
2193 if ccTest, ok := child.(*cc.Module); ok {
2194 if ccTest.IsTestPerSrcAllTestsVariation() {
2195 // Multiple-output test module (where `test_per_src: true`).
2196 //
2197 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2198 // We do not add this variation to `filesInfo`, as it has no output;
2199 // however, we do add the other variations of this module as indirect
2200 // dependencies (see below).
2201 } else {
2202 // Single-output test module (where `test_per_src: false`).
2203 af := apexFileForExecutable(ctx, ccTest)
2204 af.class = nativeTest
2205 vctx.filesInfo = append(vctx.filesInfo, af)
2206 }
2207 return true // track transitive dependencies
2208 } else {
2209 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2210 }
2211 case keyTag:
2212 if key, ok := child.(*apexKey); ok {
2213 a.privateKeyFile = key.privateKeyFile
2214 a.publicKeyFile = key.publicKeyFile
2215 } else {
2216 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2217 }
2218 case certificateTag:
2219 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2220 a.containerCertificateFile = dep.Certificate.Pem
2221 a.containerPrivateKeyFile = dep.Certificate.Key
2222 } else {
2223 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2224 }
2225 case android.PrebuiltDepTag:
2226 // If the prebuilt is force disabled, remember to delete the prebuilt file
2227 // that might have been installed in the previous builds
2228 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2229 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2230 }
2231 }
2232 return false
2233 }
2234
2235 if a.vndkApex {
2236 return false
2237 }
2238
2239 // indirect dependencies
2240 am, ok := child.(android.ApexModule)
2241 if !ok {
2242 return false
2243 }
2244 // We cannot use a switch statement on `depTag` here as the checked
2245 // tags used below are private (e.g. `cc.sharedDepTag`).
2246 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2247 if ch, ok := child.(*cc.Module); ok {
2248 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2249 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2250 return false
2251 }
2252 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2253 af.transitiveDep = true
2254
2255 // Always track transitive dependencies for host.
2256 if a.Host() {
2257 vctx.filesInfo = append(vctx.filesInfo, af)
2258 return true
2259 }
2260
2261 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2262 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2263 // If the dependency is a stubs lib, don't include it in this APEX,
2264 // but make sure that the lib is installed on the device.
2265 // In case no APEX is having the lib, the lib is installed to the system
2266 // partition.
2267 //
2268 // Always include if we are a host-apex however since those won't have any
2269 // system libraries.
2270 if !am.DirectlyInAnyApex() {
2271 // we need a module name for Make
2272 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2273 if !android.InList(name, a.requiredDeps) {
2274 a.requiredDeps = append(a.requiredDeps, name)
2275 }
2276 }
2277 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2278 // Don't track further
2279 return false
2280 }
2281
2282 // If the dep is not considered to be in the same
2283 // apex, don't add it to filesInfo so that it is not
2284 // included in this APEX.
2285 // TODO(jiyong): move this to at the top of the
2286 // else-if clause for the indirect dependencies.
2287 // Currently, that's impossible because we would
2288 // like to record requiredNativeLibs even when
2289 // DepIsInSameAPex is false. We also shouldn't do
2290 // this for host.
2291 //
2292 // TODO(jiyong): explain why the same module is passed in twice.
2293 // Switching the first am to parent breaks lots of tests.
2294 if !android.IsDepInSameApex(ctx, am, am) {
2295 return false
2296 }
2297
2298 vctx.filesInfo = append(vctx.filesInfo, af)
2299 return true // track transitive dependencies
2300 } else if rm, ok := child.(*rust.Module); ok {
2301 af := apexFileForRustLibrary(ctx, rm)
2302 af.transitiveDep = true
2303 vctx.filesInfo = append(vctx.filesInfo, af)
2304 return true // track transitive dependencies
2305 }
2306 } else if cc.IsTestPerSrcDepTag(depTag) {
2307 if ch, ok := child.(*cc.Module); ok {
2308 af := apexFileForExecutable(ctx, ch)
2309 // Handle modules created as `test_per_src` variations of a single test module:
2310 // use the name of the generated test binary (`fileToCopy`) instead of the name
2311 // of the original test module (`depName`, shared by all `test_per_src`
2312 // variations of that module).
2313 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2314 // these are not considered transitive dep
2315 af.transitiveDep = false
2316 vctx.filesInfo = append(vctx.filesInfo, af)
2317 return true // track transitive dependencies
2318 }
2319 } else if cc.IsHeaderDepTag(depTag) {
2320 // nothing
2321 } else if java.IsJniDepTag(depTag) {
2322 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2323 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2324 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2325 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2326 }
2327 } else if rust.IsDylibDepTag(depTag) {
2328 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2329 af := apexFileForRustLibrary(ctx, rustm)
2330 af.transitiveDep = true
2331 vctx.filesInfo = append(vctx.filesInfo, af)
2332 return true // track transitive dependencies
2333 }
2334 } else if rust.IsRlibDepTag(depTag) {
2335 // Rlib is statically linked, but it might have shared lib
2336 // dependencies. Track them.
2337 return true
2338 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2339 // Add the contents of the bootclasspath fragment to the apex.
2340 switch child.(type) {
2341 case *java.Library, *java.SdkLibrary:
2342 javaModule := child.(javaModule)
2343 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2344 if !af.ok() {
2345 ctx.PropertyErrorf("bootclasspath_fragments",
2346 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2347 return false
2348 }
2349 vctx.filesInfo = append(vctx.filesInfo, af)
2350 return true // track transitive dependencies
2351 default:
2352 ctx.PropertyErrorf("bootclasspath_fragments",
2353 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2354 }
2355 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2356 // Add the contents of the systemserverclasspath fragment to the apex.
2357 switch child.(type) {
2358 case *java.Library, *java.SdkLibrary:
2359 af := apexFileForJavaModule(ctx, child.(javaModule))
2360 vctx.filesInfo = append(vctx.filesInfo, af)
2361 return true // track transitive dependencies
2362 default:
2363 ctx.PropertyErrorf("systemserverclasspath_fragments",
2364 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2365 }
2366 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2367 // nothing
2368 } else if depTag == android.DarwinUniversalVariantTag {
2369 // nothing
2370 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2371 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2372 }
2373 return false
2374}
2375
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002376// Creates build rules for an APEX. It consists of the following major steps:
2377//
2378// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2379// 2) traverse the dependency tree to collect apexFile structs from them.
2380// 3) some fields in apexBundle struct are configured
2381// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002382func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002383 ////////////////////////////////////////////////////////////////////////////////////////////
2384 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002385 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002386 return
2387 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002388 ////////////////////////////////////////////////////////////////////////////////////////////
2389 // 2) traverse the dependency tree to collect apexFile structs from them.
2390
braleeb0c1f0c2021-06-07 22:49:13 +08002391 // Collect the module directory for IDE info in java/jdeps.go.
2392 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2393
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002394 // TODO(jiyong): do this using WalkPayloadDeps
2395 // TODO(jiyong): make this clean!!!
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002396 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2397 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
2398 vctx.normalizeFileInfo()
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002399 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002400 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002401 return
2402 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002403
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002404 ////////////////////////////////////////////////////////////////////////////////////////////
2405 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002406 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002407 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002408
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002409 a.setApexTypeAndSuffix(ctx)
2410 a.setPayloadFsType(ctx)
2411 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002412 if a.properties.ApexType != zipApex {
2413 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2414 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002415
2416 ////////////////////////////////////////////////////////////////////////////////////////////
2417 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002418 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002419 if a.properties.ApexType == flattenedApex {
2420 a.buildFlattenedApex(ctx)
2421 } else {
2422 a.buildUnflattenedApex(ctx)
2423 }
Jiyong Park956305c2020-01-09 12:32:06 +09002424 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002425 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002426
2427 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2428 if a.installable() {
2429 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2430 // along with other ordinary files. (Note that this is done by apexer for
2431 // non-flattened APEXes)
2432 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2433
2434 // Place the public key as apex_pubkey. This is also done by apexer for
2435 // non-flattened APEXes case.
2436 // TODO(jiyong): Why do we need this CP rule?
2437 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2438 ctx.Build(pctx, android.BuildParams{
2439 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002440 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002441 Output: copiedPubkey,
2442 })
2443 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2444 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002445}
2446
Paul Duffincc33ec82021-04-25 23:14:55 +01002447// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2448// the bootclasspath_fragment contributes to the apex.
2449func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2450 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2451 var filesToAdd []apexFile
2452
2453 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002454 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2455 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2456 dirInApex := filepath.Join("javalib", arch.String())
2457 for _, f := range files {
2458 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2459 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2460 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2461 filesToAdd = append(filesToAdd, af)
2462 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002463 }
2464 }
2465
satayev3db35472021-05-06 23:59:58 +01002466 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002467 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2468 filesToAdd = append(filesToAdd, *af)
2469 }
satayev3db35472021-05-06 23:59:58 +01002470
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002471 if pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex(); pathInApex != "" {
2472 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2473 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2474
2475 if pathOnHost != nil {
2476 // We need to copy the profile to a temporary path with the right filename because the apexer
2477 // will take the filename as is.
2478 ctx.Build(pctx, android.BuildParams{
2479 Rule: android.Cp,
2480 Input: pathOnHost,
2481 Output: tempPath,
2482 })
2483 } else {
2484 // At this point, the boot image profile cannot be generated. It is probably because the boot
2485 // image profile source file does not exist on the branch, or it is not available for the
2486 // current build target.
2487 // However, we cannot enforce the boot image profile to be generated because some build
2488 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2489 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2490 // only if the APEX is being built.
2491 ctx.Build(pctx, android.BuildParams{
2492 Rule: android.ErrorRule,
2493 Output: tempPath,
2494 Args: map[string]string{
2495 "error": "Boot image profile cannot be generated",
2496 },
2497 })
2498 }
2499
2500 androidMkModuleName := filepath.Base(pathInApex)
2501 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2502 filesToAdd = append(filesToAdd, af)
2503 }
2504
Paul Duffincc33ec82021-04-25 23:14:55 +01002505 return filesToAdd
2506}
2507
satayevb98371c2021-06-15 16:49:50 +01002508// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2509// the module contributes to the apex; or nil if the proto config was not generated.
2510func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2511 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2512 if !info.ClasspathFragmentProtoGenerated {
2513 return nil
2514 }
2515 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2516 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2517 return &af
satayev14e49132021-05-17 21:03:07 +01002518}
2519
Paul Duffincc33ec82021-04-25 23:14:55 +01002520// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2521// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002522func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2523 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2524
2525 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2526 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002527 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2528 if err != nil {
2529 ctx.ModuleErrorf("%s", err)
2530 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002531
2532 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2533 // bootclasspath_fragment.
2534 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2535 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002536}
2537
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002538///////////////////////////////////////////////////////////////////////////////////////////////////
2539// Factory functions
2540//
2541
2542func newApexBundle() *apexBundle {
2543 module := &apexBundle{}
2544
2545 module.AddProperties(&module.properties)
2546 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002547 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002548 module.AddProperties(&module.overridableProperties)
2549
2550 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2551 android.InitDefaultableModule(module)
2552 android.InitSdkAwareModule(module)
2553 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002554 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002555 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002556 return module
2557}
2558
Paul Duffineb8051d2021-10-18 17:49:39 +01002559func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002560 bundle := newApexBundle()
2561 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002562 return bundle
2563}
2564
2565// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2566// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002567func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002568 bundle := newApexBundle()
2569 bundle.testApex = true
2570 return bundle
2571}
2572
2573// apex packages other modules into an APEX file which is a packaging format for system-level
2574// components like binaries, shared libraries, etc.
2575func BundleFactory() android.Module {
2576 return newApexBundle()
2577}
2578
2579type Defaults struct {
2580 android.ModuleBase
2581 android.DefaultsModuleBase
2582}
2583
2584// apex_defaults provides defaultable properties to other apex modules.
2585func defaultsFactory() android.Module {
2586 return DefaultsFactory()
2587}
2588
2589func DefaultsFactory(props ...interface{}) android.Module {
2590 module := &Defaults{}
2591
2592 module.AddProperties(props...)
2593 module.AddProperties(
2594 &apexBundleProperties{},
2595 &apexTargetBundleProperties{},
2596 &overridableProperties{},
2597 )
2598
2599 android.InitDefaultsModule(module)
2600 return module
2601}
2602
2603type OverrideApex struct {
2604 android.ModuleBase
2605 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002606 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002607}
2608
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002609func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002610 // All the overrides happen in the base module.
2611}
2612
2613// override_apex is used to create an apex module based on another apex module by overriding some of
2614// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002615func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002616 m := &OverrideApex{}
2617
2618 m.AddProperties(&overridableProperties{})
2619
2620 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2621 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002622 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002623 return m
2624}
2625
Wei Li1c66fc72022-05-09 23:59:14 -07002626func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2627 if ctx.ModuleType() != "override_apex" {
2628 return
2629 }
2630
2631 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2632 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2633 if !baseApexExists {
2634 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2635 }
2636
2637 a, baseModuleIsApex := baseModule.(*apexBundle)
2638 if !baseModuleIsApex {
2639 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2640 }
2641 attrs, props := convertWithBp2build(a, ctx)
2642
2643 for _, p := range o.GetProperties() {
2644 overridableProperties, ok := p.(*overridableProperties)
2645 if !ok {
2646 continue
2647 }
Wei Li40f98732022-05-20 22:08:11 -07002648
2649 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2650 // After it is converted in convertWithBp2build(baseApex, ctx),
2651 // the attrs.Manifest.Value.Label is the file path relative to the directory
2652 // of base apex. So the following code converts it to a label that looks like
2653 // <package of base apex>:<path of manifest file> if base apex and override
2654 // apex are not in the same package.
2655 baseApexPackage := ctx.OtherModuleDir(a)
2656 overrideApexPackage := ctx.ModuleDir()
2657 if baseApexPackage != overrideApexPackage {
2658 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2659 }
2660
Wei Li1c66fc72022-05-09 23:59:14 -07002661 // Key
2662 if overridableProperties.Key != nil {
2663 attrs.Key = bazel.LabelAttribute{}
2664 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2665 }
2666
2667 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002668 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002669 // If overridableProperties.Certificate is nil, clear this out as
2670 // well with zeroed structs, so the override_apex does not use the
2671 // base apex's certificate.
2672 attrs.Certificate = bazel.LabelAttribute{}
2673 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002674 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002675 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002676 }
2677
2678 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002679 if overridableProperties.Prebuilts != nil {
2680 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2681 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2682 }
Wei Li1c66fc72022-05-09 23:59:14 -07002683
2684 // Compressible
2685 if overridableProperties.Compressible != nil {
2686 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2687 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002688
2689 // Package name
2690 //
2691 // e.g. com.android.adbd's package name is com.android.adbd, but
2692 // com.google.android.adbd overrides the package name to com.google.android.adbd
2693 //
2694 // TODO: this can be overridden from the product configuration, see
2695 // getOverrideManifestPackageName and
2696 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2697 //
2698 // Instead of generating the BUILD files differently based on the product config
2699 // at the point of conversion, this should be handled by the BUILD file loading
2700 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2701 if overridableProperties.Package_name != "" {
2702 attrs.Package_name = &overridableProperties.Package_name
2703 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002704
2705 // Logging parent
2706 if overridableProperties.Logging_parent != "" {
2707 attrs.Logging_parent = &overridableProperties.Logging_parent
2708 }
Wei Li1c66fc72022-05-09 23:59:14 -07002709 }
2710
2711 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2712}
2713
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002714///////////////////////////////////////////////////////////////////////////////////////////////////
2715// Vality check routines
2716//
2717// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2718// certain conditions are not met.
2719//
2720// TODO(jiyong): move these checks to a separate go file.
2721
satayevad991492021-12-03 18:58:32 +00002722var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2723
Spandan Dasa5f39a12022-08-05 02:35:52 +00002724// 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 +09002725// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002726func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002727 if a.testApex || a.vndkApex {
2728 return
2729 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002730 // apexBundle::minSdkVersion reports its own errors.
2731 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002732 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002733}
2734
Albert Martineefabcf2022-03-21 20:11:16 +00002735// Returns apex's min_sdk_version string value, honoring overrides
2736func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2737 // Only override the minSdkVersion value on Apexes which already specify
2738 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2739 // min_sdk_version value is lower than the one to override with.
Colin Cross56534df2022-10-04 09:58:58 -07002740 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2741 if minApiLevel.IsNone() {
2742 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002743 }
2744
Colin Cross56534df2022-10-04 09:58:58 -07002745 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2746 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2747 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2748 minApiLevel = overrideApiLevel
2749 }
2750
2751 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002752}
2753
2754// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002755func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2756 return android.SdkSpec{
2757 Kind: android.SdkNone,
2758 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002759 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002760 }
2761}
2762
Albert Martineefabcf2022-03-21 20:11:16 +00002763// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002764func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002765 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2766}
2767
2768// Construct ApiLevel object from min_sdk_version string value
2769func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2770 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002771 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002772 }
Albert Martineefabcf2022-03-21 20:11:16 +00002773 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002774 if err != nil {
2775 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2776 return android.NoneApiLevel
2777 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002778 return apiLevel
2779}
2780
2781// Ensures that a lib providing stub isn't statically linked
2782func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2783 // Practically, we only care about regular APEXes on the device.
2784 if ctx.Host() || a.testApex || a.vndkApex {
2785 return
2786 }
2787
2788 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2789
2790 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2791 if ccm, ok := to.(*cc.Module); ok {
2792 apexName := ctx.ModuleName()
2793 fromName := ctx.OtherModuleName(from)
2794 toName := ctx.OtherModuleName(to)
2795
2796 // If `to` is not actually in the same APEX as `from` then it does not need
2797 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002798 //
2799 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002800 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2801 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2802 return false
2803 }
2804
2805 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2806 // exception to this rule. It can't make the static dependencies dynamic
2807 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002808 // Same rule should be applied to linkerconfig, because it should be executed
2809 // only with static linked libraries before linker is available with ld.config.txt
2810 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002811 return false
2812 }
2813
2814 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2815 if isStubLibraryFromOtherApex && !externalDep {
2816 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2817 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2818 }
2819
2820 }
2821 return true
2822 })
2823}
2824
satayevb98371c2021-06-15 16:49:50 +01002825// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002826func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2827 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002828 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002829 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2830 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002831 if a.UsePlatformApis() {
2832 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2833 }
Daniel Norman69109112021-12-02 12:52:42 -08002834 if a.SocSpecific() || a.DeviceSpecific() {
2835 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2836 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002837 if a.FutureUpdatable() {
2838 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2839 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002840 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002841 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002842 }
2843}
2844
satayevb98371c2021-06-15 16:49:50 +01002845// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2846func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2847 ctx.VisitDirectDeps(func(module android.Module) {
2848 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2849 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2850 if !info.ClasspathFragmentProtoGenerated {
2851 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2852 }
2853 }
2854 })
2855}
2856
2857// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002858func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002859 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2860 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002861 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2862 tag := ctx.OtherModuleDependencyTag(module)
2863 switch tag {
2864 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002865 if m, ok := module.(interface {
2866 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2867 }); ok {
2868 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002869 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2870 }
2871 }
2872 }
2873 })
2874}
2875
satayevb98371c2021-06-15 16:49:50 +01002876// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002877func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2878 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2879 if ctx.Host() || a.testApex || a.vndkApex {
2880 return
2881 }
2882
2883 // Because APEXes targeting other than system/system_ext partitions can't set
2884 // apex_available, we skip checks for these APEXes
2885 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2886 return
2887 }
2888
2889 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2890 // Requiring them and their transitive depencies with apex_available is not right
2891 // because they just add noise.
2892 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2893 return
2894 }
2895
2896 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2897 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2898 if externalDep {
2899 return false
2900 }
2901
2902 apexName := ctx.ModuleName()
2903 fromName := ctx.OtherModuleName(from)
2904 toName := ctx.OtherModuleName(to)
2905
2906 // If `to` is not actually in the same APEX as `from` then it does not need
2907 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002908 //
2909 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002910 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2911 // As soon as the dependency graph crosses the APEX boundary, don't go
2912 // further.
2913 return false
2914 }
2915
2916 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
2917 return true
2918 }
Jiyong Park767dbd92021-03-04 13:03:10 +09002919 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2920 "\n\nDependency path:%s\n\n"+
2921 "Consider adding %q to 'apex_available' property of %q",
2922 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002923 // Visit this module's dependencies to check and report any issues with their availability.
2924 return true
2925 })
2926}
2927
Jiyong Park192600a2021-08-03 07:52:17 +00002928// checkStaticExecutable ensures that executables in an APEX are not static.
2929func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09002930 // No need to run this for host APEXes
2931 if ctx.Host() {
2932 return
2933 }
2934
Jiyong Park192600a2021-08-03 07:52:17 +00002935 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2936 if ctx.OtherModuleDependencyTag(module) != executableTag {
2937 return
2938 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09002939
2940 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00002941 apex := a.ApexVariationName()
2942 exec := ctx.OtherModuleName(module)
2943 if isStaticExecutableAllowed(apex, exec) {
2944 return
2945 }
2946 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
2947 }
2948 })
2949}
2950
2951// A small list of exceptions where static executables are allowed in APEXes.
2952func isStaticExecutableAllowed(apex string, exec string) bool {
2953 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07002954 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00002955 "linker",
2956 "linkerconfig",
2957 },
2958 }
2959 execNames, ok := m[apex]
2960 return ok && android.InList(exec, execNames)
2961}
2962
braleeb0c1f0c2021-06-07 22:49:13 +08002963// Collect information for opening IDE project files in java/jdeps.go.
2964func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09002965 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
2966 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
2967 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08002968 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
2969}
2970
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002971var (
2972 apexAvailBaseline = makeApexAvailableBaseline()
2973 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
2974)
2975
Colin Cross440e0d02020-06-11 11:32:11 -07002976func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002977 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002978 moduleName = normalizeModuleName(moduleName)
2979
Colin Cross440e0d02020-06-11 11:32:11 -07002980 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002981 return true
2982 }
2983
2984 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07002985 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002986 return true
2987 }
2988
2989 return false
2990}
2991
2992func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09002993 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
2994 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00002995 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09002996 if strings.HasPrefix(moduleName, "libclang_rt.") {
2997 // This module has many arch variants that depend on the product being built.
2998 // We don't want to list them all
2999 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003000 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003001 if strings.HasPrefix(moduleName, "androidx.") {
3002 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3003 moduleName = "androidx"
3004 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003005 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003006}
3007
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003008// Transform the map of apex -> modules to module -> apexes.
3009func invertApexBaseline(m map[string][]string) map[string][]string {
3010 r := make(map[string][]string)
3011 for apex, modules := range m {
3012 for _, module := range modules {
3013 r[module] = append(r[module], apex)
3014 }
3015 }
3016 return r
3017}
3018
3019// Retrieve the baseline of apexes to which the supplied module belongs.
3020func BaselineApexAvailable(moduleName string) []string {
3021 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3022}
3023
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003024// This is a map from apex to modules, which overrides the apex_available setting for that
3025// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003026// TODO(b/147364041): remove this
3027func makeApexAvailableBaseline() map[string][]string {
3028 // The "Module separator"s below are employed to minimize merge conflicts.
3029 m := make(map[string][]string)
3030 //
3031 // Module separator
3032 //
3033 m["com.android.appsearch"] = []string{
3034 "icing-java-proto-lite",
3035 "libprotobuf-java-lite",
3036 }
3037 //
3038 // Module separator
3039 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003040 m["com.android.btservices"] = []string{
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003041 "bluetooth-protos-lite",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003042 "internal_include_headers",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003043 "libaudio-a2dp-hw-utils",
3044 "libaudio-hearing-aid-hw-utils",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003045 "libbluetooth",
3046 "libbluetooth-types",
3047 "libbluetooth-types-header",
3048 "libbluetooth_gd",
3049 "libbluetooth_headers",
3050 "libbluetooth_jni",
3051 "libbt-audio-hal-interface",
3052 "libbt-bta",
3053 "libbt-common",
3054 "libbt-hci",
3055 "libbt-platform-protos-lite",
3056 "libbt-protos-lite",
3057 "libbt-sbc-decoder",
3058 "libbt-sbc-encoder",
3059 "libbt-stack",
3060 "libbt-utils",
3061 "libbtcore",
3062 "libbtdevice",
3063 "libbte",
3064 "libbtif",
3065 "libchrome",
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003066 }
3067 //
3068 // Module separator
3069 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003070 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3071 //
3072 // Module separator
3073 //
3074 m["com.android.extservices"] = []string{
3075 "error_prone_annotations",
3076 "ExtServices-core",
3077 "ExtServices",
3078 "libtextclassifier-java",
3079 "libz_current",
3080 "textclassifier-statsd",
3081 "TextClassifierNotificationLibNoManifest",
3082 "TextClassifierServiceLibNoManifest",
3083 }
3084 //
3085 // Module separator
3086 //
3087 m["com.android.neuralnetworks"] = []string{
3088 "android.hardware.neuralnetworks@1.0",
3089 "android.hardware.neuralnetworks@1.1",
3090 "android.hardware.neuralnetworks@1.2",
3091 "android.hardware.neuralnetworks@1.3",
3092 "android.hidl.allocator@1.0",
3093 "android.hidl.memory.token@1.0",
3094 "android.hidl.memory@1.0",
3095 "android.hidl.safe_union@1.0",
3096 "libarect",
3097 "libbuildversion",
3098 "libmath",
3099 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003100 }
3101 //
3102 // Module separator
3103 //
3104 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003105 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003106 }
3107 //
3108 // Module separator
3109 //
3110 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003111 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003112 }
3113 //
3114 // Module separator
3115 //
3116 m["com.android.mediaprovider"] = []string{
3117 "MediaProvider",
3118 "MediaProviderGoogle",
3119 "fmtlib_ndk",
3120 "libbase_ndk",
3121 "libfuse",
3122 "libfuse_jni",
3123 }
3124 //
3125 // Module separator
3126 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003127 m["com.android.runtime"] = []string{
3128 "bionic_libc_platform_headers",
3129 "libarm-optimized-routines-math",
3130 "libc_aeabi",
3131 "libc_bionic",
3132 "libc_bionic_ndk",
3133 "libc_bootstrap",
3134 "libc_common",
3135 "libc_common_shared",
3136 "libc_common_static",
3137 "libc_dns",
3138 "libc_dynamic_dispatch",
3139 "libc_fortify",
3140 "libc_freebsd",
3141 "libc_freebsd_large_stack",
3142 "libc_gdtoa",
3143 "libc_init_dynamic",
3144 "libc_init_static",
3145 "libc_jemalloc_wrapper",
3146 "libc_netbsd",
3147 "libc_nomalloc",
3148 "libc_nopthread",
3149 "libc_openbsd",
3150 "libc_openbsd_large_stack",
3151 "libc_openbsd_ndk",
3152 "libc_pthread",
3153 "libc_static_dispatch",
3154 "libc_syscalls",
3155 "libc_tzcode",
3156 "libc_unwind_static",
3157 "libdebuggerd",
3158 "libdebuggerd_common_headers",
3159 "libdebuggerd_handler_core",
3160 "libdebuggerd_handler_fallback",
3161 "libdl_static",
3162 "libjemalloc5",
3163 "liblinker_main",
3164 "liblinker_malloc",
3165 "liblz4",
3166 "liblzma",
3167 "libprocinfo",
3168 "libpropertyinfoparser",
3169 "libscudo",
3170 "libstdc++",
3171 "libsystemproperties",
3172 "libtombstoned_client_static",
3173 "libunwindstack",
3174 "libz",
3175 "libziparchive",
3176 }
3177 //
3178 // Module separator
3179 //
3180 m["com.android.tethering"] = []string{
3181 "android.hardware.tetheroffload.config-V1.0-java",
3182 "android.hardware.tetheroffload.control-V1.0-java",
3183 "android.hidl.base-V1.0-java",
3184 "libcgrouprc",
3185 "libcgrouprc_format",
3186 "libtetherutilsjni",
3187 "libvndksupport",
3188 "net-utils-framework-common",
3189 "netd_aidl_interface-V3-java",
3190 "netlink-client",
3191 "networkstack-aidl-interfaces-java",
3192 "tethering-aidl-interfaces-java",
3193 "TetheringApiCurrentLib",
3194 }
3195 //
3196 // Module separator
3197 //
3198 m["com.android.wifi"] = []string{
3199 "PlatformProperties",
3200 "android.hardware.wifi-V1.0-java",
3201 "android.hardware.wifi-V1.0-java-constants",
3202 "android.hardware.wifi-V1.1-java",
3203 "android.hardware.wifi-V1.2-java",
3204 "android.hardware.wifi-V1.3-java",
3205 "android.hardware.wifi-V1.4-java",
3206 "android.hardware.wifi.hostapd-V1.0-java",
3207 "android.hardware.wifi.hostapd-V1.1-java",
3208 "android.hardware.wifi.hostapd-V1.2-java",
3209 "android.hardware.wifi.supplicant-V1.0-java",
3210 "android.hardware.wifi.supplicant-V1.1-java",
3211 "android.hardware.wifi.supplicant-V1.2-java",
3212 "android.hardware.wifi.supplicant-V1.3-java",
3213 "android.hidl.base-V1.0-java",
3214 "android.hidl.manager-V1.0-java",
3215 "android.hidl.manager-V1.1-java",
3216 "android.hidl.manager-V1.2-java",
3217 "bouncycastle-unbundled",
3218 "dnsresolver_aidl_interface-V2-java",
3219 "error_prone_annotations",
3220 "framework-wifi-pre-jarjar",
3221 "framework-wifi-util-lib",
3222 "ipmemorystore-aidl-interfaces-V3-java",
3223 "ipmemorystore-aidl-interfaces-java",
3224 "ksoap2",
3225 "libnanohttpd",
3226 "libwifi-jni",
3227 "net-utils-services-common",
3228 "netd_aidl_interface-V2-java",
3229 "netd_aidl_interface-unstable-java",
3230 "netd_event_listener_interface-java",
3231 "netlink-client",
3232 "networkstack-client",
3233 "services.net",
3234 "wifi-lite-protos",
3235 "wifi-nano-protos",
3236 "wifi-service-pre-jarjar",
3237 "wifi-service-resources",
3238 }
3239 //
3240 // Module separator
3241 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003242 m["com.android.os.statsd"] = []string{
3243 "libstatssocket",
3244 }
3245 //
3246 // Module separator
3247 //
3248 m[android.AvailableToAnyApex] = []string{
3249 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3250 "androidx",
3251 "androidx-constraintlayout_constraintlayout",
3252 "androidx-constraintlayout_constraintlayout-nodeps",
3253 "androidx-constraintlayout_constraintlayout-solver",
3254 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3255 "com.google.android.material_material",
3256 "com.google.android.material_material-nodeps",
3257
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003258 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003259 "libprofile-clang-extras",
3260 "libprofile-clang-extras_ndk",
3261 "libprofile-extras",
3262 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003263 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003264 }
3265 return m
3266}
3267
3268func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003269 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3270 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003271}
3272
Spandan Dasf14e2542021-11-12 00:01:37 +00003273func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3274 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3275 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003276 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003277 With("name", jar).
3278 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3279 Because(jar +
3280 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003281 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003282 " 1. If the offending code is from a statically linked library, consider " +
3283 "removing that dependency and using an alternative already in the " +
3284 "bootclasspath, or perhaps a shared library." +
3285 " 2. Move the offending code into an allowed package.\n" +
3286 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3287 "health implications of bundling that code, particularly if the offending jar " +
3288 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003289
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003290 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003291 }
3292 return rules
3293}
3294
Anton Hanssone1b18362021-12-23 15:05:38 +00003295// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003296// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003297func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003298 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003299 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003300 "android.net.ssl",
3301 "com.android.org.conscrypt",
3302 },
Wei Li40f98732022-05-20 22:08:11 -07003303 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003304 "android.media",
3305 },
3306 }
3307}
3308
Anton Hanssone1b18362021-12-23 15:05:38 +00003309// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003310// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003311func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003312 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003313 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003314 "android.provider",
3315 },
Wei Li40f98732022-05-20 22:08:11 -07003316 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003317 "android.permission",
3318 "android.app.role",
3319 "com.android.permission",
3320 "com.android.role",
3321 },
Wei Li40f98732022-05-20 22:08:11 -07003322 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003323 "android.os.ext",
3324 },
Wei Li40f98732022-05-20 22:08:11 -07003325 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003326 "android.app",
3327 "android.os",
3328 "android.util",
3329 "com.android.internal.statsd",
3330 "com.android.server.stats",
3331 },
Wei Li40f98732022-05-20 22:08:11 -07003332 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003333 "com.android.server.wifi",
3334 "com.android.wifi.x",
3335 "android.hardware.wifi",
3336 "android.net.wifi",
3337 },
Wei Li40f98732022-05-20 22:08:11 -07003338 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003339 "android.net",
3340 },
3341 }
3342}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003343
3344// For Bazel / bp2build
3345
3346type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003347 Manifest bazel.LabelAttribute
3348 Android_manifest bazel.LabelAttribute
3349 File_contexts bazel.LabelAttribute
3350 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003351 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3352 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Yu Liu4ae55d12022-01-05 17:17:23 -08003353 Min_sdk_version *string
3354 Updatable bazel.BoolAttribute
3355 Installable bazel.BoolAttribute
3356 Binaries bazel.LabelListAttribute
3357 Prebuilts bazel.LabelListAttribute
3358 Native_shared_libs_32 bazel.LabelListAttribute
3359 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003360 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003361 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003362 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003363 Tests bazel.LabelListAttribute
Yu Liu4ae55d12022-01-05 17:17:23 -08003364}
3365
3366type convertedNativeSharedLibs struct {
3367 Native_shared_libs_32 bazel.LabelListAttribute
3368 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003369}
3370
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003371// ConvertWithBp2build performs bp2build conversion of an apex
3372func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003373 // We only convert apex and apex_test modules at this time
3374 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003375 return
3376 }
3377
Wei Li1c66fc72022-05-09 23:59:14 -07003378 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003379 commonAttrs := android.CommonAttributes{
3380 Name: a.Name(),
3381 }
3382 if a.testApex {
3383 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3384 }
3385 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003386}
3387
3388func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003389 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003390 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003391
3392 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003393 if a.properties.AndroidManifest != nil {
3394 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003395 }
3396
3397 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003398 if a.properties.File_contexts == nil {
3399 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3400 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3401 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3402 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003403 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003404 } else {
3405 // File_contexts is a file
3406 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003407 }
3408
Albert Martineefabcf2022-03-21 20:11:16 +00003409 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3410 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003411 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003412 if a.properties.Min_sdk_version != nil {
3413 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003414 }
3415
3416 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003417 if a.overridableProperties.Key != nil {
3418 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003419 }
3420
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003421 // Certificate
3422 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003423
Yu Liu4ae55d12022-01-05 17:17:23 -08003424 nativeSharedLibs := &convertedNativeSharedLibs{
3425 Native_shared_libs_32: bazel.LabelListAttribute{},
3426 Native_shared_libs_64: bazel.LabelListAttribute{},
3427 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003428
3429 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3430 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3431 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3432 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3433 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003434 if a.CompileMultilib() != nil {
3435 compileMultilib = *a.CompileMultilib()
3436 }
3437
3438 // properties.Native_shared_libs is treated as "both"
3439 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3440 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3441 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3442 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3443 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003444
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003445 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003446 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3447 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3448
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003449 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003450 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003451
Yu Liu4c212ce2022-10-14 12:20:20 -07003452 var testsAttrs bazel.LabelListAttribute
3453 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3454 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3455 testsAttrs = bazel.MakeLabelListAttribute(tests)
3456 }
3457
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003458 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003459 if a.properties.Updatable != nil {
3460 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003461 }
3462
3463 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003464 if a.properties.Installable != nil {
3465 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003466 }
3467
Wei Lif034cb42022-01-19 15:54:31 -08003468 var compressibleAttribute bazel.BoolAttribute
3469 if a.overridableProperties.Compressible != nil {
3470 compressibleAttribute.Value = a.overridableProperties.Compressible
3471 }
3472
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003473 var packageName *string
3474 if a.overridableProperties.Package_name != "" {
3475 packageName = &a.overridableProperties.Package_name
3476 }
3477
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003478 var loggingParent *string
3479 if a.overridableProperties.Logging_parent != "" {
3480 loggingParent = &a.overridableProperties.Logging_parent
3481 }
3482
Wei Li1c66fc72022-05-09 23:59:14 -07003483 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003484 Manifest: manifestLabelAttribute,
3485 Android_manifest: androidManifestLabelAttribute,
3486 File_contexts: fileContextsLabelAttribute,
3487 Min_sdk_version: minSdkVersion,
3488 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003489 Certificate: certificate,
3490 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003491 Updatable: updatableAttribute,
3492 Installable: installableAttribute,
3493 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3494 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3495 Binaries: binariesLabelListAttribute,
3496 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003497 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003498 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003499 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003500 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003501 }
3502
3503 props := bazel.BazelTargetModuleProperties{
3504 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003505 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003506 }
3507
Wei Li1c66fc72022-05-09 23:59:14 -07003508 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003509}
Yu Liu4ae55d12022-01-05 17:17:23 -08003510
3511// The following conversions are based on this table where the rows are the compile_multilib
3512// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3513// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3514// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3515// should not be compiled.
3516// multib/compile_multilib, 32, 64, both, first
3517// 32, 32/32, none/none, 32/32, none/32
3518// 64, none/none, 64/none, 64/none, 64/none
3519// both, 32/32, 64/none, 32&64/32, 64/32
3520// first, 32/32, 64/none, 64/32, 64/32
3521
3522func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3523 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3524 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3525 switch compileMultilb {
3526 case "both", "32":
3527 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3528 case "first":
3529 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3530 case "64":
3531 // Incompatible, ignore
3532 default:
3533 invalidCompileMultilib(ctx, compileMultilb)
3534 }
3535}
3536
3537func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3538 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3539 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3540 switch compileMultilb {
3541 case "both", "64", "first":
3542 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3543 case "32":
3544 // Incompatible, ignore
3545 default:
3546 invalidCompileMultilib(ctx, compileMultilb)
3547 }
3548}
3549
3550func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3551 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3552 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3553 switch compileMultilb {
3554 case "both":
3555 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3556 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3557 case "first":
3558 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3559 case "32":
3560 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3561 case "64":
3562 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3563 default:
3564 invalidCompileMultilib(ctx, compileMultilb)
3565 }
3566}
3567
3568func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3569 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3570 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3571 switch compileMultilb {
3572 case "both", "first":
3573 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3574 case "32":
3575 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3576 case "64":
3577 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3578 default:
3579 invalidCompileMultilib(ctx, compileMultilb)
3580 }
3581}
3582
3583func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3584 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3585 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3586}
3587
3588func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3589 list := bazel.LabelListAttribute{}
3590 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3591 nativeSharedLibs.Native_shared_libs_32.Append(list)
3592}
3593
3594func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3595 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3596 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3597}
3598
3599func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3600 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3601 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3602}
3603
3604func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3605 labelListAttr *bazel.LabelListAttribute) {
3606 list := bazel.LabelListAttribute{}
3607 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3608 labelListAttr.Append(list)
3609}
3610
3611func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3612 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3613}