blob: e9b08150fca113de313aa6f5b042fa57db9f4ac1 [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 (
Sasha Smundakfe9a5b82022-07-27 14:51:45 -070020 "android/soong/bazel/cquery"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090021 "fmt"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090022 "path/filepath"
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +000023 "regexp"
Jiyong Parkab3ceb32018-10-10 14:05:29 +090024 "sort"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090025 "strings"
26
Jiyong Park48ca7dc2018-10-10 14:01:00 +090027 "github.com/google/blueprint"
Alex Light778127a2019-02-27 14:19:50 -080028 "github.com/google/blueprint/bootstrap"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090029 "github.com/google/blueprint/proptools"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070030
31 "android/soong/android"
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -040032 "android/soong/bazel"
markchien2f59ec92020-09-02 16:23:38 +080033 "android/soong/bpf"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070034 "android/soong/cc"
35 prebuilt_etc "android/soong/etc"
Jiyong Park12a719c2021-01-07 15:31:24 +090036 "android/soong/filesystem"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070037 "android/soong/java"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090038 "android/soong/multitree"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070039 "android/soong/python"
Jiyong Park99644e92020-11-17 22:21:02 +090040 "android/soong/rust"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070041 "android/soong/sh"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090042)
43
Jiyong Park8e6d52f2020-11-19 14:37:47 +090044func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000045 registerApexBuildComponents(android.InitRegistrationContext)
46}
Jiyong Park8e6d52f2020-11-19 14:37:47 +090047
Paul Duffin667893c2021-03-09 22:34:13 +000048func registerApexBuildComponents(ctx android.RegistrationContext) {
49 ctx.RegisterModuleType("apex", BundleFactory)
50 ctx.RegisterModuleType("apex_test", testApexBundleFactory)
51 ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
52 ctx.RegisterModuleType("apex_defaults", defaultsFactory)
53 ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
Wei Li1c66fc72022-05-09 23:59:14 -070054 ctx.RegisterModuleType("override_apex", OverrideApexFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000055 ctx.RegisterModuleType("apex_set", apexSetFactory)
56
Paul Duffin5dda3e32021-05-05 14:13:27 +010057 ctx.PreArchMutators(registerPreArchMutators)
Paul Duffin667893c2021-03-09 22:34:13 +000058 ctx.PreDepsMutators(RegisterPreDepsMutators)
59 ctx.PostDepsMutators(RegisterPostDepsMutators)
Jiyong Park8e6d52f2020-11-19 14:37:47 +090060}
61
Paul Duffin5dda3e32021-05-05 14:13:27 +010062func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
63 ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
64}
65
Jiyong Park8e6d52f2020-11-19 14:37:47 +090066func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
67 ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
68 ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
69}
70
71func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
Paul Duffin949abc02020-12-08 10:34:30 +000072 ctx.TopDown("apex_info", apexInfoMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090073 ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
74 ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
75 ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
Paul Duffin28bf7ee2021-05-12 16:41:35 +010076 // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
77 // it should create a platform variant.
78 ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090079 ctx.BottomUp("apex", apexMutator).Parallel()
80 ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
81 ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
Spandan Das66773252022-01-15 00:23:18 +000082 // Register after apex_info mutator so that it can use ApexVariationName
83 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090084}
85
86type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090087 // Json manifest file describing meta info of this APEX bundle. Refer to
88 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090089 Manifest *string `android:"path"`
90
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090091 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
92 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090093 AndroidManifest *string `android:"path"`
94
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090095 // Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
96 // device (/apex/<apex_name>). If unspecified, follows the name property.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090097 Apex_name *string
98
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090099 // Determines the file contexts file for setting the security contexts to files in this APEX
100 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
101 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900102 File_contexts *string `android:"path"`
103
Jiyong Park038e8522021-12-13 23:56:35 +0900104 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
105 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
106 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
107 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
108 // capability. If this property is not set, or a file is missing in the file, default config
109 // is used.
110 Canned_fs_config *string `android:"path"`
111
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900112 ApexNativeDependencies
113
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900114 Multilib apexMultilibProperties
115
Sundong Ahn80c04892021-11-23 00:57:19 +0000116 // List of sh binaries that are embedded inside this APEX bundle.
117 Sh_binaries []string
118
Paul Duffin3abc1742021-03-15 19:32:23 +0000119 // List of platform_compat_config files that are embedded inside this APEX bundle.
120 Compat_configs []string
121
Jiyong Park12a719c2021-01-07 15:31:24 +0900122 // List of filesystem images that are embedded inside this APEX bundle.
123 Filesystems []string
124
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900125 // The minimum SDK version that this APEX must support at minimum. This is usually set to
126 // the SDK version that the APEX was first introduced.
127 Min_sdk_version *string
128
129 // Whether this APEX is considered updatable or not. When set to true, this will enforce
130 // additional rules for making sure that the APEX is truly updatable. To be updatable,
131 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000132 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900133 Updatable *bool
134
Jiyong Parkf4020582021-11-29 12:37:10 +0900135 // Marks that this APEX is designed to be updatable in the future, although it's not
136 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
137 // updatable APEXes. Currently, this disables the size optimization, so that the size of
138 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
139 // false.
140 Future_updatable *bool
141
Jiyong Park1bc84122021-06-22 20:23:05 +0900142 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
143 // false`. Default is false.
144 Platform_apis *bool
145
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900146 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
147 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900148 Installable *bool
149
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900150 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
151 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
152 Use_vndk_as_stable *bool
153
Daniel Norman6cfb37af2021-11-16 20:28:29 +0000154 // Whether this is multi-installed APEX should skip installing symbol files.
155 // Multi-installed APEXes share the same apex_name and are installed at the same time.
156 // Default is false.
157 //
158 // Should be set to true for all multi-installed APEXes except the singular
159 // default version within the multi-installed group.
160 // Only the default version can install symbol files in $(PRODUCT_OUT}/apex,
161 // or else conflicting build rules may be created.
162 Multi_install_skip_symbol_files *bool
163
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900164 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
165 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
166 // container. When set to zip, contents are stored in a zip container directly. This type is
167 // mostly for host-side debugging. When set to both, the two types are both built. Default
168 // is 'image'.
169 Payload_type *string
170
Huang Jianan13cac632021-08-02 15:02:17 +0800171 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
172 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900173 Payload_fs_type *string
174
175 // For telling the APEX to ignore special handling for system libraries such as bionic.
176 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900177 Ignore_system_library_special_case *bool
178
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100179 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100180 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100181 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900182
183 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
184 // used in tests.
185 Test_only_unsigned_payload *bool
186
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000187 // Whenever apex should be compressed, regardless of product flag used. Should be only
188 // used in tests.
189 Test_only_force_compression *bool
190
Jooyung Han09c11ad2021-10-27 03:45:31 +0900191 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
192 // with the tool to sign payload contents.
193 Custom_sign_tool *string
194
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100195 // Canonical name of this APEX bundle. Used to determine the path to the
196 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
197 // apex mutator variations. For override_apex modules, this is the name of the
198 // overridden base module.
199 ApexVariationName string `blueprint:"mutated"`
200
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900201 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900202
203 // List of sanitizer names that this APEX is enabled for
204 SanitizerNames []string `blueprint:"mutated"`
205
206 PreventInstall bool `blueprint:"mutated"`
207
208 HideFromMake bool `blueprint:"mutated"`
209
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900210 // Internal package method for this APEX. When payload_type is image, this can be either
211 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
212 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900213 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900214}
215
216type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900217 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900218 Native_shared_libs []string
219
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900220 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900221 Jni_libs []string
222
Jiyong Park99644e92020-11-17 22:21:02 +0900223 // List of rust dyn libraries
224 Rust_dyn_libs []string
225
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900226 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900227 Binaries []string
228
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900229 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900230 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900231
232 // List of filesystem images that are embedded inside this APEX bundle.
233 Filesystems []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900234}
235
236type apexMultilibProperties struct {
237 // Native dependencies whose compile_multilib is "first"
238 First ApexNativeDependencies
239
240 // Native dependencies whose compile_multilib is "both"
241 Both ApexNativeDependencies
242
243 // Native dependencies whose compile_multilib is "prefer32"
244 Prefer32 ApexNativeDependencies
245
246 // Native dependencies whose compile_multilib is "32"
247 Lib32 ApexNativeDependencies
248
249 // Native dependencies whose compile_multilib is "64"
250 Lib64 ApexNativeDependencies
251}
252
253type apexTargetBundleProperties struct {
254 Target struct {
255 // Multilib properties only for android.
256 Android struct {
257 Multilib apexMultilibProperties
258 }
259
260 // Multilib properties only for host.
261 Host struct {
262 Multilib apexMultilibProperties
263 }
264
265 // Multilib properties only for host linux_bionic.
266 Linux_bionic struct {
267 Multilib apexMultilibProperties
268 }
269
270 // Multilib properties only for host linux_glibc.
271 Linux_glibc struct {
272 Multilib apexMultilibProperties
273 }
274 }
275}
276
Jiyong Park59140302020-12-14 18:44:04 +0900277type apexArchBundleProperties struct {
278 Arch struct {
279 Arm struct {
280 ApexNativeDependencies
281 }
282 Arm64 struct {
283 ApexNativeDependencies
284 }
285 X86 struct {
286 ApexNativeDependencies
287 }
288 X86_64 struct {
289 ApexNativeDependencies
290 }
291 }
292}
293
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900294// These properties can be used in override_apex to override the corresponding properties in the
295// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900296type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900297 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900298 Apps []string
299
Daniel Norman5a3ce132021-08-26 15:44:43 -0700300 // List of prebuilt files that are embedded inside this APEX bundle.
301 Prebuilts []string
302
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900303 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900304 Rros []string
305
markchien7c803b82021-08-26 22:10:06 +0800306 // List of BPF programs inside this APEX bundle.
307 Bpfs []string
308
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900309 // List of bootclasspath fragments that are embedded inside this APEX bundle.
310 Bootclasspath_fragments []string
311
312 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
313 Systemserverclasspath_fragments []string
314
315 // List of java libraries that are embedded inside this APEX bundle.
316 Java_libs []string
317
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900318 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
319 // Soong). This does not completely prevent installation of the overridden binaries, but if
320 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
321 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900322 Overrides []string
323
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900324 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900325 Logging_parent string
326
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900327 // Apex Container package name. Override value for attribute package:name in
328 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900329 Package_name string
330
331 // A txt file containing list of files that are allowed to be included in this APEX.
332 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700333
334 // Name of the apex_key module that provides the private key to sign this APEX bundle.
335 Key *string
336
337 // Specifies the certificate and the private key to sign the zip container of this APEX. If
338 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
339 // as the certificate and the private key, respectively. If this is ":module", then the
340 // certificate and the private key are provided from the android_app_certificate module
341 // named "module".
342 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400343
344 // Whether this APEX can be compressed or not. Setting this property to false means this
345 // APEX will never be compressed. When set to true, APEX will be compressed if other
346 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
347 // Default: false.
348 Compressible *bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900349}
350
351type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900352 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900353 android.ModuleBase
354 android.DefaultableModuleBase
355 android.OverridableModuleBase
356 android.SdkBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400357 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900358 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900359
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900360 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900361 properties apexBundleProperties
362 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900363 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900364 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900365 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900366
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900367 ///////////////////////////////////////////////////////////////////////////////////////////
368 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900369
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900370 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800371 publicKeyFile android.Path
372 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900373
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900374 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800375 containerCertificateFile android.Path
376 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900377
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900378 // Flags for special variants of APEX
379 testApex bool
380 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900381
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900382 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
383 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900384 primaryApexType bool
385
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900386 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900387 suffix string
388
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900389 // File system type of apex_payload.img
390 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900391
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900392 // Whether to create symlink to the system file instead of having a file inside the apex or
393 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900394 linkToSystemLib bool
395
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900396 // List of files to be included in this APEX. This is filled in the first part of
397 // GenerateAndroidBuildActions.
398 filesInfo []apexFile
399
400 // List of other module names that should be installed when this APEX gets installed.
401 requiredDeps []string
402
403 ///////////////////////////////////////////////////////////////////////////////////////////
404 // Outputs (final and intermediates)
405
406 // Processed apex manifest in JSONson format (for Q)
407 manifestJsonOut android.WritablePath
408
409 // Processed apex manifest in PB format (for R+)
410 manifestPbOut android.WritablePath
411
412 // Processed file_contexts files
413 fileContexts android.WritablePath
414
Bob Badourde6a0872022-04-01 18:00:00 +0000415 // Path to notice file in html.gz format.
416 htmlGzNotice android.WritablePath
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900417
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900418 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900419 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900420 outputFile android.WritablePath
421
Jooyung Hana6d36672022-02-24 13:58:07 +0900422 // The built uncompressed .apex file.
423 outputApexFile android.WritablePath
424
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900425 // The built APEX file in app bundle format. This file is not directly installed to the
426 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
427 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
428 // system) to be merged into a single app bundle file that Play accepts. See
429 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
430 bundleModuleFile android.WritablePath
431
Colin Cross6340ea52021-11-04 12:01:18 -0700432 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900433 installDir android.InstallPath
434
Colin Cross6340ea52021-11-04 12:01:18 -0700435 // Path where this APEX was installed.
436 installedFile android.InstallPath
437
438 // Installed locations of symlinks for backward compatibility.
439 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900440
441 // Text file having the list of individual files that are included in this APEX. Used for
442 // debugging purpose.
443 installedFilesFile android.WritablePath
444
445 // List of module names that this APEX is including (to be shown via *-deps-info target).
446 // Used for debugging purpose.
447 android.ApexBundleDepsInfo
448
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900449 // Optional list of lint report zip files for apexes that contain java or app modules
450 lintReports android.Paths
451
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900452 prebuiltFileToDelete string
sophiezc80a2b32020-11-12 16:39:19 +0000453
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000454 isCompressed bool
455
sophiezc80a2b32020-11-12 16:39:19 +0000456 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700457 nativeApisUsedByModuleFile android.ModuleOutPath
458 nativeApisBackedByModuleFile android.ModuleOutPath
459 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800460
461 // Collect the module directory for IDE info in java/jdeps.go.
462 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900463}
464
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900465// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900466type apexFileClass int
467
Jooyung Han72bd2f82019-10-23 16:46:38 +0900468const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900469 app apexFileClass = iota
470 appSet
471 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900472 goBinary
473 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900474 nativeExecutable
475 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900476 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900477 pyBinary
478 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900479)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900480
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900481// apexFile represents a file in an APEX bundle. This is created during the first half of
482// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
483// of the function, this is used to create commands that copies the files into a staging directory,
484// where they are packaged into the APEX file. This struct is also used for creating Make modules
485// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900486type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900487 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000488 builtFile android.Path
489 installDir string
490 customStem string
491 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900492
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900493 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
494 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
495 // suffix>]
496 androidMkModuleName string // becomes LOCAL_MODULE
497 class apexFileClass // becomes LOCAL_MODULE_CLASS
498 moduleDir string // becomes LOCAL_PATH
499 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
500 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
501 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
502 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900503
504 jacocoReportClassesFile android.Path // only for javalibs and apps
505 lintDepSets java.LintDepSets // only for javalibs and apps
506 certificate java.Certificate // only for apps
507 overriddenPackageName string // only for apps
508
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900509 transitiveDep bool
510 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900511
Jiyong Park57621b22021-01-20 20:33:11 +0900512 multilib string
513
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900514 // TODO(jiyong): remove this
515 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900516}
517
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900518// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900519func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
520 ret := apexFile{
521 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900522 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900523 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900524 class: class,
525 module: module,
526 }
527 if module != nil {
528 ret.moduleDir = ctx.OtherModuleDir(module)
529 ret.requiredModuleNames = module.RequiredModuleNames()
530 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
531 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900532 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900533 }
534 return ret
535}
536
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900537func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900538 return af.builtFile != nil && af.builtFile.String() != ""
539}
540
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900541// apexRelativePath returns the relative path of the given path from the install directory of this
542// apexFile.
543// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900544func (af *apexFile) apexRelativePath(path string) string {
545 return filepath.Join(af.installDir, path)
546}
547
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900548// path returns path of this apex file relative to the APEX root
549func (af *apexFile) path() string {
550 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900551}
552
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900553// stem returns the base filename of this apex file
554func (af *apexFile) stem() string {
555 if af.customStem != "" {
556 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900557 }
558 return af.builtFile.Base()
559}
560
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900561// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
562func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900563 var ret []string
564 for _, symlink := range af.symlinks {
565 ret = append(ret, af.apexRelativePath(symlink))
566 }
567 return ret
568}
569
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900570// availableToPlatform tests whether this apexFile is from a module that can be installed to the
571// platform.
572func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900573 if af.module == nil {
574 return false
575 }
576 if am, ok := af.module.(android.ApexModule); ok {
577 return am.AvailableFor(android.AvailableToPlatform)
578 }
579 return false
580}
581
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900582////////////////////////////////////////////////////////////////////////////////////////////////////
583// Mutators
584//
585// Brief description about mutators for APEX. The following three mutators are the most important
586// ones.
587//
588// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
589// to the (direct) dependencies of this APEX bundle.
590//
Paul Duffin949abc02020-12-08 10:34:30 +0000591// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900592// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
593// modules are marked as being included in the APEX via BuildForApex().
594//
Paul Duffin949abc02020-12-08 10:34:30 +0000595// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
596// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900597
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900598type dependencyTag struct {
599 blueprint.BaseDependencyTag
600 name string
601
602 // Determines if the dependent will be part of the APEX payload. Can be false for the
603 // dependencies to the signing key module, etc.
604 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000605
606 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
607 // replacement. This is needed because some prebuilt modules do not provide all the information
608 // needed by the apex.
609 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000610
611 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
612 // also be added as exported members of that SDK.
613 memberType android.SdkMemberType
614}
615
616func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
617 return d.memberType
618}
619
620func (d *dependencyTag) ExportMember() bool {
621 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900622}
623
Paul Duffin520917a2022-05-13 13:01:59 +0000624func (d *dependencyTag) String() string {
625 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
626}
627
628func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000629 return !d.sourceOnly
630}
631
632var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000633var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000634
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900635var (
Paul Duffin520917a2022-05-13 13:01:59 +0000636 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
637 bpfTag = &dependencyTag{name: "bpf", payload: true}
638 certificateTag = &dependencyTag{name: "certificate"}
639 executableTag = &dependencyTag{name: "executable", payload: true}
640 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000641 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
642 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000643 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000644 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
645 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
646 keyTag = &dependencyTag{name: "key"}
647 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
648 rroTag = &dependencyTag{name: "rro", payload: true}
649 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
650 testForTag = &dependencyTag{name: "test for"}
651 testTag = &dependencyTag{name: "test", payload: true}
652 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900653)
654
655// TODO(jiyong): shorten this function signature
656func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900657 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900658 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900659 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900660
661 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900662 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900663 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
664 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900665 }
666
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900667 // Use *FarVariation* to be able to depend on modules having conflicting variations with
668 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
669 // 'arm' or 'arm64' for native shared libs.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900670 ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900671 ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900672 ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
673 ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
Jiyong Park99644e92020-11-17 22:21:02 +0900674 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
Jiyong Park06711462021-02-15 17:54:43 +0900675 ctx.AddFarVariationDependencies(target.Variations(), fsTag, nativeModules.Filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900676}
677
678func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900679 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900680 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
681 } else {
682 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
683 if ctx.Os().Bionic() {
684 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
685 } else {
686 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
687 }
688 }
689}
690
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900691// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
692// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
693func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
694 deviceConfig := ctx.DeviceConfig()
695 if a.vndkApex {
696 return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900697 }
698
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900699 var prefix string
700 var vndkVersion string
701 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000702 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900703 prefix = cc.VendorVariationPrefix
704 vndkVersion = deviceConfig.VndkVersion()
705 } else if a.ProductSpecific() {
706 prefix = cc.ProductVariationPrefix
707 vndkVersion = deviceConfig.ProductVndkVersion()
708 }
709 }
710 if vndkVersion == "current" {
711 vndkVersion = deviceConfig.PlatformVndkVersion()
712 }
713 if vndkVersion != "" {
714 return prefix + vndkVersion
715 }
716
717 return android.CoreVariation // The usual case
718}
719
720func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900721 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
722 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
723 // each target os/architectures, appropriate dependencies are selected by their
724 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900725 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900726 imageVariation := a.getImageVariation(ctx)
727
728 a.combineProperties(ctx)
729
730 has32BitTarget := false
731 for _, target := range targets {
732 if target.Arch.ArchType.Multilib == "lib32" {
733 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000734 }
735 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900736 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900737 // Don't include artifacts for the host cross targets because there is no way for us
738 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900739 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900740 continue
741 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000742
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900743 var depsList []ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000744
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900745 // Add native modules targeting both ABIs. When multilib.* is omitted for
746 // native_shared_libs/jni_libs/tests, it implies multilib.both
747 depsList = append(depsList, a.properties.Multilib.Both)
748 depsList = append(depsList, ApexNativeDependencies{
749 Native_shared_libs: a.properties.Native_shared_libs,
750 Tests: a.properties.Tests,
751 Jni_libs: a.properties.Jni_libs,
752 Binaries: nil,
753 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900754
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900755 // Add native modules targeting the first ABI When multilib.* is omitted for
756 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900757 isPrimaryAbi := i == 0
758 if isPrimaryAbi {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900759 depsList = append(depsList, a.properties.Multilib.First)
760 depsList = append(depsList, ApexNativeDependencies{
761 Native_shared_libs: nil,
762 Tests: nil,
763 Jni_libs: nil,
764 Binaries: a.properties.Binaries,
765 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900766 }
767
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900768 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900769 switch target.Arch.ArchType.Multilib {
770 case "lib32":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900771 depsList = append(depsList, a.properties.Multilib.Lib32)
772 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900773 case "lib64":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900774 depsList = append(depsList, a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900775 if !has32BitTarget {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900776 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900777 }
778 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900779
Jiyong Park59140302020-12-14 18:44:04 +0900780 // Add native modules targeting a specific arch variant
781 switch target.Arch.ArchType {
782 case android.Arm:
783 depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
784 case android.Arm64:
785 depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
786 case android.X86:
787 depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
788 case android.X86_64:
789 depsList = append(depsList, a.archProperties.Arch.X86_64.ApexNativeDependencies)
790 default:
791 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
792 }
793
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900794 for _, d := range depsList {
795 addDependenciesForNativeModules(ctx, d, target, imageVariation)
796 }
Sundong Ahn80c04892021-11-23 00:57:19 +0000797 ctx.AddFarVariationDependencies([]blueprint.Variation{
798 {Mutator: "os", Variation: target.OsVariation()},
799 {Mutator: "arch", Variation: target.ArchVariation()},
800 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900801 }
802
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900803 // Common-arch dependencies come next
804 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900805 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000806 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100807}
808
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900809// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900810func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
811 if a.overridableProperties.Allowed_files != nil {
812 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100813 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900814
815 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
816 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800817 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900818 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900819 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
820 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
821 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700822 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
823 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
824 // regardless of the TARGET_PREFER_* setting. See b/144532908
825 arches := ctx.DeviceConfig().Arches()
826 if len(arches) != 0 {
827 archForPrebuiltEtc := arches[0]
828 for _, arch := range arches {
829 // Prefer 64-bit arch if there is any
830 if arch.ArchType.Multilib == "lib64" {
831 archForPrebuiltEtc = arch
832 break
833 }
834 }
835 ctx.AddFarVariationDependencies([]blueprint.Variation{
836 {Mutator: "os", Variation: ctx.Os().String()},
837 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
838 }, prebuiltTag, prebuilts...)
839 }
840 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700841
842 // Dependencies for signing
843 if String(a.overridableProperties.Key) == "" {
844 ctx.PropertyErrorf("key", "missing")
845 return
846 }
847 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
848
849 cert := android.SrcIsModule(a.getCertString(ctx))
850 if cert != "" {
851 ctx.AddDependency(ctx.Module(), certificateTag, cert)
852 // empty cert is not an error. Cert and private keys will be directly found under
853 // PRODUCT_DEFAULT_DEV_CERTIFICATE
854 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100855}
856
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900857type ApexBundleInfo struct {
858 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100859}
860
Paul Duffin949abc02020-12-08 10:34:30 +0000861var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900862
Paul Duffina7d6a892020-12-07 17:39:59 +0000863var _ ApexInfoMutator = (*apexBundle)(nil)
864
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100865func (a *apexBundle) ApexVariationName() string {
866 return a.properties.ApexVariationName
867}
868
Paul Duffina7d6a892020-12-07 17:39:59 +0000869// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900870// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
871// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
872// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
873// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000874//
875// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
876// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
877// The apexMutator uses that list to create module variants for the apexes to which it belongs.
878// The relationship between module variants and apexes is not one-to-one as variants will be
879// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000880func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900881
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900882 // The VNDK APEX is special. For the APEX, the membership is described in a very different
883 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
884 // libraries are self-identified by their vndk.enabled properties. There is no need to run
885 // this mutator for the APEX as nothing will be collected. So, let's return fast.
886 if a.vndkApex {
887 return
888 }
889
890 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
891 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
892 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
893 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
894 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900895 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
896 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900897 if proptools.Bool(a.properties.Use_vndk_as_stable) {
898 if !useVndk {
899 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
900 }
901 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
902 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
903 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
904 }
905 })
906 if mctx.Failed() {
907 return
908 }
Jooyung Handf78e212020-07-22 15:54:47 +0900909 }
910
Colin Cross56a83212020-09-15 18:30:11 -0700911 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900912 am, ok := child.(android.ApexModule)
913 if !ok || !am.CanHaveApexVariants() {
914 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900915 }
Paul Duffin573989d2021-03-17 13:25:29 +0000916 depTag := mctx.OtherModuleDependencyTag(child)
917
918 // Check to see if the tag always requires that the child module has an apex variant for every
919 // apex variant of the parent module. If it does not then it is still possible for something
920 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
921 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
922 return true
923 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000924 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900925 return false
926 }
Jooyung Handf78e212020-07-22 15:54:47 +0900927 if excludeVndkLibs {
928 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
929 return false
930 }
931 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900932 // By default, all the transitive dependencies are collected, unless filtered out
933 // above.
Colin Cross56a83212020-09-15 18:30:11 -0700934 return true
935 }
936
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900937 // Records whether a certain module is included in this apexBundle via direct dependency or
938 // inndirect dependency.
939 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -0700940 mctx.WalkDeps(func(child, parent android.Module) bool {
941 if !continueApexDepsWalk(child, parent) {
942 return false
943 }
Jooyung Han698dd9f2020-07-22 15:17:19 +0900944 // If the parent is apexBundle, this child is directly depended.
945 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900946 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -0700947 contents[depName] = contents[depName].Add(directDep)
948 return true
949 })
950
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900951 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +0900952 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -0700953 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
954 Contents: apexContents,
955 })
956
Jooyung Haned124c32021-01-26 11:43:46 +0900957 minSdkVersion := a.minSdkVersion(mctx)
958 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
959 if minSdkVersion.IsNone() {
960 minSdkVersion = android.FutureApiLevel
961 }
962
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900963 // This is the main part of this mutator. Mark the collected dependencies that they need to
964 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +0900965
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100966 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
967 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -0700968 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100969 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +0900970 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -0700971 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +0900972 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100973 InApexVariants: []string{apexVariationName},
974 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -0700975 ApexContents: []*android.ApexContents{apexContents},
976 }
Colin Cross56a83212020-09-15 18:30:11 -0700977 mctx.WalkDeps(func(child, parent android.Module) bool {
978 if !continueApexDepsWalk(child, parent) {
979 return false
980 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900981 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +0900982 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +0900983 })
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900984}
985
Paul Duffina7d6a892020-12-07 17:39:59 +0000986type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100987 // ApexVariationName returns the name of the APEX variation to use in the apex
988 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
989 ApexVariationName() string
990
Paul Duffina7d6a892020-12-07 17:39:59 +0000991 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
992 // depended upon by an apex and which require an apex specific variant.
993 ApexInfoMutator(android.TopDownMutatorContext)
994}
995
996// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
997// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +0000998// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +0000999func apexInfoMutator(mctx android.TopDownMutatorContext) {
1000 if !mctx.Module().Enabled() {
1001 return
1002 }
1003
1004 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1005 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001006 }
Spandan Das42e89502022-05-06 22:12:55 +00001007 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001008}
1009
Spandan Das66773252022-01-15 00:23:18 +00001010// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1011// This check is enforced for updatable modules
1012func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1013 if !mctx.Module().Enabled() {
1014 return
1015 }
Spandan Das08c911f2022-01-21 22:07:26 +00001016 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001017 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001018 // b/208656169 Do not propagate strict updatability linting to libcore/
1019 // These libs are available on the classpath during compilation
1020 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1021 // Only skip libraries defined in libcore root, not subdirectories
1022 if mctx.OtherModuleDir(child) == "libcore" {
1023 // Do not traverse transitive deps of libcore/ libs
1024 return false
1025 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001026 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1027 return false
1028 }
Spandan Das66773252022-01-15 00:23:18 +00001029 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1030 lintable.SetStrictUpdatabilityLinting(true)
1031 }
1032 // visit transitive deps
1033 return true
1034 })
1035 }
1036}
1037
Spandan Das42e89502022-05-06 22:12:55 +00001038// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1039func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1040 if !mctx.Module().Enabled() {
1041 return
1042 }
1043 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1044 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1045 mctx.VisitDirectDeps(func(module android.Module) {
1046 // ignore android_test_app
1047 if app, ok := module.(*java.AndroidApp); ok {
1048 app.SetUpdatable(true)
1049 }
1050 })
1051 }
1052}
1053
Spandan Das08c911f2022-01-21 22:07:26 +00001054// TODO: b/215736885 Whittle the denylist
1055// Transitive deps of certain mainline modules baseline NewApi errors
1056// Skip these mainline modules for now
1057var (
1058 skipStrictUpdatabilityLintAllowlist = []string{
1059 "com.android.art",
1060 "com.android.art.debug",
1061 "com.android.conscrypt",
1062 "com.android.media",
1063 // test apexes
1064 "test_com.android.art",
1065 "test_com.android.conscrypt",
1066 "test_com.android.media",
1067 "test_jitzygote_com.android.art",
1068 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001069
1070 // TODO: b/215736885 Remove this list
1071 skipLintJavalibAllowlist = []string{
1072 "conscrypt.module.platform.api.stubs",
1073 "conscrypt.module.public.api.stubs",
1074 "conscrypt.module.public.api.stubs.system",
1075 "conscrypt.module.public.api.stubs.module_lib",
1076 "framework-media.stubs",
1077 "framework-media.stubs.system",
1078 "framework-media.stubs.module_lib",
1079 }
Spandan Das08c911f2022-01-21 22:07:26 +00001080)
1081
1082func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1083 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1084}
1085
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001086// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1087// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1088// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001089func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1090 if !mctx.Module().Enabled() {
1091 return
1092 }
1093 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001094 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1095 }
1096}
1097
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001098// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1099// the apex in order to retrieve its contents later.
1100// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001101func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1102 if !mctx.Module().Enabled() {
1103 return
1104 }
Colin Cross56a83212020-09-15 18:30:11 -07001105 if am, ok := mctx.Module().(android.ApexModule); ok {
1106 if testFor := am.TestFor(); len(testFor) > 0 {
1107 mctx.AddFarVariationDependencies([]blueprint.Variation{
1108 {Mutator: "os", Variation: am.Target().OsVariation()},
1109 {"arch", "common"},
1110 }, testForTag, testFor...)
1111 }
1112 }
1113}
1114
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001115// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001116func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1117 if !mctx.Module().Enabled() {
1118 return
1119 }
Colin Cross56a83212020-09-15 18:30:11 -07001120 if _, ok := mctx.Module().(android.ApexModule); ok {
1121 var contents []*android.ApexContents
1122 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1123 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1124 contents = append(contents, abInfo.Contents)
1125 }
1126 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1127 ApexContents: contents,
1128 })
Colin Crossaede88c2020-08-11 12:17:01 -07001129 }
1130}
1131
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001132// markPlatformAvailability marks whether or not a module can be available to platform. A module
1133// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1134// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1135// be) available to platform
1136// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001137func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1138 // Host and recovery are not considered as platform
1139 if mctx.Host() || mctx.Module().InstallInRecovery() {
1140 return
1141 }
1142
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001143 am, ok := mctx.Module().(android.ApexModule)
1144 if !ok {
1145 return
1146 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001147
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001148 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001149
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001150 // If any of the dep is not available to platform, this module is also considered as being
1151 // not available to platform even if it has "//apex_available:platform"
1152 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001153 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001154 // if the dependency crosses apex boundary, don't consider it
1155 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001156 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001157 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1158 availableToPlatform = false
1159 // TODO(b/154889534) trigger an error when 'am' has
1160 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001161 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001162 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001163
Paul Duffinb5769c12021-05-12 16:16:51 +01001164 // Exception 1: check to see if the module always requires it.
1165 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001166 availableToPlatform = true
1167 }
1168
1169 // Exception 2: bootstrap bionic libraries are also always available to platform
1170 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1171 availableToPlatform = true
1172 }
1173
1174 if !availableToPlatform {
1175 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001176 }
1177}
1178
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001179// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001180// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001181func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001182 if !mctx.Module().Enabled() {
1183 return
1184 }
Colin Cross56a83212020-09-15 18:30:11 -07001185
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001186 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001187 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001188 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001189 return
1190 }
1191
1192 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001193 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1194 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001195 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001196 if strings.HasPrefix(apexBundleName, "com.android.art") {
1197 // Create an alias from the platform variant. This is done to make
1198 // test_for dependencies work for modules that are split by the APEX
1199 // mutator, since test_for dependencies always go to the platform variant.
1200 // This doesn't happen for normal APEXes that are disjunct, so only do
1201 // this for the overlapping ART APEXes.
1202 // TODO(b/183882457): Remove this if the test_for functionality is
1203 // refactored to depend on the proper APEX variants instead of platform.
1204 mctx.CreateAliasVariation("", apexBundleName)
1205 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001206 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1207 apexBundleName := o.GetOverriddenModuleName()
1208 if apexBundleName == "" {
1209 mctx.ModuleErrorf("base property is not set")
1210 return
1211 }
1212 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001213 if strings.HasPrefix(apexBundleName, "com.android.art") {
1214 // TODO(b/183882457): See note for CreateAliasVariation above.
1215 mctx.CreateAliasVariation("", apexBundleName)
1216 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001217 }
1218}
Sundong Ahne9b55722019-09-06 17:37:42 +09001219
Paul Duffin6717d882021-06-15 19:09:41 +01001220// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1221// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001222func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001223 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001224 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001225 return !a.vndkApex
1226 }
1227
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001228 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001229}
1230
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001231// See android.UpdateDirectlyInAnyApex
1232// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001233func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1234 if !mctx.Module().Enabled() {
1235 return
1236 }
1237 if am, ok := mctx.Module().(android.ApexModule); ok {
1238 android.UpdateDirectlyInAnyApex(mctx, am)
1239 }
1240}
1241
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001242// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001243type apexPackaging int
1244
1245const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001246 // imageApex is a packaging method where contents are included in a filesystem image which
1247 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001248 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001249
1250 // zipApex is a packaging method where contents are directly included in the zip container.
1251 // This is used for host-side testing - because the contents are easily accessible by
1252 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001253 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001254
1255 // flattendApex is a packaging method where contents are not included in the APEX file, but
1256 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1257 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001258 flattenedApex
1259)
1260
1261const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001262 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001263 imageApexSuffix = ".apex"
1264 imageCapexSuffix = ".capex"
1265 zipApexSuffix = ".zipapex"
1266 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001267
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001268 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001269 imageApexType = "image"
1270 zipApexType = "zip"
1271 flattenedApexType = "flattened"
1272
Dan Willemsen47e1a752021-10-16 18:36:13 -07001273 ext4FsType = "ext4"
1274 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001275 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001276)
1277
1278// The suffix for the output "file", not the module
1279func (a apexPackaging) suffix() string {
1280 switch a {
1281 case imageApex:
1282 return imageApexSuffix
1283 case zipApex:
1284 return zipApexSuffix
1285 default:
1286 panic(fmt.Errorf("unknown APEX type %d", a))
1287 }
1288}
1289
1290func (a apexPackaging) name() string {
1291 switch a {
1292 case imageApex:
1293 return imageApexType
1294 case zipApex:
1295 return zipApexType
1296 default:
1297 panic(fmt.Errorf("unknown APEX type %d", a))
1298 }
1299}
1300
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001301// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1302// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001303func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001304 if !mctx.Module().Enabled() {
1305 return
1306 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001307 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001308 var variants []string
1309 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1310 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001311 // This is the normal case. Note that both image and flattend APEXes are
1312 // created. The image type is installed to the system partition, while the
1313 // flattened APEX is (optionally) installed to the system_ext partition.
1314 // This is mostly for GSI which has to support wide range of devices. If GSI
1315 // is installed on a newer (APEX-capable) device, the image APEX in the
1316 // system will be used. However, if the same GSI is installed on an old
1317 // device which can't support image APEX, the flattened APEX in the
1318 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001319 variants = append(variants, imageApexType, flattenedApexType)
1320 case "zip":
1321 variants = append(variants, zipApexType)
1322 case "both":
1323 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1324 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001325 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001326 return
1327 }
1328
1329 modules := mctx.CreateLocalVariations(variants...)
1330
1331 for i, v := range variants {
1332 switch v {
1333 case imageApexType:
1334 modules[i].(*apexBundle).properties.ApexType = imageApex
1335 case zipApexType:
1336 modules[i].(*apexBundle).properties.ApexType = zipApex
1337 case flattenedApexType:
1338 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001339 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001340 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001341 modules[i].(*apexBundle).MakeAsSystemExt()
1342 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001343 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001344 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001345 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001346 // payload_type is forcibly overridden to "image"
1347 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001348 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001349 }
1350}
1351
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001352var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001353
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001354// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001355func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001356 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001357 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001358 return true
1359}
1360
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001361var _ android.OutputFileProducer = (*apexBundle)(nil)
1362
1363// Implements android.OutputFileProducer
1364func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1365 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001366 case "", android.DefaultDistTag:
1367 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001368 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001369 case imageApexSuffix:
1370 // uncompressed one
1371 if a.outputApexFile != nil {
1372 return android.Paths{a.outputApexFile}, nil
1373 }
1374 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001375 default:
1376 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1377 }
1378}
1379
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001380var _ multitree.Exportable = (*apexBundle)(nil)
1381
1382func (a *apexBundle) Exportable() bool {
1383 if a.properties.ApexType == flattenedApex {
1384 return false
1385 }
1386 return true
1387}
1388
1389func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1390 ret := make(map[string]android.Paths)
1391 ret["apex"] = android.Paths{a.outputFile}
1392 return ret
1393}
1394
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001395var _ cc.Coverage = (*apexBundle)(nil)
1396
1397// Implements cc.Coverage
1398func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1399 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1400}
1401
1402// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001403func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001404 a.properties.PreventInstall = true
1405}
1406
1407// Implements cc.Coverage
1408func (a *apexBundle) HideFromMake() {
1409 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001410 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1411 // TODO(ccross): untangle these
1412 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001413}
1414
1415// Implements cc.Coverage
1416func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1417 a.properties.IsCoverageVariant = coverage
1418}
1419
1420// Implements cc.Coverage
1421func (a *apexBundle) EnableCoverageIfNeeded() {}
1422
1423var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1424
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001425// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001426func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001427 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001428}
1429
Jiyong Parkf4020582021-11-29 12:37:10 +09001430func (a *apexBundle) FutureUpdatable() bool {
1431 return proptools.BoolDefault(a.properties.Future_updatable, false)
1432}
1433
Jiyong Park1bc84122021-06-22 20:23:05 +09001434func (a *apexBundle) UsePlatformApis() bool {
1435 return proptools.BoolDefault(a.properties.Platform_apis, false)
1436}
1437
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001438// getCertString returns the name of the cert that should be used to sign this APEX. This is
1439// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001440func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001441 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001442 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1443 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1444 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001445 if a.vndkApex {
1446 moduleName = vndkApexName
1447 }
1448 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001449 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001450 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001451 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001452 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001453}
1454
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001455// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001456func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001457 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001458}
1459
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001460// See the generate_hashtree property
1461func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001462 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001463}
1464
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001465// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001466func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1467 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1468}
1469
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001470// See the test_only_force_compression property
1471func (a *apexBundle) testOnlyShouldForceCompression() bool {
1472 return proptools.Bool(a.properties.Test_only_force_compression)
1473}
1474
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001475// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1476// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1477// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001478
Jiyong Parkf97782b2019-02-13 20:28:58 +09001479func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1480 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1481 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1482 }
1483}
1484
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001485func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001486 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1487 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001488 }
1489
1490 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001491 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001492 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001493 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001494 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001495 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001496 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001497 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001498 }
1499 }
1500 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001501}
1502
Jooyung Han8ce8db92020-05-15 19:05:05 +09001503func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001504 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1505 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001506 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001507 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001508 for _, target := range ctx.MultiTargets() {
1509 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001510 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001511 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001512 Tests: nil,
1513 Jni_libs: nil,
1514 Binaries: nil,
1515 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001516 break
1517 }
1518 }
1519 }
1520}
1521
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001522// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1523// returned apexFile saves information about the Soong module that will be used for creating the
1524// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001525func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001526 // Decide the APEX-local directory by the multilib of the library In the future, we may
1527 // query this to the module.
1528 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001529 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001530 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001531 case "lib32":
1532 dirInApex = "lib"
1533 case "lib64":
1534 dirInApex = "lib64"
1535 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001536 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001537 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001538 }
Jooyung Han35155c42020-02-06 17:33:20 +09001539 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001540 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001541 // Special case for Bionic libs and other libs installed with them. This is to
1542 // prevent those libs from being included in the search path
1543 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1544 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1545 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1546 // will be loaded into the default linker namespace (aka "platform" namespace). If
1547 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1548 // be loaded again into the runtime linker namespace, which will result in double
1549 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001550 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001551 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001552
Jiyong Parkf653b052019-11-18 15:39:01 +09001553 fileToCopy := ccMod.OutputFile().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001554 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1555 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001556}
1557
Jiyong Park1833cef2019-12-13 13:28:36 +09001558func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001559 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001560 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001561 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001562 }
Jooyung Han35155c42020-02-06 17:33:20 +09001563 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Jiyong Parkf653b052019-11-18 15:39:01 +09001564 fileToCopy := cc.OutputFile().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001565 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1566 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001567 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001568 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001569 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001570}
1571
Jiyong Park99644e92020-11-17 22:21:02 +09001572func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1573 dirInApex := "bin"
1574 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1575 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1576 }
1577 fileToCopy := rustm.OutputFile().Path()
1578 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1579 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1580 return af
1581}
1582
1583func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1584 // Decide the APEX-local directory by the multilib of the library
1585 // In the future, we may query this to the module.
1586 var dirInApex string
1587 switch rustm.Arch().ArchType.Multilib {
1588 case "lib32":
1589 dirInApex = "lib"
1590 case "lib64":
1591 dirInApex = "lib64"
1592 }
1593 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1594 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1595 }
1596 fileToCopy := rustm.OutputFile().Path()
1597 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1598 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1599}
1600
Jiyong Park1833cef2019-12-13 13:28:36 +09001601func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001602 dirInApex := "bin"
1603 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001604 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001605}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001606
Jiyong Park1833cef2019-12-13 13:28:36 +09001607func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001608 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001609 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001610 // NB: Since go binaries are static we don't need the module for anything here, which is
1611 // good since the go tool is a blueprint.Module not an android.Module like we would
1612 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001613 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001614}
1615
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001616func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001617 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001618 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1619 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1620 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001621 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001622 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001623 af.symlinks = sh.Symlinks()
1624 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001625}
1626
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001627func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001628 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001629 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001630 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001631}
1632
atrost6e126252020-01-27 17:01:16 +00001633func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1634 dirInApex := filepath.Join("etc", config.SubDir())
1635 fileToCopy := config.CompatConfig()
1636 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1637}
1638
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001639// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1640// way.
1641type javaModule interface {
1642 android.Module
1643 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001644 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001645 JacocoReportClassesFile() android.Path
1646 LintDepSets() java.LintDepSets
1647 Stem() string
1648}
1649
1650var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001651var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001652var _ javaModule = (*java.SdkLibrary)(nil)
1653var _ javaModule = (*java.DexImport)(nil)
1654var _ javaModule = (*java.SdkLibraryImport)(nil)
1655
Paul Duffin190fdef2021-04-26 10:33:59 +01001656// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001657func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001658 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001659}
1660
1661// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1662func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001663 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001664 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001665 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1666 af.lintDepSets = module.LintDepSets()
1667 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001668 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1669 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1670 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1671 }
1672 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001673 return af
1674}
1675
1676// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1677// the same way.
1678type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001679 android.Module
1680 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001681 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001682 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001683 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001684 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001685 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001686 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001687}
1688
1689var _ androidApp = (*java.AndroidApp)(nil)
1690var _ androidApp = (*java.AndroidAppImport)(nil)
1691
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001692func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1693 buildId := ctx.Config().BuildId()
1694
1695 // The build ID is used as a suffix for a filename, so ensure that
1696 // the set of characters being used are sanitized.
1697 // - any word character: [a-zA-Z0-9_]
1698 // - dots: .
1699 // - dashes: -
1700 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1701 if !validRegex.MatchString(buildId) {
1702 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1703 }
1704 return buildId
1705}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001706
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001707func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001708 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001709 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001710 appDir = "priv-app"
1711 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001712
1713 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1714 // so that PackageManager correctly invalidates the existing installed apk
1715 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001716 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001717 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001718
Yo Chiange8128052020-07-23 20:09:18 +08001719 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001720 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001721 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001722 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001723
1724 if app, ok := aapp.(interface {
1725 OverriddenManifestPackageName() string
1726 }); ok {
1727 af.overriddenPackageName = app.OverriddenManifestPackageName()
1728 }
Jiyong Park618922e2020-01-08 13:35:43 +09001729 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001730}
1731
Jiyong Park69aeba92020-04-24 21:16:36 +09001732func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1733 rroDir := "overlay"
1734 dirInApex := filepath.Join(rroDir, rro.Theme())
1735 fileToCopy := rro.OutputFile()
1736 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1737 af.certificate = rro.Certificate()
1738
1739 if a, ok := rro.(interface {
1740 OverriddenManifestPackageName() string
1741 }); ok {
1742 af.overriddenPackageName = a.OverriddenManifestPackageName()
1743 }
1744 return af
1745}
1746
Ken Chenfad7f9d2021-11-10 22:02:57 +08001747func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1748 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001749 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1750}
1751
Jiyong Park12a719c2021-01-07 15:31:24 +09001752func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1753 dirInApex := filepath.Join("etc", "fs")
1754 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1755}
1756
Paul Duffin064b70c2020-11-02 17:32:38 +00001757// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001758// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1759// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1760// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001761func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001762 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001763 am, ok := child.(android.ApexModule)
1764 if !ok || !am.CanHaveApexVariants() {
1765 return false
1766 }
1767
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001768 // Filter-out unwanted depedendencies
1769 depTag := ctx.OtherModuleDependencyTag(child)
1770 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1771 return false
1772 }
Paul Duffin520917a2022-05-13 13:01:59 +00001773 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001774 return false
1775 }
1776
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001777 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001778 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001779
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001780 // Visit actually
1781 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001782 })
1783}
1784
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001785// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1786type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001787
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001788const (
1789 ext4 fsType = iota
1790 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001791 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001792)
Artur Satayev849f8442020-04-28 14:57:42 +01001793
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001794func (f fsType) string() string {
1795 switch f {
1796 case ext4:
1797 return ext4FsType
1798 case f2fs:
1799 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001800 case erofs:
1801 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001802 default:
1803 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001804 }
1805}
1806
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001807var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1808
1809func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1810 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1811}
1812
1813func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1814 bazelCtx := ctx.Config().BazelContext
1815 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1816}
1817
1818func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1819 if !a.commonBuildActions(ctx) {
1820 return
1821 }
1822
1823 a.setApexTypeAndSuffix(ctx)
1824 a.setPayloadFsType(ctx)
1825 a.setSystemLibLink(ctx)
1826
1827 if a.properties.ApexType != zipApex {
1828 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1829 }
1830
1831 bazelCtx := ctx.Config().BazelContext
1832 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1833 if err != nil {
1834 ctx.ModuleErrorf(err.Error())
1835 return
1836 }
1837 a.installDir = android.PathForModuleInstall(ctx, "apex")
1838 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1839 a.outputFile = a.outputApexFile
1840 a.setCompression(ctx)
1841
1842 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[0])
1843 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[1])
1844 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[0])
1845 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[1])
1846 apexType := a.properties.ApexType
1847 switch apexType {
1848 case imageApex:
1849 // TODO(asmundak): Bazel does not create these files yet.
1850 // b/190817312
1851 a.htmlGzNotice = android.PathForBazelOut(ctx, "NOTICE.html.gz")
1852 // b/239081457
1853 a.bundleModuleFile = android.PathForBazelOut(ctx, a.Name()+apexType.suffix()+"-base.zip")
1854 // b/239081455
1855 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.txt"))
1856 // b/239081456
1857 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_backing.txt"))
1858 // b/239084755
1859 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.xml"))
1860 installSuffix := imageApexSuffix
1861 if a.isCompressed {
1862 installSuffix = imageCapexSuffix
1863 }
1864 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1865 a.compatSymlinks.Paths()...)
1866 default:
1867 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1868 }
1869
1870 /*
1871 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1872 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1873 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1874 To find out what Soong build puts there, run:
1875 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1876 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1877 return a.depVisitor(&vctx, ctx, child, parent)
1878 })
1879 vctx.normalizeFileInfo()
1880 */
1881
1882}
1883
1884func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1885 if a.properties.ApexType != imageApex {
1886 a.isCompressed = false
1887 } else if a.testOnlyShouldForceCompression() {
1888 a.isCompressed = true
1889 } else {
1890 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1891 }
1892}
1893
1894func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1895 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1896 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1897 // the same library in the system partition, thus effectively sharing the same libraries
1898 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1899 // in the APEX.
1900 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1901
1902 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1903 // So we can't link them to /system/lib libs which are core variants.
1904 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1905 a.linkToSystemLib = false
1906 }
1907
1908 forced := ctx.Config().ForceApexSymlinkOptimization()
1909 updatable := a.Updatable() || a.FutureUpdatable()
1910
1911 // We don't need the optimization for updatable APEXes, as it might give false signal
1912 // to the system health when the APEXes are still bundled (b/149805758).
1913 if !forced && updatable && a.properties.ApexType == imageApex {
1914 a.linkToSystemLib = false
1915 }
1916
1917 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1918 if ctx.Host() {
1919 a.linkToSystemLib = false
1920 }
1921}
1922
1923func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1924 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
1925 case ext4FsType:
1926 a.payloadFsType = ext4
1927 case f2fsFsType:
1928 a.payloadFsType = f2fs
1929 case erofsFsType:
1930 a.payloadFsType = erofs
1931 default:
1932 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
1933 }
1934}
1935
1936func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
1937 // Set suffix and primaryApexType depending on the ApexType
1938 buildFlattenedAsDefault := ctx.Config().FlattenApex()
1939 switch a.properties.ApexType {
1940 case imageApex:
1941 if buildFlattenedAsDefault {
1942 a.suffix = imageApexSuffix
1943 } else {
1944 a.suffix = ""
1945 a.primaryApexType = true
1946
1947 if ctx.Config().InstallExtraFlattenedApexes() {
1948 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
1949 }
1950 }
1951 case zipApex:
1952 if proptools.String(a.properties.Payload_type) == "zip" {
1953 a.suffix = ""
1954 a.primaryApexType = true
1955 } else {
1956 a.suffix = zipApexSuffix
1957 }
1958 case flattenedApex:
1959 if buildFlattenedAsDefault {
1960 a.suffix = ""
1961 a.primaryApexType = true
1962 } else {
1963 a.suffix = flattenedSuffix
1964 }
1965 }
1966}
1967
1968func (a apexBundle) isCompressable() bool {
1969 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
1970}
1971
1972func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
1973 a.checkApexAvailability(ctx)
1974 a.checkUpdatable(ctx)
1975 a.CheckMinSdkVersion(ctx)
1976 a.checkStaticLinkingToStubLibraries(ctx)
1977 a.checkStaticExecutables(ctx)
1978 if len(a.properties.Tests) > 0 && !a.testApex {
1979 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
1980 return false
1981 }
1982 return true
1983}
1984
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001985type visitorContext struct {
1986 // all the files that will be included in this APEX
1987 filesInfo []apexFile
1988
1989 // native lib dependencies
1990 provideNativeLibs []string
1991 requireNativeLibs []string
1992
1993 handleSpecialLibs bool
1994}
1995
1996func (vctx *visitorContext) normalizeFileInfo() {
1997 encountered := make(map[string]apexFile)
1998 for _, f := range vctx.filesInfo {
1999 dest := filepath.Join(f.installDir, f.builtFile.Base())
2000 if e, ok := encountered[dest]; !ok {
2001 encountered[dest] = f
2002 } else {
2003 // If a module is directly included and also transitively depended on
2004 // consider it as directly included.
2005 e.transitiveDep = e.transitiveDep && f.transitiveDep
2006 encountered[dest] = e
2007 }
2008 }
2009 vctx.filesInfo = vctx.filesInfo[:0]
2010 for _, v := range encountered {
2011 vctx.filesInfo = append(vctx.filesInfo, v)
2012 }
2013 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2014 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2015 // changes.
2016 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2017 })
2018}
2019
2020func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2021 depTag := ctx.OtherModuleDependencyTag(child)
2022 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2023 return false
2024 }
2025 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2026 return false
2027 }
2028 depName := ctx.OtherModuleName(child)
2029 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2030 switch depTag {
2031 case sharedLibTag, jniLibTag:
2032 isJniLib := depTag == jniLibTag
2033 switch ch := child.(type) {
2034 case *cc.Module:
2035 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2036 fi.isJniLib = isJniLib
2037 vctx.filesInfo = append(vctx.filesInfo, fi)
2038 // Collect the list of stub-providing libs except:
2039 // - VNDK libs are only for vendors
2040 // - bootstrap bionic libs are treated as provided by system
2041 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2042 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2043 }
2044 return true // track transitive dependencies
2045 case *rust.Module:
2046 fi := apexFileForRustLibrary(ctx, ch)
2047 fi.isJniLib = isJniLib
2048 vctx.filesInfo = append(vctx.filesInfo, fi)
2049 return true // track transitive dependencies
2050 default:
2051 propertyName := "native_shared_libs"
2052 if isJniLib {
2053 propertyName = "jni_libs"
2054 }
2055 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2056 }
2057 case executableTag:
2058 switch ch := child.(type) {
2059 case *cc.Module:
2060 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2061 return true // track transitive dependencies
2062 case *python.Module:
2063 if ch.HostToolPath().Valid() {
2064 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2065 }
2066 case bootstrap.GoBinaryTool:
2067 if a.Host() {
2068 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2069 }
2070 case *rust.Module:
2071 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2072 return true // track transitive dependencies
2073 default:
2074 ctx.PropertyErrorf("binaries",
2075 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2076 }
2077 case shBinaryTag:
2078 if csh, ok := child.(*sh.ShBinary); ok {
2079 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2080 } else {
2081 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2082 }
2083 case bcpfTag:
2084 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2085 if !ok {
2086 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2087 return false
2088 }
2089
2090 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2091 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2092 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2093 }
2094 return true
2095 case sscpfTag:
2096 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2097 ctx.PropertyErrorf("systemserverclasspath_fragments",
2098 "%q is not a systemserverclasspath_fragment module", depName)
2099 return false
2100 }
2101 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2102 vctx.filesInfo = append(vctx.filesInfo, *af)
2103 }
2104 return true
2105 case javaLibTag:
2106 switch child.(type) {
2107 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2108 af := apexFileForJavaModule(ctx, child.(javaModule))
2109 if !af.ok() {
2110 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2111 return false
2112 }
2113 vctx.filesInfo = append(vctx.filesInfo, af)
2114 return true // track transitive dependencies
2115 default:
2116 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2117 }
2118 case androidAppTag:
2119 switch ap := child.(type) {
2120 case *java.AndroidApp:
2121 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2122 return true // track transitive dependencies
2123 case *java.AndroidAppImport:
2124 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2125 case *java.AndroidTestHelperApp:
2126 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2127 case *java.AndroidAppSet:
2128 appDir := "app"
2129 if ap.Privileged() {
2130 appDir = "priv-app"
2131 }
2132 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2133 // suffixed so that PackageManager correctly invalidates the
2134 // existing installed apk in favour of the new APK-in-APEX.
2135 // See bugs for more information.
2136 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2137 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2138 af.certificate = java.PresignedCertificate
2139 vctx.filesInfo = append(vctx.filesInfo, af)
2140 default:
2141 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2142 }
2143 case rroTag:
2144 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2145 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2146 } else {
2147 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2148 }
2149 case bpfTag:
2150 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2151 filesToCopy, _ := bpfProgram.OutputFiles("")
2152 apex_sub_dir := bpfProgram.SubDir()
2153 for _, bpfFile := range filesToCopy {
2154 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2155 }
2156 } else {
2157 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2158 }
2159 case fsTag:
2160 if fs, ok := child.(filesystem.Filesystem); ok {
2161 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2162 } else {
2163 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2164 }
2165 case prebuiltTag:
2166 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2167 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2168 } else {
2169 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2170 }
2171 case compatConfigTag:
2172 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2173 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2174 } else {
2175 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2176 }
2177 case testTag:
2178 if ccTest, ok := child.(*cc.Module); ok {
2179 if ccTest.IsTestPerSrcAllTestsVariation() {
2180 // Multiple-output test module (where `test_per_src: true`).
2181 //
2182 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2183 // We do not add this variation to `filesInfo`, as it has no output;
2184 // however, we do add the other variations of this module as indirect
2185 // dependencies (see below).
2186 } else {
2187 // Single-output test module (where `test_per_src: false`).
2188 af := apexFileForExecutable(ctx, ccTest)
2189 af.class = nativeTest
2190 vctx.filesInfo = append(vctx.filesInfo, af)
2191 }
2192 return true // track transitive dependencies
2193 } else {
2194 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2195 }
2196 case keyTag:
2197 if key, ok := child.(*apexKey); ok {
2198 a.privateKeyFile = key.privateKeyFile
2199 a.publicKeyFile = key.publicKeyFile
2200 } else {
2201 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2202 }
2203 case certificateTag:
2204 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2205 a.containerCertificateFile = dep.Certificate.Pem
2206 a.containerPrivateKeyFile = dep.Certificate.Key
2207 } else {
2208 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2209 }
2210 case android.PrebuiltDepTag:
2211 // If the prebuilt is force disabled, remember to delete the prebuilt file
2212 // that might have been installed in the previous builds
2213 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2214 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2215 }
2216 }
2217 return false
2218 }
2219
2220 if a.vndkApex {
2221 return false
2222 }
2223
2224 // indirect dependencies
2225 am, ok := child.(android.ApexModule)
2226 if !ok {
2227 return false
2228 }
2229 // We cannot use a switch statement on `depTag` here as the checked
2230 // tags used below are private (e.g. `cc.sharedDepTag`).
2231 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2232 if ch, ok := child.(*cc.Module); ok {
2233 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2234 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2235 return false
2236 }
2237 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2238 af.transitiveDep = true
2239
2240 // Always track transitive dependencies for host.
2241 if a.Host() {
2242 vctx.filesInfo = append(vctx.filesInfo, af)
2243 return true
2244 }
2245
2246 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2247 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2248 // If the dependency is a stubs lib, don't include it in this APEX,
2249 // but make sure that the lib is installed on the device.
2250 // In case no APEX is having the lib, the lib is installed to the system
2251 // partition.
2252 //
2253 // Always include if we are a host-apex however since those won't have any
2254 // system libraries.
2255 if !am.DirectlyInAnyApex() {
2256 // we need a module name for Make
2257 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2258 if !android.InList(name, a.requiredDeps) {
2259 a.requiredDeps = append(a.requiredDeps, name)
2260 }
2261 }
2262 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2263 // Don't track further
2264 return false
2265 }
2266
2267 // If the dep is not considered to be in the same
2268 // apex, don't add it to filesInfo so that it is not
2269 // included in this APEX.
2270 // TODO(jiyong): move this to at the top of the
2271 // else-if clause for the indirect dependencies.
2272 // Currently, that's impossible because we would
2273 // like to record requiredNativeLibs even when
2274 // DepIsInSameAPex is false. We also shouldn't do
2275 // this for host.
2276 //
2277 // TODO(jiyong): explain why the same module is passed in twice.
2278 // Switching the first am to parent breaks lots of tests.
2279 if !android.IsDepInSameApex(ctx, am, am) {
2280 return false
2281 }
2282
2283 vctx.filesInfo = append(vctx.filesInfo, af)
2284 return true // track transitive dependencies
2285 } else if rm, ok := child.(*rust.Module); ok {
2286 af := apexFileForRustLibrary(ctx, rm)
2287 af.transitiveDep = true
2288 vctx.filesInfo = append(vctx.filesInfo, af)
2289 return true // track transitive dependencies
2290 }
2291 } else if cc.IsTestPerSrcDepTag(depTag) {
2292 if ch, ok := child.(*cc.Module); ok {
2293 af := apexFileForExecutable(ctx, ch)
2294 // Handle modules created as `test_per_src` variations of a single test module:
2295 // use the name of the generated test binary (`fileToCopy`) instead of the name
2296 // of the original test module (`depName`, shared by all `test_per_src`
2297 // variations of that module).
2298 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2299 // these are not considered transitive dep
2300 af.transitiveDep = false
2301 vctx.filesInfo = append(vctx.filesInfo, af)
2302 return true // track transitive dependencies
2303 }
2304 } else if cc.IsHeaderDepTag(depTag) {
2305 // nothing
2306 } else if java.IsJniDepTag(depTag) {
2307 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2308 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2309 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2310 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2311 }
2312 } else if rust.IsDylibDepTag(depTag) {
2313 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2314 af := apexFileForRustLibrary(ctx, rustm)
2315 af.transitiveDep = true
2316 vctx.filesInfo = append(vctx.filesInfo, af)
2317 return true // track transitive dependencies
2318 }
2319 } else if rust.IsRlibDepTag(depTag) {
2320 // Rlib is statically linked, but it might have shared lib
2321 // dependencies. Track them.
2322 return true
2323 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2324 // Add the contents of the bootclasspath fragment to the apex.
2325 switch child.(type) {
2326 case *java.Library, *java.SdkLibrary:
2327 javaModule := child.(javaModule)
2328 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2329 if !af.ok() {
2330 ctx.PropertyErrorf("bootclasspath_fragments",
2331 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2332 return false
2333 }
2334 vctx.filesInfo = append(vctx.filesInfo, af)
2335 return true // track transitive dependencies
2336 default:
2337 ctx.PropertyErrorf("bootclasspath_fragments",
2338 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2339 }
2340 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2341 // Add the contents of the systemserverclasspath fragment to the apex.
2342 switch child.(type) {
2343 case *java.Library, *java.SdkLibrary:
2344 af := apexFileForJavaModule(ctx, child.(javaModule))
2345 vctx.filesInfo = append(vctx.filesInfo, af)
2346 return true // track transitive dependencies
2347 default:
2348 ctx.PropertyErrorf("systemserverclasspath_fragments",
2349 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2350 }
2351 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2352 // nothing
2353 } else if depTag == android.DarwinUniversalVariantTag {
2354 // nothing
2355 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2356 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2357 }
2358 return false
2359}
2360
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002361// Creates build rules for an APEX. It consists of the following major steps:
2362//
2363// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2364// 2) traverse the dependency tree to collect apexFile structs from them.
2365// 3) some fields in apexBundle struct are configured
2366// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002367func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002368 ////////////////////////////////////////////////////////////////////////////////////////////
2369 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002370 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002371 return
2372 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002373 ////////////////////////////////////////////////////////////////////////////////////////////
2374 // 2) traverse the dependency tree to collect apexFile structs from them.
2375
braleeb0c1f0c2021-06-07 22:49:13 +08002376 // Collect the module directory for IDE info in java/jdeps.go.
2377 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2378
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002379 // TODO(jiyong): do this using WalkPayloadDeps
2380 // TODO(jiyong): make this clean!!!
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002381 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2382 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
2383 vctx.normalizeFileInfo()
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002384 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002385 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002386 return
2387 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002388
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002389 ////////////////////////////////////////////////////////////////////////////////////////////
2390 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002391 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002392 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002393
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002394 a.setApexTypeAndSuffix(ctx)
2395 a.setPayloadFsType(ctx)
2396 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002397 if a.properties.ApexType != zipApex {
2398 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2399 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002400
2401 ////////////////////////////////////////////////////////////////////////////////////////////
2402 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002403 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002404 if a.properties.ApexType == flattenedApex {
2405 a.buildFlattenedApex(ctx)
2406 } else {
2407 a.buildUnflattenedApex(ctx)
2408 }
Jiyong Park956305c2020-01-09 12:32:06 +09002409 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002410 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002411
2412 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2413 if a.installable() {
2414 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2415 // along with other ordinary files. (Note that this is done by apexer for
2416 // non-flattened APEXes)
2417 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2418
2419 // Place the public key as apex_pubkey. This is also done by apexer for
2420 // non-flattened APEXes case.
2421 // TODO(jiyong): Why do we need this CP rule?
2422 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2423 ctx.Build(pctx, android.BuildParams{
2424 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002425 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002426 Output: copiedPubkey,
2427 })
2428 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2429 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002430}
2431
Paul Duffincc33ec82021-04-25 23:14:55 +01002432// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2433// the bootclasspath_fragment contributes to the apex.
2434func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2435 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2436 var filesToAdd []apexFile
2437
2438 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002439 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2440 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2441 dirInApex := filepath.Join("javalib", arch.String())
2442 for _, f := range files {
2443 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2444 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2445 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2446 filesToAdd = append(filesToAdd, af)
2447 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002448 }
2449 }
2450
satayev3db35472021-05-06 23:59:58 +01002451 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002452 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2453 filesToAdd = append(filesToAdd, *af)
2454 }
satayev3db35472021-05-06 23:59:58 +01002455
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002456 if pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex(); pathInApex != "" {
2457 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2458 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2459
2460 if pathOnHost != nil {
2461 // We need to copy the profile to a temporary path with the right filename because the apexer
2462 // will take the filename as is.
2463 ctx.Build(pctx, android.BuildParams{
2464 Rule: android.Cp,
2465 Input: pathOnHost,
2466 Output: tempPath,
2467 })
2468 } else {
2469 // At this point, the boot image profile cannot be generated. It is probably because the boot
2470 // image profile source file does not exist on the branch, or it is not available for the
2471 // current build target.
2472 // However, we cannot enforce the boot image profile to be generated because some build
2473 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2474 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2475 // only if the APEX is being built.
2476 ctx.Build(pctx, android.BuildParams{
2477 Rule: android.ErrorRule,
2478 Output: tempPath,
2479 Args: map[string]string{
2480 "error": "Boot image profile cannot be generated",
2481 },
2482 })
2483 }
2484
2485 androidMkModuleName := filepath.Base(pathInApex)
2486 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2487 filesToAdd = append(filesToAdd, af)
2488 }
2489
Paul Duffincc33ec82021-04-25 23:14:55 +01002490 return filesToAdd
2491}
2492
satayevb98371c2021-06-15 16:49:50 +01002493// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2494// the module contributes to the apex; or nil if the proto config was not generated.
2495func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2496 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2497 if !info.ClasspathFragmentProtoGenerated {
2498 return nil
2499 }
2500 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2501 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2502 return &af
satayev14e49132021-05-17 21:03:07 +01002503}
2504
Paul Duffincc33ec82021-04-25 23:14:55 +01002505// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2506// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002507func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2508 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2509
2510 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2511 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002512 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2513 if err != nil {
2514 ctx.ModuleErrorf("%s", err)
2515 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002516
2517 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2518 // bootclasspath_fragment.
2519 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2520 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002521}
2522
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002523///////////////////////////////////////////////////////////////////////////////////////////////////
2524// Factory functions
2525//
2526
2527func newApexBundle() *apexBundle {
2528 module := &apexBundle{}
2529
2530 module.AddProperties(&module.properties)
2531 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002532 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002533 module.AddProperties(&module.overridableProperties)
2534
2535 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2536 android.InitDefaultableModule(module)
2537 android.InitSdkAwareModule(module)
2538 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002539 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002540 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002541 return module
2542}
2543
Paul Duffineb8051d2021-10-18 17:49:39 +01002544func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002545 bundle := newApexBundle()
2546 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002547 return bundle
2548}
2549
2550// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2551// certain compatibility checks such as apex_available are not done for apex_test.
2552func testApexBundleFactory() android.Module {
2553 bundle := newApexBundle()
2554 bundle.testApex = true
2555 return bundle
2556}
2557
2558// apex packages other modules into an APEX file which is a packaging format for system-level
2559// components like binaries, shared libraries, etc.
2560func BundleFactory() android.Module {
2561 return newApexBundle()
2562}
2563
2564type Defaults struct {
2565 android.ModuleBase
2566 android.DefaultsModuleBase
2567}
2568
2569// apex_defaults provides defaultable properties to other apex modules.
2570func defaultsFactory() android.Module {
2571 return DefaultsFactory()
2572}
2573
2574func DefaultsFactory(props ...interface{}) android.Module {
2575 module := &Defaults{}
2576
2577 module.AddProperties(props...)
2578 module.AddProperties(
2579 &apexBundleProperties{},
2580 &apexTargetBundleProperties{},
2581 &overridableProperties{},
2582 )
2583
2584 android.InitDefaultsModule(module)
2585 return module
2586}
2587
2588type OverrideApex struct {
2589 android.ModuleBase
2590 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002591 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002592}
2593
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002594func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002595 // All the overrides happen in the base module.
2596}
2597
2598// override_apex is used to create an apex module based on another apex module by overriding some of
2599// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002600func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002601 m := &OverrideApex{}
2602
2603 m.AddProperties(&overridableProperties{})
2604
2605 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2606 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002607 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002608 return m
2609}
2610
Wei Li1c66fc72022-05-09 23:59:14 -07002611func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2612 if ctx.ModuleType() != "override_apex" {
2613 return
2614 }
2615
2616 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2617 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2618 if !baseApexExists {
2619 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2620 }
2621
2622 a, baseModuleIsApex := baseModule.(*apexBundle)
2623 if !baseModuleIsApex {
2624 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2625 }
2626 attrs, props := convertWithBp2build(a, ctx)
2627
2628 for _, p := range o.GetProperties() {
2629 overridableProperties, ok := p.(*overridableProperties)
2630 if !ok {
2631 continue
2632 }
Wei Li40f98732022-05-20 22:08:11 -07002633
2634 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2635 // After it is converted in convertWithBp2build(baseApex, ctx),
2636 // the attrs.Manifest.Value.Label is the file path relative to the directory
2637 // of base apex. So the following code converts it to a label that looks like
2638 // <package of base apex>:<path of manifest file> if base apex and override
2639 // apex are not in the same package.
2640 baseApexPackage := ctx.OtherModuleDir(a)
2641 overrideApexPackage := ctx.ModuleDir()
2642 if baseApexPackage != overrideApexPackage {
2643 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2644 }
2645
Wei Li1c66fc72022-05-09 23:59:14 -07002646 // Key
2647 if overridableProperties.Key != nil {
2648 attrs.Key = bazel.LabelAttribute{}
2649 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2650 }
2651
2652 // Certificate
2653 if overridableProperties.Certificate != nil {
2654 attrs.Certificate = bazel.LabelAttribute{}
2655 attrs.Certificate.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Certificate))
2656 }
2657
2658 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002659 if overridableProperties.Prebuilts != nil {
2660 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2661 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2662 }
Wei Li1c66fc72022-05-09 23:59:14 -07002663
2664 // Compressible
2665 if overridableProperties.Compressible != nil {
2666 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2667 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002668
2669 // Package name
2670 //
2671 // e.g. com.android.adbd's package name is com.android.adbd, but
2672 // com.google.android.adbd overrides the package name to com.google.android.adbd
2673 //
2674 // TODO: this can be overridden from the product configuration, see
2675 // getOverrideManifestPackageName and
2676 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2677 //
2678 // Instead of generating the BUILD files differently based on the product config
2679 // at the point of conversion, this should be handled by the BUILD file loading
2680 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2681 if overridableProperties.Package_name != "" {
2682 attrs.Package_name = &overridableProperties.Package_name
2683 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002684
2685 // Logging parent
2686 if overridableProperties.Logging_parent != "" {
2687 attrs.Logging_parent = &overridableProperties.Logging_parent
2688 }
Wei Li1c66fc72022-05-09 23:59:14 -07002689 }
2690
2691 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2692}
2693
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002694///////////////////////////////////////////////////////////////////////////////////////////////////
2695// Vality check routines
2696//
2697// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2698// certain conditions are not met.
2699//
2700// TODO(jiyong): move these checks to a separate go file.
2701
satayevad991492021-12-03 18:58:32 +00002702var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2703
Spandan Dasa5f39a12022-08-05 02:35:52 +00002704// 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 +09002705// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002706func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002707 if a.testApex || a.vndkApex {
2708 return
2709 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002710 // apexBundle::minSdkVersion reports its own errors.
2711 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002712 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002713}
2714
Albert Martineefabcf2022-03-21 20:11:16 +00002715// Returns apex's min_sdk_version string value, honoring overrides
2716func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2717 // Only override the minSdkVersion value on Apexes which already specify
2718 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2719 // min_sdk_version value is lower than the one to override with.
2720 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2721 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2722 originalMinApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2723 isMinSdkSet := a.properties.Min_sdk_version != nil
2724 isOverrideValueHigher := overrideApiLevel.CompareTo(originalMinApiLevel) > 0
2725 if overrideMinSdkValue != "" && isMinSdkSet && isOverrideValueHigher {
2726 return overrideMinSdkValue
2727 }
2728
2729 return proptools.String(a.properties.Min_sdk_version)
2730}
2731
2732// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002733func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2734 return android.SdkSpec{
2735 Kind: android.SdkNone,
2736 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002737 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002738 }
2739}
2740
Albert Martineefabcf2022-03-21 20:11:16 +00002741// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002742func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002743 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2744}
2745
2746// Construct ApiLevel object from min_sdk_version string value
2747func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2748 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002749 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002750 }
Albert Martineefabcf2022-03-21 20:11:16 +00002751 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002752 if err != nil {
2753 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2754 return android.NoneApiLevel
2755 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002756 return apiLevel
2757}
2758
2759// Ensures that a lib providing stub isn't statically linked
2760func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2761 // Practically, we only care about regular APEXes on the device.
2762 if ctx.Host() || a.testApex || a.vndkApex {
2763 return
2764 }
2765
2766 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2767
2768 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2769 if ccm, ok := to.(*cc.Module); ok {
2770 apexName := ctx.ModuleName()
2771 fromName := ctx.OtherModuleName(from)
2772 toName := ctx.OtherModuleName(to)
2773
2774 // If `to` is not actually in the same APEX as `from` then it does not need
2775 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002776 //
2777 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002778 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2779 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2780 return false
2781 }
2782
2783 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2784 // exception to this rule. It can't make the static dependencies dynamic
2785 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002786 // Same rule should be applied to linkerconfig, because it should be executed
2787 // only with static linked libraries before linker is available with ld.config.txt
2788 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002789 return false
2790 }
2791
2792 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2793 if isStubLibraryFromOtherApex && !externalDep {
2794 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2795 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2796 }
2797
2798 }
2799 return true
2800 })
2801}
2802
satayevb98371c2021-06-15 16:49:50 +01002803// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002804func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2805 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002806 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002807 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2808 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002809 if a.UsePlatformApis() {
2810 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2811 }
Daniel Norman69109112021-12-02 12:52:42 -08002812 if a.SocSpecific() || a.DeviceSpecific() {
2813 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2814 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002815 if a.FutureUpdatable() {
2816 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2817 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002818 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002819 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002820 }
2821}
2822
satayevb98371c2021-06-15 16:49:50 +01002823// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2824func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2825 ctx.VisitDirectDeps(func(module android.Module) {
2826 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2827 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2828 if !info.ClasspathFragmentProtoGenerated {
2829 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2830 }
2831 }
2832 })
2833}
2834
2835// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002836func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002837 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2838 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002839 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2840 tag := ctx.OtherModuleDependencyTag(module)
2841 switch tag {
2842 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002843 if m, ok := module.(interface {
2844 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2845 }); ok {
2846 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002847 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2848 }
2849 }
2850 }
2851 })
2852}
2853
satayevb98371c2021-06-15 16:49:50 +01002854// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002855func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2856 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2857 if ctx.Host() || a.testApex || a.vndkApex {
2858 return
2859 }
2860
2861 // Because APEXes targeting other than system/system_ext partitions can't set
2862 // apex_available, we skip checks for these APEXes
2863 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2864 return
2865 }
2866
2867 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2868 // Requiring them and their transitive depencies with apex_available is not right
2869 // because they just add noise.
2870 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2871 return
2872 }
2873
2874 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2875 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2876 if externalDep {
2877 return false
2878 }
2879
2880 apexName := ctx.ModuleName()
2881 fromName := ctx.OtherModuleName(from)
2882 toName := ctx.OtherModuleName(to)
2883
2884 // If `to` is not actually in the same APEX as `from` then it does not need
2885 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002886 //
2887 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002888 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2889 // As soon as the dependency graph crosses the APEX boundary, don't go
2890 // further.
2891 return false
2892 }
2893
2894 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
2895 return true
2896 }
Jiyong Park767dbd92021-03-04 13:03:10 +09002897 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2898 "\n\nDependency path:%s\n\n"+
2899 "Consider adding %q to 'apex_available' property of %q",
2900 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002901 // Visit this module's dependencies to check and report any issues with their availability.
2902 return true
2903 })
2904}
2905
Jiyong Park192600a2021-08-03 07:52:17 +00002906// checkStaticExecutable ensures that executables in an APEX are not static.
2907func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09002908 // No need to run this for host APEXes
2909 if ctx.Host() {
2910 return
2911 }
2912
Jiyong Park192600a2021-08-03 07:52:17 +00002913 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2914 if ctx.OtherModuleDependencyTag(module) != executableTag {
2915 return
2916 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09002917
2918 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00002919 apex := a.ApexVariationName()
2920 exec := ctx.OtherModuleName(module)
2921 if isStaticExecutableAllowed(apex, exec) {
2922 return
2923 }
2924 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
2925 }
2926 })
2927}
2928
2929// A small list of exceptions where static executables are allowed in APEXes.
2930func isStaticExecutableAllowed(apex string, exec string) bool {
2931 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07002932 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00002933 "linker",
2934 "linkerconfig",
2935 },
2936 }
2937 execNames, ok := m[apex]
2938 return ok && android.InList(exec, execNames)
2939}
2940
braleeb0c1f0c2021-06-07 22:49:13 +08002941// Collect information for opening IDE project files in java/jdeps.go.
2942func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09002943 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
2944 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
2945 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08002946 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
2947}
2948
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002949var (
2950 apexAvailBaseline = makeApexAvailableBaseline()
2951 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
2952)
2953
Colin Cross440e0d02020-06-11 11:32:11 -07002954func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002955 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002956 moduleName = normalizeModuleName(moduleName)
2957
Colin Cross440e0d02020-06-11 11:32:11 -07002958 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002959 return true
2960 }
2961
2962 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07002963 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002964 return true
2965 }
2966
2967 return false
2968}
2969
2970func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09002971 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
2972 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00002973 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09002974 if strings.HasPrefix(moduleName, "libclang_rt.") {
2975 // This module has many arch variants that depend on the product being built.
2976 // We don't want to list them all
2977 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002978 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09002979 if strings.HasPrefix(moduleName, "androidx.") {
2980 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
2981 moduleName = "androidx"
2982 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002983 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002984}
2985
Jiyong Park8e6d52f2020-11-19 14:37:47 +09002986// Transform the map of apex -> modules to module -> apexes.
2987func invertApexBaseline(m map[string][]string) map[string][]string {
2988 r := make(map[string][]string)
2989 for apex, modules := range m {
2990 for _, module := range modules {
2991 r[module] = append(r[module], apex)
2992 }
2993 }
2994 return r
2995}
2996
2997// Retrieve the baseline of apexes to which the supplied module belongs.
2998func BaselineApexAvailable(moduleName string) []string {
2999 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3000}
3001
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003002// This is a map from apex to modules, which overrides the apex_available setting for that
3003// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003004// TODO(b/147364041): remove this
3005func makeApexAvailableBaseline() map[string][]string {
3006 // The "Module separator"s below are employed to minimize merge conflicts.
3007 m := make(map[string][]string)
3008 //
3009 // Module separator
3010 //
3011 m["com.android.appsearch"] = []string{
3012 "icing-java-proto-lite",
3013 "libprotobuf-java-lite",
3014 }
3015 //
3016 // Module separator
3017 //
Etienne Ruffieux16512672021-12-15 15:49:04 +00003018 m["com.android.bluetooth"] = []string{
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003019 "android.hardware.audio.common@5.0",
3020 "android.hardware.bluetooth.a2dp@1.0",
3021 "android.hardware.bluetooth.audio@2.0",
3022 "android.hardware.bluetooth@1.0",
3023 "android.hardware.bluetooth@1.1",
3024 "android.hardware.graphics.bufferqueue@1.0",
3025 "android.hardware.graphics.bufferqueue@2.0",
3026 "android.hardware.graphics.common@1.0",
3027 "android.hardware.graphics.common@1.1",
3028 "android.hardware.graphics.common@1.2",
3029 "android.hardware.media@1.0",
3030 "android.hidl.safe_union@1.0",
3031 "android.hidl.token@1.0",
3032 "android.hidl.token@1.0-utils",
3033 "avrcp-target-service",
3034 "avrcp_headers",
3035 "bluetooth-protos-lite",
3036 "bluetooth.mapsapi",
3037 "com.android.vcard",
3038 "dnsresolver_aidl_interface-V2-java",
3039 "ipmemorystore-aidl-interfaces-V5-java",
3040 "ipmemorystore-aidl-interfaces-java",
3041 "internal_include_headers",
3042 "lib-bt-packets",
3043 "lib-bt-packets-avrcp",
3044 "lib-bt-packets-base",
3045 "libFraunhoferAAC",
3046 "libaudio-a2dp-hw-utils",
3047 "libaudio-hearing-aid-hw-utils",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003048 "libbluetooth",
3049 "libbluetooth-types",
3050 "libbluetooth-types-header",
3051 "libbluetooth_gd",
3052 "libbluetooth_headers",
3053 "libbluetooth_jni",
3054 "libbt-audio-hal-interface",
3055 "libbt-bta",
3056 "libbt-common",
3057 "libbt-hci",
3058 "libbt-platform-protos-lite",
3059 "libbt-protos-lite",
3060 "libbt-sbc-decoder",
3061 "libbt-sbc-encoder",
3062 "libbt-stack",
3063 "libbt-utils",
3064 "libbtcore",
3065 "libbtdevice",
3066 "libbte",
3067 "libbtif",
3068 "libchrome",
3069 "libevent",
3070 "libfmq",
3071 "libg722codec",
3072 "libgui_headers",
3073 "libmedia_headers",
3074 "libmodpb64",
3075 "libosi",
3076 "libstagefright_foundation_headers",
3077 "libstagefright_headers",
3078 "libstatslog",
3079 "libstatssocket",
3080 "libtinyxml2",
3081 "libudrv-uipc",
3082 "libz",
3083 "media_plugin_headers",
3084 "net-utils-services-common",
3085 "netd_aidl_interface-unstable-java",
3086 "netd_event_listener_interface-java",
3087 "netlink-client",
3088 "networkstack-client",
3089 "sap-api-java-static",
3090 "services.net",
3091 }
3092 //
3093 // Module separator
3094 //
3095 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3096 //
3097 // Module separator
3098 //
3099 m["com.android.extservices"] = []string{
3100 "error_prone_annotations",
3101 "ExtServices-core",
3102 "ExtServices",
3103 "libtextclassifier-java",
3104 "libz_current",
3105 "textclassifier-statsd",
3106 "TextClassifierNotificationLibNoManifest",
3107 "TextClassifierServiceLibNoManifest",
3108 }
3109 //
3110 // Module separator
3111 //
3112 m["com.android.neuralnetworks"] = []string{
3113 "android.hardware.neuralnetworks@1.0",
3114 "android.hardware.neuralnetworks@1.1",
3115 "android.hardware.neuralnetworks@1.2",
3116 "android.hardware.neuralnetworks@1.3",
3117 "android.hidl.allocator@1.0",
3118 "android.hidl.memory.token@1.0",
3119 "android.hidl.memory@1.0",
3120 "android.hidl.safe_union@1.0",
3121 "libarect",
3122 "libbuildversion",
3123 "libmath",
3124 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003125 }
3126 //
3127 // Module separator
3128 //
3129 m["com.android.media"] = []string{
3130 "android.frameworks.bufferhub@1.0",
3131 "android.hardware.cas.native@1.0",
3132 "android.hardware.cas@1.0",
3133 "android.hardware.configstore-utils",
3134 "android.hardware.configstore@1.0",
3135 "android.hardware.configstore@1.1",
3136 "android.hardware.graphics.allocator@2.0",
3137 "android.hardware.graphics.allocator@3.0",
3138 "android.hardware.graphics.bufferqueue@1.0",
3139 "android.hardware.graphics.bufferqueue@2.0",
3140 "android.hardware.graphics.common@1.0",
3141 "android.hardware.graphics.common@1.1",
3142 "android.hardware.graphics.common@1.2",
3143 "android.hardware.graphics.mapper@2.0",
3144 "android.hardware.graphics.mapper@2.1",
3145 "android.hardware.graphics.mapper@3.0",
3146 "android.hardware.media.omx@1.0",
3147 "android.hardware.media@1.0",
3148 "android.hidl.allocator@1.0",
3149 "android.hidl.memory.token@1.0",
3150 "android.hidl.memory@1.0",
3151 "android.hidl.token@1.0",
3152 "android.hidl.token@1.0-utils",
3153 "bionic_libc_platform_headers",
3154 "exoplayer2-extractor",
3155 "exoplayer2-extractor-annotation-stubs",
3156 "gl_headers",
3157 "jsr305",
3158 "libEGL",
3159 "libEGL_blobCache",
3160 "libEGL_getProcAddress",
3161 "libFLAC",
3162 "libFLAC-config",
3163 "libFLAC-headers",
3164 "libGLESv2",
3165 "libaacextractor",
3166 "libamrextractor",
3167 "libarect",
3168 "libaudio_system_headers",
3169 "libaudioclient",
3170 "libaudioclient_headers",
3171 "libaudiofoundation",
3172 "libaudiofoundation_headers",
3173 "libaudiomanager",
3174 "libaudiopolicy",
3175 "libaudioutils",
3176 "libaudioutils_fixedfft",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003177 "libbluetooth-types-header",
3178 "libbufferhub",
3179 "libbufferhub_headers",
3180 "libbufferhubqueue",
3181 "libc_malloc_debug_backtrace",
3182 "libcamera_client",
3183 "libcamera_metadata",
3184 "libdvr_headers",
3185 "libexpat",
3186 "libfifo",
3187 "libflacextractor",
3188 "libgrallocusage",
3189 "libgraphicsenv",
3190 "libgui",
3191 "libgui_headers",
3192 "libhardware_headers",
3193 "libinput",
3194 "liblzma",
3195 "libmath",
3196 "libmedia",
3197 "libmedia_codeclist",
3198 "libmedia_headers",
3199 "libmedia_helper",
3200 "libmedia_helper_headers",
3201 "libmedia_midiiowrapper",
3202 "libmedia_omx",
3203 "libmediautils",
3204 "libmidiextractor",
3205 "libmkvextractor",
3206 "libmp3extractor",
3207 "libmp4extractor",
3208 "libmpeg2extractor",
3209 "libnativebase_headers",
3210 "libnativewindow_headers",
3211 "libnblog",
3212 "liboggextractor",
3213 "libpackagelistparser",
3214 "libpdx",
3215 "libpdx_default_transport",
3216 "libpdx_headers",
3217 "libpdx_uds",
3218 "libprocinfo",
3219 "libspeexresampler",
3220 "libspeexresampler",
3221 "libstagefright_esds",
3222 "libstagefright_flacdec",
3223 "libstagefright_flacdec",
3224 "libstagefright_foundation",
3225 "libstagefright_foundation_headers",
3226 "libstagefright_foundation_without_imemory",
3227 "libstagefright_headers",
3228 "libstagefright_id3",
3229 "libstagefright_metadatautils",
3230 "libstagefright_mpeg2extractor",
3231 "libstagefright_mpeg2support",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003232 "libui",
3233 "libui_headers",
3234 "libunwindstack",
3235 "libvibrator",
3236 "libvorbisidec",
3237 "libwavextractor",
3238 "libwebm",
3239 "media_ndk_headers",
3240 "media_plugin_headers",
3241 "updatable-media",
3242 }
3243 //
3244 // Module separator
3245 //
3246 m["com.android.media.swcodec"] = []string{
3247 "android.frameworks.bufferhub@1.0",
3248 "android.hardware.common-ndk_platform",
3249 "android.hardware.configstore-utils",
3250 "android.hardware.configstore@1.0",
3251 "android.hardware.configstore@1.1",
3252 "android.hardware.graphics.allocator@2.0",
3253 "android.hardware.graphics.allocator@3.0",
3254 "android.hardware.graphics.allocator@4.0",
3255 "android.hardware.graphics.bufferqueue@1.0",
3256 "android.hardware.graphics.bufferqueue@2.0",
3257 "android.hardware.graphics.common-ndk_platform",
3258 "android.hardware.graphics.common@1.0",
3259 "android.hardware.graphics.common@1.1",
3260 "android.hardware.graphics.common@1.2",
3261 "android.hardware.graphics.mapper@2.0",
3262 "android.hardware.graphics.mapper@2.1",
3263 "android.hardware.graphics.mapper@3.0",
3264 "android.hardware.graphics.mapper@4.0",
3265 "android.hardware.media.bufferpool@2.0",
3266 "android.hardware.media.c2@1.0",
3267 "android.hardware.media.c2@1.1",
3268 "android.hardware.media.omx@1.0",
3269 "android.hardware.media@1.0",
3270 "android.hardware.media@1.0",
3271 "android.hidl.memory.token@1.0",
3272 "android.hidl.memory@1.0",
3273 "android.hidl.safe_union@1.0",
3274 "android.hidl.token@1.0",
3275 "android.hidl.token@1.0-utils",
3276 "libEGL",
3277 "libFLAC",
3278 "libFLAC-config",
3279 "libFLAC-headers",
3280 "libFraunhoferAAC",
3281 "libLibGuiProperties",
3282 "libarect",
3283 "libaudio_system_headers",
3284 "libaudioutils",
3285 "libaudioutils",
3286 "libaudioutils_fixedfft",
3287 "libavcdec",
3288 "libavcenc",
3289 "libavservices_minijail",
3290 "libavservices_minijail",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003291 "libbinderthreadstateutils",
3292 "libbluetooth-types-header",
3293 "libbufferhub_headers",
3294 "libcodec2",
3295 "libcodec2_headers",
3296 "libcodec2_hidl@1.0",
3297 "libcodec2_hidl@1.1",
3298 "libcodec2_internal",
3299 "libcodec2_soft_aacdec",
3300 "libcodec2_soft_aacenc",
3301 "libcodec2_soft_amrnbdec",
3302 "libcodec2_soft_amrnbenc",
3303 "libcodec2_soft_amrwbdec",
3304 "libcodec2_soft_amrwbenc",
3305 "libcodec2_soft_av1dec_gav1",
3306 "libcodec2_soft_avcdec",
3307 "libcodec2_soft_avcenc",
3308 "libcodec2_soft_common",
3309 "libcodec2_soft_flacdec",
3310 "libcodec2_soft_flacenc",
3311 "libcodec2_soft_g711alawdec",
3312 "libcodec2_soft_g711mlawdec",
3313 "libcodec2_soft_gsmdec",
3314 "libcodec2_soft_h263dec",
3315 "libcodec2_soft_h263enc",
3316 "libcodec2_soft_hevcdec",
3317 "libcodec2_soft_hevcenc",
3318 "libcodec2_soft_mp3dec",
3319 "libcodec2_soft_mpeg2dec",
3320 "libcodec2_soft_mpeg4dec",
3321 "libcodec2_soft_mpeg4enc",
3322 "libcodec2_soft_opusdec",
3323 "libcodec2_soft_opusenc",
3324 "libcodec2_soft_rawdec",
3325 "libcodec2_soft_vorbisdec",
3326 "libcodec2_soft_vp8dec",
3327 "libcodec2_soft_vp8enc",
3328 "libcodec2_soft_vp9dec",
3329 "libcodec2_soft_vp9enc",
3330 "libcodec2_vndk",
3331 "libdvr_headers",
3332 "libfmq",
3333 "libfmq",
3334 "libgav1",
3335 "libgralloctypes",
3336 "libgrallocusage",
3337 "libgraphicsenv",
3338 "libgsm",
3339 "libgui_bufferqueue_static",
3340 "libgui_headers",
3341 "libhardware",
3342 "libhardware_headers",
3343 "libhevcdec",
3344 "libhevcenc",
3345 "libion",
3346 "libjpeg",
3347 "liblzma",
3348 "libmath",
3349 "libmedia_codecserviceregistrant",
3350 "libmedia_headers",
3351 "libmpeg2dec",
3352 "libnativebase_headers",
3353 "libnativewindow_headers",
3354 "libpdx_headers",
3355 "libscudo_wrapper",
3356 "libsfplugin_ccodec_utils",
3357 "libspeexresampler",
3358 "libstagefright_amrnb_common",
3359 "libstagefright_amrnbdec",
3360 "libstagefright_amrnbenc",
3361 "libstagefright_amrwbdec",
3362 "libstagefright_amrwbenc",
3363 "libstagefright_bufferpool@2.0.1",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003364 "libstagefright_enc_common",
3365 "libstagefright_flacdec",
3366 "libstagefright_foundation",
3367 "libstagefright_foundation_headers",
3368 "libstagefright_headers",
3369 "libstagefright_m4vh263dec",
3370 "libstagefright_m4vh263enc",
3371 "libstagefright_mp3dec",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003372 "libui",
3373 "libui_headers",
3374 "libunwindstack",
3375 "libvorbisidec",
3376 "libvpx",
3377 "libyuv",
3378 "libyuv_static",
3379 "media_ndk_headers",
3380 "media_plugin_headers",
3381 "mediaswcodec",
3382 }
3383 //
3384 // Module separator
3385 //
3386 m["com.android.mediaprovider"] = []string{
3387 "MediaProvider",
3388 "MediaProviderGoogle",
3389 "fmtlib_ndk",
3390 "libbase_ndk",
3391 "libfuse",
3392 "libfuse_jni",
3393 }
3394 //
3395 // Module separator
3396 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003397 m["com.android.runtime"] = []string{
3398 "bionic_libc_platform_headers",
3399 "libarm-optimized-routines-math",
3400 "libc_aeabi",
3401 "libc_bionic",
3402 "libc_bionic_ndk",
3403 "libc_bootstrap",
3404 "libc_common",
3405 "libc_common_shared",
3406 "libc_common_static",
3407 "libc_dns",
3408 "libc_dynamic_dispatch",
3409 "libc_fortify",
3410 "libc_freebsd",
3411 "libc_freebsd_large_stack",
3412 "libc_gdtoa",
3413 "libc_init_dynamic",
3414 "libc_init_static",
3415 "libc_jemalloc_wrapper",
3416 "libc_netbsd",
3417 "libc_nomalloc",
3418 "libc_nopthread",
3419 "libc_openbsd",
3420 "libc_openbsd_large_stack",
3421 "libc_openbsd_ndk",
3422 "libc_pthread",
3423 "libc_static_dispatch",
3424 "libc_syscalls",
3425 "libc_tzcode",
3426 "libc_unwind_static",
3427 "libdebuggerd",
3428 "libdebuggerd_common_headers",
3429 "libdebuggerd_handler_core",
3430 "libdebuggerd_handler_fallback",
3431 "libdl_static",
3432 "libjemalloc5",
3433 "liblinker_main",
3434 "liblinker_malloc",
3435 "liblz4",
3436 "liblzma",
3437 "libprocinfo",
3438 "libpropertyinfoparser",
3439 "libscudo",
3440 "libstdc++",
3441 "libsystemproperties",
3442 "libtombstoned_client_static",
3443 "libunwindstack",
3444 "libz",
3445 "libziparchive",
3446 }
3447 //
3448 // Module separator
3449 //
3450 m["com.android.tethering"] = []string{
3451 "android.hardware.tetheroffload.config-V1.0-java",
3452 "android.hardware.tetheroffload.control-V1.0-java",
3453 "android.hidl.base-V1.0-java",
3454 "libcgrouprc",
3455 "libcgrouprc_format",
3456 "libtetherutilsjni",
3457 "libvndksupport",
3458 "net-utils-framework-common",
3459 "netd_aidl_interface-V3-java",
3460 "netlink-client",
3461 "networkstack-aidl-interfaces-java",
3462 "tethering-aidl-interfaces-java",
3463 "TetheringApiCurrentLib",
3464 }
3465 //
3466 // Module separator
3467 //
3468 m["com.android.wifi"] = []string{
3469 "PlatformProperties",
3470 "android.hardware.wifi-V1.0-java",
3471 "android.hardware.wifi-V1.0-java-constants",
3472 "android.hardware.wifi-V1.1-java",
3473 "android.hardware.wifi-V1.2-java",
3474 "android.hardware.wifi-V1.3-java",
3475 "android.hardware.wifi-V1.4-java",
3476 "android.hardware.wifi.hostapd-V1.0-java",
3477 "android.hardware.wifi.hostapd-V1.1-java",
3478 "android.hardware.wifi.hostapd-V1.2-java",
3479 "android.hardware.wifi.supplicant-V1.0-java",
3480 "android.hardware.wifi.supplicant-V1.1-java",
3481 "android.hardware.wifi.supplicant-V1.2-java",
3482 "android.hardware.wifi.supplicant-V1.3-java",
3483 "android.hidl.base-V1.0-java",
3484 "android.hidl.manager-V1.0-java",
3485 "android.hidl.manager-V1.1-java",
3486 "android.hidl.manager-V1.2-java",
3487 "bouncycastle-unbundled",
3488 "dnsresolver_aidl_interface-V2-java",
3489 "error_prone_annotations",
3490 "framework-wifi-pre-jarjar",
3491 "framework-wifi-util-lib",
3492 "ipmemorystore-aidl-interfaces-V3-java",
3493 "ipmemorystore-aidl-interfaces-java",
3494 "ksoap2",
3495 "libnanohttpd",
3496 "libwifi-jni",
3497 "net-utils-services-common",
3498 "netd_aidl_interface-V2-java",
3499 "netd_aidl_interface-unstable-java",
3500 "netd_event_listener_interface-java",
3501 "netlink-client",
3502 "networkstack-client",
3503 "services.net",
3504 "wifi-lite-protos",
3505 "wifi-nano-protos",
3506 "wifi-service-pre-jarjar",
3507 "wifi-service-resources",
3508 }
3509 //
3510 // Module separator
3511 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003512 m["com.android.os.statsd"] = []string{
3513 "libstatssocket",
3514 }
3515 //
3516 // Module separator
3517 //
3518 m[android.AvailableToAnyApex] = []string{
3519 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3520 "androidx",
3521 "androidx-constraintlayout_constraintlayout",
3522 "androidx-constraintlayout_constraintlayout-nodeps",
3523 "androidx-constraintlayout_constraintlayout-solver",
3524 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3525 "com.google.android.material_material",
3526 "com.google.android.material_material-nodeps",
3527
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003528 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003529 "libprofile-clang-extras",
3530 "libprofile-clang-extras_ndk",
3531 "libprofile-extras",
3532 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003533 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003534 }
3535 return m
3536}
3537
3538func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003539 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3540 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003541}
3542
Spandan Dasf14e2542021-11-12 00:01:37 +00003543func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3544 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3545 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003546 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003547 With("name", jar).
3548 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3549 Because(jar +
3550 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003551 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003552 " 1. If the offending code is from a statically linked library, consider " +
3553 "removing that dependency and using an alternative already in the " +
3554 "bootclasspath, or perhaps a shared library." +
3555 " 2. Move the offending code into an allowed package.\n" +
3556 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3557 "health implications of bundling that code, particularly if the offending jar " +
3558 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003559
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003560 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003561 }
3562 return rules
3563}
3564
Anton Hanssone1b18362021-12-23 15:05:38 +00003565// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003566// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003567func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003568 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003569 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003570 "android.net.ssl",
3571 "com.android.org.conscrypt",
3572 },
Wei Li40f98732022-05-20 22:08:11 -07003573 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003574 "android.media",
3575 },
3576 }
3577}
3578
Anton Hanssone1b18362021-12-23 15:05:38 +00003579// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003580// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003581func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003582 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003583 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003584 "android.provider",
3585 },
Wei Li40f98732022-05-20 22:08:11 -07003586 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003587 "android.permission",
3588 "android.app.role",
3589 "com.android.permission",
3590 "com.android.role",
3591 },
Wei Li40f98732022-05-20 22:08:11 -07003592 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003593 "android.os.ext",
3594 },
Wei Li40f98732022-05-20 22:08:11 -07003595 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003596 "android.app",
3597 "android.os",
3598 "android.util",
3599 "com.android.internal.statsd",
3600 "com.android.server.stats",
3601 },
Wei Li40f98732022-05-20 22:08:11 -07003602 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003603 "com.android.server.wifi",
3604 "com.android.wifi.x",
3605 "android.hardware.wifi",
3606 "android.net.wifi",
3607 },
Wei Li40f98732022-05-20 22:08:11 -07003608 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003609 "android.net",
3610 },
3611 }
3612}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003613
3614// For Bazel / bp2build
3615
3616type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003617 Manifest bazel.LabelAttribute
3618 Android_manifest bazel.LabelAttribute
3619 File_contexts bazel.LabelAttribute
3620 Key bazel.LabelAttribute
3621 Certificate bazel.LabelAttribute
3622 Min_sdk_version *string
3623 Updatable bazel.BoolAttribute
3624 Installable bazel.BoolAttribute
3625 Binaries bazel.LabelListAttribute
3626 Prebuilts bazel.LabelListAttribute
3627 Native_shared_libs_32 bazel.LabelListAttribute
3628 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003629 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003630 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003631 Logging_parent *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003632}
3633
3634type convertedNativeSharedLibs struct {
3635 Native_shared_libs_32 bazel.LabelListAttribute
3636 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003637}
3638
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003639// ConvertWithBp2build performs bp2build conversion of an apex
3640func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
3641 // We do not convert apex_test modules at this time
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003642 if ctx.ModuleType() != "apex" {
3643 return
3644 }
3645
Wei Li1c66fc72022-05-09 23:59:14 -07003646 attrs, props := convertWithBp2build(a, ctx)
3647 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, &attrs)
3648}
3649
3650func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003651 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003652 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003653
3654 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003655 if a.properties.AndroidManifest != nil {
3656 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003657 }
3658
3659 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003660 if a.properties.File_contexts == nil {
3661 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3662 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3663 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3664 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003665 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003666 } else {
3667 // File_contexts is a file
3668 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003669 }
3670
Albert Martineefabcf2022-03-21 20:11:16 +00003671 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3672 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003673 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003674 if a.properties.Min_sdk_version != nil {
3675 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003676 }
3677
3678 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003679 if a.overridableProperties.Key != nil {
3680 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003681 }
3682
3683 var certificateLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003684 if a.overridableProperties.Certificate != nil {
3685 certificateLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Certificate))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003686 }
3687
Yu Liu4ae55d12022-01-05 17:17:23 -08003688 nativeSharedLibs := &convertedNativeSharedLibs{
3689 Native_shared_libs_32: bazel.LabelListAttribute{},
3690 Native_shared_libs_64: bazel.LabelListAttribute{},
3691 }
3692 compileMultilib := "both"
3693 if a.CompileMultilib() != nil {
3694 compileMultilib = *a.CompileMultilib()
3695 }
3696
3697 // properties.Native_shared_libs is treated as "both"
3698 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3699 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3700 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3701 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3702 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003703
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003704 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003705 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3706 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3707
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003708 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003709 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003710
3711 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003712 if a.properties.Updatable != nil {
3713 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003714 }
3715
3716 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003717 if a.properties.Installable != nil {
3718 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003719 }
3720
Wei Lif034cb42022-01-19 15:54:31 -08003721 var compressibleAttribute bazel.BoolAttribute
3722 if a.overridableProperties.Compressible != nil {
3723 compressibleAttribute.Value = a.overridableProperties.Compressible
3724 }
3725
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003726 var packageName *string
3727 if a.overridableProperties.Package_name != "" {
3728 packageName = &a.overridableProperties.Package_name
3729 }
3730
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003731 var loggingParent *string
3732 if a.overridableProperties.Logging_parent != "" {
3733 loggingParent = &a.overridableProperties.Logging_parent
3734 }
3735
Wei Li1c66fc72022-05-09 23:59:14 -07003736 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003737 Manifest: manifestLabelAttribute,
3738 Android_manifest: androidManifestLabelAttribute,
3739 File_contexts: fileContextsLabelAttribute,
3740 Min_sdk_version: minSdkVersion,
3741 Key: keyLabelAttribute,
3742 Certificate: certificateLabelAttribute,
3743 Updatable: updatableAttribute,
3744 Installable: installableAttribute,
3745 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3746 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3747 Binaries: binariesLabelListAttribute,
3748 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003749 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003750 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003751 Logging_parent: loggingParent,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003752 }
3753
3754 props := bazel.BazelTargetModuleProperties{
3755 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003756 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003757 }
3758
Wei Li1c66fc72022-05-09 23:59:14 -07003759 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003760}
Yu Liu4ae55d12022-01-05 17:17:23 -08003761
3762// The following conversions are based on this table where the rows are the compile_multilib
3763// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3764// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3765// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3766// should not be compiled.
3767// multib/compile_multilib, 32, 64, both, first
3768// 32, 32/32, none/none, 32/32, none/32
3769// 64, none/none, 64/none, 64/none, 64/none
3770// both, 32/32, 64/none, 32&64/32, 64/32
3771// first, 32/32, 64/none, 64/32, 64/32
3772
3773func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3774 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3775 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3776 switch compileMultilb {
3777 case "both", "32":
3778 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3779 case "first":
3780 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3781 case "64":
3782 // Incompatible, ignore
3783 default:
3784 invalidCompileMultilib(ctx, compileMultilb)
3785 }
3786}
3787
3788func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3789 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3790 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3791 switch compileMultilb {
3792 case "both", "64", "first":
3793 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3794 case "32":
3795 // Incompatible, ignore
3796 default:
3797 invalidCompileMultilib(ctx, compileMultilb)
3798 }
3799}
3800
3801func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3802 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3803 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3804 switch compileMultilb {
3805 case "both":
3806 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3807 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3808 case "first":
3809 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3810 case "32":
3811 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3812 case "64":
3813 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3814 default:
3815 invalidCompileMultilib(ctx, compileMultilb)
3816 }
3817}
3818
3819func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3820 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3821 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3822 switch compileMultilb {
3823 case "both", "first":
3824 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3825 case "32":
3826 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3827 case "64":
3828 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3829 default:
3830 invalidCompileMultilib(ctx, compileMultilb)
3831 }
3832}
3833
3834func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3835 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3836 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3837}
3838
3839func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3840 list := bazel.LabelListAttribute{}
3841 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3842 nativeSharedLibs.Native_shared_libs_32.Append(list)
3843}
3844
3845func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3846 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3847 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3848}
3849
3850func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3851 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3852 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3853}
3854
3855func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3856 labelListAttr *bazel.LabelListAttribute) {
3857 list := bazel.LabelListAttribute{}
3858 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3859 labelListAttr.Append(list)
3860}
3861
3862func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3863 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3864}