blob: 4394a30f95c6c131b618abc753882339c00e1efe [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 Smundak6a2b7c42022-05-19 21:28:53 -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 Smundak6a2b7c42022-05-19 21:28:53 -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 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+a.installSuffix(), a.outputFile,
1861 a.compatSymlinks.Paths()...)
1862 default:
1863 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1864 }
1865
1866 /*
1867 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1868 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1869 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1870 To find out what Soong build puts there, run:
1871 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1872 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1873 return a.depVisitor(&vctx, ctx, child, parent)
1874 })
1875 vctx.normalizeFileInfo()
1876 */
1877
1878}
1879
1880func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1881 a.isCompressed = (a.properties.ApexType == imageApex) &&
1882 ((ctx.Config().CompressedApex() &&
1883 proptools.BoolDefault(a.overridableProperties.Compressible, false) &&
1884 !a.testApex && !ctx.Config().UnbundledBuildApps()) ||
1885 a.testOnlyShouldForceCompression())
1886}
1887
1888func (a apexBundle) installSuffix() string {
1889 if a.isCompressed {
1890 return imageCapexSuffix
1891 }
1892 return imageApexSuffix
1893}
1894
1895func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1896 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1897 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1898 // the same library in the system partition, thus effectively sharing the same libraries
1899 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1900 // in the APEX.
1901 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1902
1903 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1904 // So we can't link them to /system/lib libs which are core variants.
1905 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1906 a.linkToSystemLib = false
1907 }
1908
1909 forced := ctx.Config().ForceApexSymlinkOptimization()
1910 updatable := a.Updatable() || a.FutureUpdatable()
1911
1912 // We don't need the optimization for updatable APEXes, as it might give false signal
1913 // to the system health when the APEXes are still bundled (b/149805758).
1914 if !forced && updatable && a.properties.ApexType == imageApex {
1915 a.linkToSystemLib = false
1916 }
1917
1918 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1919 if ctx.Host() {
1920 a.linkToSystemLib = false
1921 }
1922}
1923
1924func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1925 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
1926 case ext4FsType:
1927 a.payloadFsType = ext4
1928 case f2fsFsType:
1929 a.payloadFsType = f2fs
1930 case erofsFsType:
1931 a.payloadFsType = erofs
1932 default:
1933 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
1934 }
1935}
1936
1937func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
1938 // Set suffix and primaryApexType depending on the ApexType
1939 buildFlattenedAsDefault := ctx.Config().FlattenApex()
1940 switch a.properties.ApexType {
1941 case imageApex:
1942 if buildFlattenedAsDefault {
1943 a.suffix = imageApexSuffix
1944 } else {
1945 a.suffix = ""
1946 a.primaryApexType = true
1947
1948 if ctx.Config().InstallExtraFlattenedApexes() {
1949 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
1950 }
1951 }
1952 case zipApex:
1953 if proptools.String(a.properties.Payload_type) == "zip" {
1954 a.suffix = ""
1955 a.primaryApexType = true
1956 } else {
1957 a.suffix = zipApexSuffix
1958 }
1959 case flattenedApex:
1960 if buildFlattenedAsDefault {
1961 a.suffix = ""
1962 a.primaryApexType = true
1963 } else {
1964 a.suffix = flattenedSuffix
1965 }
1966 }
1967}
1968
1969func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
1970 a.checkApexAvailability(ctx)
1971 a.checkUpdatable(ctx)
1972 a.CheckMinSdkVersion(ctx)
1973 a.checkStaticLinkingToStubLibraries(ctx)
1974 a.checkStaticExecutables(ctx)
1975 if len(a.properties.Tests) > 0 && !a.testApex {
1976 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
1977 return false
1978 }
1979 return true
1980}
1981
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001982type visitorContext struct {
1983 // all the files that will be included in this APEX
1984 filesInfo []apexFile
1985
1986 // native lib dependencies
1987 provideNativeLibs []string
1988 requireNativeLibs []string
1989
1990 handleSpecialLibs bool
1991}
1992
1993func (vctx *visitorContext) normalizeFileInfo() {
1994 encountered := make(map[string]apexFile)
1995 for _, f := range vctx.filesInfo {
1996 dest := filepath.Join(f.installDir, f.builtFile.Base())
1997 if e, ok := encountered[dest]; !ok {
1998 encountered[dest] = f
1999 } else {
2000 // If a module is directly included and also transitively depended on
2001 // consider it as directly included.
2002 e.transitiveDep = e.transitiveDep && f.transitiveDep
2003 encountered[dest] = e
2004 }
2005 }
2006 vctx.filesInfo = vctx.filesInfo[:0]
2007 for _, v := range encountered {
2008 vctx.filesInfo = append(vctx.filesInfo, v)
2009 }
2010 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2011 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2012 // changes.
2013 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2014 })
2015}
2016
2017func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2018 depTag := ctx.OtherModuleDependencyTag(child)
2019 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2020 return false
2021 }
2022 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2023 return false
2024 }
2025 depName := ctx.OtherModuleName(child)
2026 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2027 switch depTag {
2028 case sharedLibTag, jniLibTag:
2029 isJniLib := depTag == jniLibTag
2030 switch ch := child.(type) {
2031 case *cc.Module:
2032 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2033 fi.isJniLib = isJniLib
2034 vctx.filesInfo = append(vctx.filesInfo, fi)
2035 // Collect the list of stub-providing libs except:
2036 // - VNDK libs are only for vendors
2037 // - bootstrap bionic libs are treated as provided by system
2038 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2039 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2040 }
2041 return true // track transitive dependencies
2042 case *rust.Module:
2043 fi := apexFileForRustLibrary(ctx, ch)
2044 fi.isJniLib = isJniLib
2045 vctx.filesInfo = append(vctx.filesInfo, fi)
2046 return true // track transitive dependencies
2047 default:
2048 propertyName := "native_shared_libs"
2049 if isJniLib {
2050 propertyName = "jni_libs"
2051 }
2052 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2053 }
2054 case executableTag:
2055 switch ch := child.(type) {
2056 case *cc.Module:
2057 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2058 return true // track transitive dependencies
2059 case *python.Module:
2060 if ch.HostToolPath().Valid() {
2061 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2062 }
2063 case bootstrap.GoBinaryTool:
2064 if a.Host() {
2065 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2066 }
2067 case *rust.Module:
2068 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2069 return true // track transitive dependencies
2070 default:
2071 ctx.PropertyErrorf("binaries",
2072 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2073 }
2074 case shBinaryTag:
2075 if csh, ok := child.(*sh.ShBinary); ok {
2076 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2077 } else {
2078 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2079 }
2080 case bcpfTag:
2081 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2082 if !ok {
2083 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2084 return false
2085 }
2086
2087 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2088 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2089 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2090 }
2091 return true
2092 case sscpfTag:
2093 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2094 ctx.PropertyErrorf("systemserverclasspath_fragments",
2095 "%q is not a systemserverclasspath_fragment module", depName)
2096 return false
2097 }
2098 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2099 vctx.filesInfo = append(vctx.filesInfo, *af)
2100 }
2101 return true
2102 case javaLibTag:
2103 switch child.(type) {
2104 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2105 af := apexFileForJavaModule(ctx, child.(javaModule))
2106 if !af.ok() {
2107 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2108 return false
2109 }
2110 vctx.filesInfo = append(vctx.filesInfo, af)
2111 return true // track transitive dependencies
2112 default:
2113 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2114 }
2115 case androidAppTag:
2116 switch ap := child.(type) {
2117 case *java.AndroidApp:
2118 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2119 return true // track transitive dependencies
2120 case *java.AndroidAppImport:
2121 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2122 case *java.AndroidTestHelperApp:
2123 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2124 case *java.AndroidAppSet:
2125 appDir := "app"
2126 if ap.Privileged() {
2127 appDir = "priv-app"
2128 }
2129 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2130 // suffixed so that PackageManager correctly invalidates the
2131 // existing installed apk in favour of the new APK-in-APEX.
2132 // See bugs for more information.
2133 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2134 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2135 af.certificate = java.PresignedCertificate
2136 vctx.filesInfo = append(vctx.filesInfo, af)
2137 default:
2138 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2139 }
2140 case rroTag:
2141 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2142 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2143 } else {
2144 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2145 }
2146 case bpfTag:
2147 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2148 filesToCopy, _ := bpfProgram.OutputFiles("")
2149 apex_sub_dir := bpfProgram.SubDir()
2150 for _, bpfFile := range filesToCopy {
2151 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2152 }
2153 } else {
2154 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2155 }
2156 case fsTag:
2157 if fs, ok := child.(filesystem.Filesystem); ok {
2158 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2159 } else {
2160 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2161 }
2162 case prebuiltTag:
2163 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2164 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2165 } else {
2166 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2167 }
2168 case compatConfigTag:
2169 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2170 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2171 } else {
2172 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2173 }
2174 case testTag:
2175 if ccTest, ok := child.(*cc.Module); ok {
2176 if ccTest.IsTestPerSrcAllTestsVariation() {
2177 // Multiple-output test module (where `test_per_src: true`).
2178 //
2179 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2180 // We do not add this variation to `filesInfo`, as it has no output;
2181 // however, we do add the other variations of this module as indirect
2182 // dependencies (see below).
2183 } else {
2184 // Single-output test module (where `test_per_src: false`).
2185 af := apexFileForExecutable(ctx, ccTest)
2186 af.class = nativeTest
2187 vctx.filesInfo = append(vctx.filesInfo, af)
2188 }
2189 return true // track transitive dependencies
2190 } else {
2191 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2192 }
2193 case keyTag:
2194 if key, ok := child.(*apexKey); ok {
2195 a.privateKeyFile = key.privateKeyFile
2196 a.publicKeyFile = key.publicKeyFile
2197 } else {
2198 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2199 }
2200 case certificateTag:
2201 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2202 a.containerCertificateFile = dep.Certificate.Pem
2203 a.containerPrivateKeyFile = dep.Certificate.Key
2204 } else {
2205 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2206 }
2207 case android.PrebuiltDepTag:
2208 // If the prebuilt is force disabled, remember to delete the prebuilt file
2209 // that might have been installed in the previous builds
2210 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2211 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2212 }
2213 }
2214 return false
2215 }
2216
2217 if a.vndkApex {
2218 return false
2219 }
2220
2221 // indirect dependencies
2222 am, ok := child.(android.ApexModule)
2223 if !ok {
2224 return false
2225 }
2226 // We cannot use a switch statement on `depTag` here as the checked
2227 // tags used below are private (e.g. `cc.sharedDepTag`).
2228 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2229 if ch, ok := child.(*cc.Module); ok {
2230 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2231 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2232 return false
2233 }
2234 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2235 af.transitiveDep = true
2236
2237 // Always track transitive dependencies for host.
2238 if a.Host() {
2239 vctx.filesInfo = append(vctx.filesInfo, af)
2240 return true
2241 }
2242
2243 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2244 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2245 // If the dependency is a stubs lib, don't include it in this APEX,
2246 // but make sure that the lib is installed on the device.
2247 // In case no APEX is having the lib, the lib is installed to the system
2248 // partition.
2249 //
2250 // Always include if we are a host-apex however since those won't have any
2251 // system libraries.
2252 if !am.DirectlyInAnyApex() {
2253 // we need a module name for Make
2254 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2255 if !android.InList(name, a.requiredDeps) {
2256 a.requiredDeps = append(a.requiredDeps, name)
2257 }
2258 }
2259 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2260 // Don't track further
2261 return false
2262 }
2263
2264 // If the dep is not considered to be in the same
2265 // apex, don't add it to filesInfo so that it is not
2266 // included in this APEX.
2267 // TODO(jiyong): move this to at the top of the
2268 // else-if clause for the indirect dependencies.
2269 // Currently, that's impossible because we would
2270 // like to record requiredNativeLibs even when
2271 // DepIsInSameAPex is false. We also shouldn't do
2272 // this for host.
2273 //
2274 // TODO(jiyong): explain why the same module is passed in twice.
2275 // Switching the first am to parent breaks lots of tests.
2276 if !android.IsDepInSameApex(ctx, am, am) {
2277 return false
2278 }
2279
2280 vctx.filesInfo = append(vctx.filesInfo, af)
2281 return true // track transitive dependencies
2282 } else if rm, ok := child.(*rust.Module); ok {
2283 af := apexFileForRustLibrary(ctx, rm)
2284 af.transitiveDep = true
2285 vctx.filesInfo = append(vctx.filesInfo, af)
2286 return true // track transitive dependencies
2287 }
2288 } else if cc.IsTestPerSrcDepTag(depTag) {
2289 if ch, ok := child.(*cc.Module); ok {
2290 af := apexFileForExecutable(ctx, ch)
2291 // Handle modules created as `test_per_src` variations of a single test module:
2292 // use the name of the generated test binary (`fileToCopy`) instead of the name
2293 // of the original test module (`depName`, shared by all `test_per_src`
2294 // variations of that module).
2295 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2296 // these are not considered transitive dep
2297 af.transitiveDep = false
2298 vctx.filesInfo = append(vctx.filesInfo, af)
2299 return true // track transitive dependencies
2300 }
2301 } else if cc.IsHeaderDepTag(depTag) {
2302 // nothing
2303 } else if java.IsJniDepTag(depTag) {
2304 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2305 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2306 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2307 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2308 }
2309 } else if rust.IsDylibDepTag(depTag) {
2310 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2311 af := apexFileForRustLibrary(ctx, rustm)
2312 af.transitiveDep = true
2313 vctx.filesInfo = append(vctx.filesInfo, af)
2314 return true // track transitive dependencies
2315 }
2316 } else if rust.IsRlibDepTag(depTag) {
2317 // Rlib is statically linked, but it might have shared lib
2318 // dependencies. Track them.
2319 return true
2320 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2321 // Add the contents of the bootclasspath fragment to the apex.
2322 switch child.(type) {
2323 case *java.Library, *java.SdkLibrary:
2324 javaModule := child.(javaModule)
2325 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2326 if !af.ok() {
2327 ctx.PropertyErrorf("bootclasspath_fragments",
2328 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2329 return false
2330 }
2331 vctx.filesInfo = append(vctx.filesInfo, af)
2332 return true // track transitive dependencies
2333 default:
2334 ctx.PropertyErrorf("bootclasspath_fragments",
2335 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2336 }
2337 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2338 // Add the contents of the systemserverclasspath fragment to the apex.
2339 switch child.(type) {
2340 case *java.Library, *java.SdkLibrary:
2341 af := apexFileForJavaModule(ctx, child.(javaModule))
2342 vctx.filesInfo = append(vctx.filesInfo, af)
2343 return true // track transitive dependencies
2344 default:
2345 ctx.PropertyErrorf("systemserverclasspath_fragments",
2346 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2347 }
2348 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2349 // nothing
2350 } else if depTag == android.DarwinUniversalVariantTag {
2351 // nothing
2352 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2353 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2354 }
2355 return false
2356}
2357
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002358// Creates build rules for an APEX. It consists of the following major steps:
2359//
2360// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2361// 2) traverse the dependency tree to collect apexFile structs from them.
2362// 3) some fields in apexBundle struct are configured
2363// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002364func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002365 ////////////////////////////////////////////////////////////////////////////////////////////
2366 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundak6a2b7c42022-05-19 21:28:53 -07002367 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002368 return
2369 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002370 ////////////////////////////////////////////////////////////////////////////////////////////
2371 // 2) traverse the dependency tree to collect apexFile structs from them.
2372
braleeb0c1f0c2021-06-07 22:49:13 +08002373 // Collect the module directory for IDE info in java/jdeps.go.
2374 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2375
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002376 // TODO(jiyong): do this using WalkPayloadDeps
2377 // TODO(jiyong): make this clean!!!
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002378 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2379 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
2380 vctx.normalizeFileInfo()
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002381 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002382 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002383 return
2384 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002385
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002386 ////////////////////////////////////////////////////////////////////////////////////////////
2387 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002388 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002389 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002390
Sasha Smundak6a2b7c42022-05-19 21:28:53 -07002391 a.setApexTypeAndSuffix(ctx)
2392 a.setPayloadFsType(ctx)
2393 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002394 if a.properties.ApexType != zipApex {
2395 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2396 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002397
2398 ////////////////////////////////////////////////////////////////////////////////////////////
2399 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002400 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002401 if a.properties.ApexType == flattenedApex {
2402 a.buildFlattenedApex(ctx)
2403 } else {
2404 a.buildUnflattenedApex(ctx)
2405 }
Jiyong Park956305c2020-01-09 12:32:06 +09002406 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002407 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002408
2409 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2410 if a.installable() {
2411 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2412 // along with other ordinary files. (Note that this is done by apexer for
2413 // non-flattened APEXes)
2414 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2415
2416 // Place the public key as apex_pubkey. This is also done by apexer for
2417 // non-flattened APEXes case.
2418 // TODO(jiyong): Why do we need this CP rule?
2419 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2420 ctx.Build(pctx, android.BuildParams{
2421 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002422 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002423 Output: copiedPubkey,
2424 })
2425 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2426 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002427}
2428
Paul Duffincc33ec82021-04-25 23:14:55 +01002429// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2430// the bootclasspath_fragment contributes to the apex.
2431func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2432 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2433 var filesToAdd []apexFile
2434
2435 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002436 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2437 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2438 dirInApex := filepath.Join("javalib", arch.String())
2439 for _, f := range files {
2440 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2441 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2442 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2443 filesToAdd = append(filesToAdd, af)
2444 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002445 }
2446 }
2447
satayev3db35472021-05-06 23:59:58 +01002448 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002449 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2450 filesToAdd = append(filesToAdd, *af)
2451 }
satayev3db35472021-05-06 23:59:58 +01002452
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002453 if pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex(); pathInApex != "" {
2454 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2455 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2456
2457 if pathOnHost != nil {
2458 // We need to copy the profile to a temporary path with the right filename because the apexer
2459 // will take the filename as is.
2460 ctx.Build(pctx, android.BuildParams{
2461 Rule: android.Cp,
2462 Input: pathOnHost,
2463 Output: tempPath,
2464 })
2465 } else {
2466 // At this point, the boot image profile cannot be generated. It is probably because the boot
2467 // image profile source file does not exist on the branch, or it is not available for the
2468 // current build target.
2469 // However, we cannot enforce the boot image profile to be generated because some build
2470 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2471 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2472 // only if the APEX is being built.
2473 ctx.Build(pctx, android.BuildParams{
2474 Rule: android.ErrorRule,
2475 Output: tempPath,
2476 Args: map[string]string{
2477 "error": "Boot image profile cannot be generated",
2478 },
2479 })
2480 }
2481
2482 androidMkModuleName := filepath.Base(pathInApex)
2483 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2484 filesToAdd = append(filesToAdd, af)
2485 }
2486
Paul Duffincc33ec82021-04-25 23:14:55 +01002487 return filesToAdd
2488}
2489
satayevb98371c2021-06-15 16:49:50 +01002490// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2491// the module contributes to the apex; or nil if the proto config was not generated.
2492func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2493 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2494 if !info.ClasspathFragmentProtoGenerated {
2495 return nil
2496 }
2497 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2498 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2499 return &af
satayev14e49132021-05-17 21:03:07 +01002500}
2501
Paul Duffincc33ec82021-04-25 23:14:55 +01002502// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2503// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002504func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2505 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2506
2507 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2508 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002509 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2510 if err != nil {
2511 ctx.ModuleErrorf("%s", err)
2512 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002513
2514 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2515 // bootclasspath_fragment.
2516 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2517 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002518}
2519
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002520///////////////////////////////////////////////////////////////////////////////////////////////////
2521// Factory functions
2522//
2523
2524func newApexBundle() *apexBundle {
2525 module := &apexBundle{}
2526
2527 module.AddProperties(&module.properties)
2528 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002529 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002530 module.AddProperties(&module.overridableProperties)
2531
2532 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2533 android.InitDefaultableModule(module)
2534 android.InitSdkAwareModule(module)
2535 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002536 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002537 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002538 return module
2539}
2540
Paul Duffineb8051d2021-10-18 17:49:39 +01002541func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002542 bundle := newApexBundle()
2543 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002544 return bundle
2545}
2546
2547// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2548// certain compatibility checks such as apex_available are not done for apex_test.
2549func testApexBundleFactory() android.Module {
2550 bundle := newApexBundle()
2551 bundle.testApex = true
2552 return bundle
2553}
2554
2555// apex packages other modules into an APEX file which is a packaging format for system-level
2556// components like binaries, shared libraries, etc.
2557func BundleFactory() android.Module {
2558 return newApexBundle()
2559}
2560
2561type Defaults struct {
2562 android.ModuleBase
2563 android.DefaultsModuleBase
2564}
2565
2566// apex_defaults provides defaultable properties to other apex modules.
2567func defaultsFactory() android.Module {
2568 return DefaultsFactory()
2569}
2570
2571func DefaultsFactory(props ...interface{}) android.Module {
2572 module := &Defaults{}
2573
2574 module.AddProperties(props...)
2575 module.AddProperties(
2576 &apexBundleProperties{},
2577 &apexTargetBundleProperties{},
2578 &overridableProperties{},
2579 )
2580
2581 android.InitDefaultsModule(module)
2582 return module
2583}
2584
2585type OverrideApex struct {
2586 android.ModuleBase
2587 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002588 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002589}
2590
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002591func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002592 // All the overrides happen in the base module.
2593}
2594
2595// override_apex is used to create an apex module based on another apex module by overriding some of
2596// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002597func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002598 m := &OverrideApex{}
2599
2600 m.AddProperties(&overridableProperties{})
2601
2602 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2603 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002604 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002605 return m
2606}
2607
Wei Li1c66fc72022-05-09 23:59:14 -07002608func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2609 if ctx.ModuleType() != "override_apex" {
2610 return
2611 }
2612
2613 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2614 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2615 if !baseApexExists {
2616 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2617 }
2618
2619 a, baseModuleIsApex := baseModule.(*apexBundle)
2620 if !baseModuleIsApex {
2621 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2622 }
2623 attrs, props := convertWithBp2build(a, ctx)
2624
2625 for _, p := range o.GetProperties() {
2626 overridableProperties, ok := p.(*overridableProperties)
2627 if !ok {
2628 continue
2629 }
Wei Li40f98732022-05-20 22:08:11 -07002630
2631 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2632 // After it is converted in convertWithBp2build(baseApex, ctx),
2633 // the attrs.Manifest.Value.Label is the file path relative to the directory
2634 // of base apex. So the following code converts it to a label that looks like
2635 // <package of base apex>:<path of manifest file> if base apex and override
2636 // apex are not in the same package.
2637 baseApexPackage := ctx.OtherModuleDir(a)
2638 overrideApexPackage := ctx.ModuleDir()
2639 if baseApexPackage != overrideApexPackage {
2640 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2641 }
2642
Wei Li1c66fc72022-05-09 23:59:14 -07002643 // Key
2644 if overridableProperties.Key != nil {
2645 attrs.Key = bazel.LabelAttribute{}
2646 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2647 }
2648
2649 // Certificate
2650 if overridableProperties.Certificate != nil {
2651 attrs.Certificate = bazel.LabelAttribute{}
2652 attrs.Certificate.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Certificate))
2653 }
2654
2655 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002656 if overridableProperties.Prebuilts != nil {
2657 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2658 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2659 }
Wei Li1c66fc72022-05-09 23:59:14 -07002660
2661 // Compressible
2662 if overridableProperties.Compressible != nil {
2663 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2664 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002665
2666 // Package name
2667 //
2668 // e.g. com.android.adbd's package name is com.android.adbd, but
2669 // com.google.android.adbd overrides the package name to com.google.android.adbd
2670 //
2671 // TODO: this can be overridden from the product configuration, see
2672 // getOverrideManifestPackageName and
2673 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2674 //
2675 // Instead of generating the BUILD files differently based on the product config
2676 // at the point of conversion, this should be handled by the BUILD file loading
2677 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2678 if overridableProperties.Package_name != "" {
2679 attrs.Package_name = &overridableProperties.Package_name
2680 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002681
2682 // Logging parent
2683 if overridableProperties.Logging_parent != "" {
2684 attrs.Logging_parent = &overridableProperties.Logging_parent
2685 }
Wei Li1c66fc72022-05-09 23:59:14 -07002686 }
2687
2688 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2689}
2690
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002691///////////////////////////////////////////////////////////////////////////////////////////////////
2692// Vality check routines
2693//
2694// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2695// certain conditions are not met.
2696//
2697// TODO(jiyong): move these checks to a separate go file.
2698
satayevad991492021-12-03 18:58:32 +00002699var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2700
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002701// Entures that min_sdk_version of the included modules are equal or less than the min_sdk_version
2702// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002703func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002704 if a.testApex || a.vndkApex {
2705 return
2706 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002707 // apexBundle::minSdkVersion reports its own errors.
2708 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002709 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002710}
2711
Albert Martineefabcf2022-03-21 20:11:16 +00002712// Returns apex's min_sdk_version string value, honoring overrides
2713func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2714 // Only override the minSdkVersion value on Apexes which already specify
2715 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2716 // min_sdk_version value is lower than the one to override with.
2717 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2718 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2719 originalMinApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2720 isMinSdkSet := a.properties.Min_sdk_version != nil
2721 isOverrideValueHigher := overrideApiLevel.CompareTo(originalMinApiLevel) > 0
2722 if overrideMinSdkValue != "" && isMinSdkSet && isOverrideValueHigher {
2723 return overrideMinSdkValue
2724 }
2725
2726 return proptools.String(a.properties.Min_sdk_version)
2727}
2728
2729// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002730func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2731 return android.SdkSpec{
2732 Kind: android.SdkNone,
2733 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002734 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002735 }
2736}
2737
Albert Martineefabcf2022-03-21 20:11:16 +00002738// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002739func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002740 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2741}
2742
2743// Construct ApiLevel object from min_sdk_version string value
2744func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2745 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002746 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002747 }
Albert Martineefabcf2022-03-21 20:11:16 +00002748 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002749 if err != nil {
2750 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2751 return android.NoneApiLevel
2752 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002753 return apiLevel
2754}
2755
2756// Ensures that a lib providing stub isn't statically linked
2757func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2758 // Practically, we only care about regular APEXes on the device.
2759 if ctx.Host() || a.testApex || a.vndkApex {
2760 return
2761 }
2762
2763 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2764
2765 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2766 if ccm, ok := to.(*cc.Module); ok {
2767 apexName := ctx.ModuleName()
2768 fromName := ctx.OtherModuleName(from)
2769 toName := ctx.OtherModuleName(to)
2770
2771 // If `to` is not actually in the same APEX as `from` then it does not need
2772 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002773 //
2774 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002775 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2776 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2777 return false
2778 }
2779
2780 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2781 // exception to this rule. It can't make the static dependencies dynamic
2782 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002783 // Same rule should be applied to linkerconfig, because it should be executed
2784 // only with static linked libraries before linker is available with ld.config.txt
2785 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002786 return false
2787 }
2788
2789 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2790 if isStubLibraryFromOtherApex && !externalDep {
2791 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2792 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2793 }
2794
2795 }
2796 return true
2797 })
2798}
2799
satayevb98371c2021-06-15 16:49:50 +01002800// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002801func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2802 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002803 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002804 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2805 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002806 if a.UsePlatformApis() {
2807 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2808 }
Daniel Norman69109112021-12-02 12:52:42 -08002809 if a.SocSpecific() || a.DeviceSpecific() {
2810 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2811 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002812 if a.FutureUpdatable() {
2813 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2814 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002815 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002816 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002817 }
2818}
2819
satayevb98371c2021-06-15 16:49:50 +01002820// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2821func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2822 ctx.VisitDirectDeps(func(module android.Module) {
2823 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2824 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2825 if !info.ClasspathFragmentProtoGenerated {
2826 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2827 }
2828 }
2829 })
2830}
2831
2832// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002833func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002834 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2835 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002836 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2837 tag := ctx.OtherModuleDependencyTag(module)
2838 switch tag {
2839 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002840 if m, ok := module.(interface {
2841 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2842 }); ok {
2843 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002844 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2845 }
2846 }
2847 }
2848 })
2849}
2850
satayevb98371c2021-06-15 16:49:50 +01002851// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002852func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2853 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2854 if ctx.Host() || a.testApex || a.vndkApex {
2855 return
2856 }
2857
2858 // Because APEXes targeting other than system/system_ext partitions can't set
2859 // apex_available, we skip checks for these APEXes
2860 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2861 return
2862 }
2863
2864 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2865 // Requiring them and their transitive depencies with apex_available is not right
2866 // because they just add noise.
2867 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2868 return
2869 }
2870
2871 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2872 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2873 if externalDep {
2874 return false
2875 }
2876
2877 apexName := ctx.ModuleName()
2878 fromName := ctx.OtherModuleName(from)
2879 toName := ctx.OtherModuleName(to)
2880
2881 // If `to` is not actually in the same APEX as `from` then it does not need
2882 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002883 //
2884 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002885 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2886 // As soon as the dependency graph crosses the APEX boundary, don't go
2887 // further.
2888 return false
2889 }
2890
2891 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
2892 return true
2893 }
Jiyong Park767dbd92021-03-04 13:03:10 +09002894 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2895 "\n\nDependency path:%s\n\n"+
2896 "Consider adding %q to 'apex_available' property of %q",
2897 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002898 // Visit this module's dependencies to check and report any issues with their availability.
2899 return true
2900 })
2901}
2902
Jiyong Park192600a2021-08-03 07:52:17 +00002903// checkStaticExecutable ensures that executables in an APEX are not static.
2904func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09002905 // No need to run this for host APEXes
2906 if ctx.Host() {
2907 return
2908 }
2909
Jiyong Park192600a2021-08-03 07:52:17 +00002910 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2911 if ctx.OtherModuleDependencyTag(module) != executableTag {
2912 return
2913 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09002914
2915 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00002916 apex := a.ApexVariationName()
2917 exec := ctx.OtherModuleName(module)
2918 if isStaticExecutableAllowed(apex, exec) {
2919 return
2920 }
2921 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
2922 }
2923 })
2924}
2925
2926// A small list of exceptions where static executables are allowed in APEXes.
2927func isStaticExecutableAllowed(apex string, exec string) bool {
2928 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07002929 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00002930 "linker",
2931 "linkerconfig",
2932 },
2933 }
2934 execNames, ok := m[apex]
2935 return ok && android.InList(exec, execNames)
2936}
2937
braleeb0c1f0c2021-06-07 22:49:13 +08002938// Collect information for opening IDE project files in java/jdeps.go.
2939func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09002940 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
2941 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
2942 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08002943 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
2944}
2945
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002946var (
2947 apexAvailBaseline = makeApexAvailableBaseline()
2948 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
2949)
2950
Colin Cross440e0d02020-06-11 11:32:11 -07002951func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002952 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002953 moduleName = normalizeModuleName(moduleName)
2954
Colin Cross440e0d02020-06-11 11:32:11 -07002955 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002956 return true
2957 }
2958
2959 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07002960 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002961 return true
2962 }
2963
2964 return false
2965}
2966
2967func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09002968 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
2969 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00002970 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09002971 if strings.HasPrefix(moduleName, "libclang_rt.") {
2972 // This module has many arch variants that depend on the product being built.
2973 // We don't want to list them all
2974 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002975 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09002976 if strings.HasPrefix(moduleName, "androidx.") {
2977 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
2978 moduleName = "androidx"
2979 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002980 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002981}
2982
Jiyong Park8e6d52f2020-11-19 14:37:47 +09002983// Transform the map of apex -> modules to module -> apexes.
2984func invertApexBaseline(m map[string][]string) map[string][]string {
2985 r := make(map[string][]string)
2986 for apex, modules := range m {
2987 for _, module := range modules {
2988 r[module] = append(r[module], apex)
2989 }
2990 }
2991 return r
2992}
2993
2994// Retrieve the baseline of apexes to which the supplied module belongs.
2995func BaselineApexAvailable(moduleName string) []string {
2996 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
2997}
2998
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002999// This is a map from apex to modules, which overrides the apex_available setting for that
3000// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003001// TODO(b/147364041): remove this
3002func makeApexAvailableBaseline() map[string][]string {
3003 // The "Module separator"s below are employed to minimize merge conflicts.
3004 m := make(map[string][]string)
3005 //
3006 // Module separator
3007 //
3008 m["com.android.appsearch"] = []string{
3009 "icing-java-proto-lite",
3010 "libprotobuf-java-lite",
3011 }
3012 //
3013 // Module separator
3014 //
Etienne Ruffieux16512672021-12-15 15:49:04 +00003015 m["com.android.bluetooth"] = []string{
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003016 "android.hardware.audio.common@5.0",
3017 "android.hardware.bluetooth.a2dp@1.0",
3018 "android.hardware.bluetooth.audio@2.0",
3019 "android.hardware.bluetooth@1.0",
3020 "android.hardware.bluetooth@1.1",
3021 "android.hardware.graphics.bufferqueue@1.0",
3022 "android.hardware.graphics.bufferqueue@2.0",
3023 "android.hardware.graphics.common@1.0",
3024 "android.hardware.graphics.common@1.1",
3025 "android.hardware.graphics.common@1.2",
3026 "android.hardware.media@1.0",
3027 "android.hidl.safe_union@1.0",
3028 "android.hidl.token@1.0",
3029 "android.hidl.token@1.0-utils",
3030 "avrcp-target-service",
3031 "avrcp_headers",
3032 "bluetooth-protos-lite",
3033 "bluetooth.mapsapi",
3034 "com.android.vcard",
3035 "dnsresolver_aidl_interface-V2-java",
3036 "ipmemorystore-aidl-interfaces-V5-java",
3037 "ipmemorystore-aidl-interfaces-java",
3038 "internal_include_headers",
3039 "lib-bt-packets",
3040 "lib-bt-packets-avrcp",
3041 "lib-bt-packets-base",
3042 "libFraunhoferAAC",
3043 "libaudio-a2dp-hw-utils",
3044 "libaudio-hearing-aid-hw-utils",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003045 "libbluetooth",
3046 "libbluetooth-types",
3047 "libbluetooth-types-header",
3048 "libbluetooth_gd",
3049 "libbluetooth_headers",
3050 "libbluetooth_jni",
3051 "libbt-audio-hal-interface",
3052 "libbt-bta",
3053 "libbt-common",
3054 "libbt-hci",
3055 "libbt-platform-protos-lite",
3056 "libbt-protos-lite",
3057 "libbt-sbc-decoder",
3058 "libbt-sbc-encoder",
3059 "libbt-stack",
3060 "libbt-utils",
3061 "libbtcore",
3062 "libbtdevice",
3063 "libbte",
3064 "libbtif",
3065 "libchrome",
3066 "libevent",
3067 "libfmq",
3068 "libg722codec",
3069 "libgui_headers",
3070 "libmedia_headers",
3071 "libmodpb64",
3072 "libosi",
3073 "libstagefright_foundation_headers",
3074 "libstagefright_headers",
3075 "libstatslog",
3076 "libstatssocket",
3077 "libtinyxml2",
3078 "libudrv-uipc",
3079 "libz",
3080 "media_plugin_headers",
3081 "net-utils-services-common",
3082 "netd_aidl_interface-unstable-java",
3083 "netd_event_listener_interface-java",
3084 "netlink-client",
3085 "networkstack-client",
3086 "sap-api-java-static",
3087 "services.net",
3088 }
3089 //
3090 // Module separator
3091 //
3092 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3093 //
3094 // Module separator
3095 //
3096 m["com.android.extservices"] = []string{
3097 "error_prone_annotations",
3098 "ExtServices-core",
3099 "ExtServices",
3100 "libtextclassifier-java",
3101 "libz_current",
3102 "textclassifier-statsd",
3103 "TextClassifierNotificationLibNoManifest",
3104 "TextClassifierServiceLibNoManifest",
3105 }
3106 //
3107 // Module separator
3108 //
3109 m["com.android.neuralnetworks"] = []string{
3110 "android.hardware.neuralnetworks@1.0",
3111 "android.hardware.neuralnetworks@1.1",
3112 "android.hardware.neuralnetworks@1.2",
3113 "android.hardware.neuralnetworks@1.3",
3114 "android.hidl.allocator@1.0",
3115 "android.hidl.memory.token@1.0",
3116 "android.hidl.memory@1.0",
3117 "android.hidl.safe_union@1.0",
3118 "libarect",
3119 "libbuildversion",
3120 "libmath",
3121 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003122 }
3123 //
3124 // Module separator
3125 //
3126 m["com.android.media"] = []string{
3127 "android.frameworks.bufferhub@1.0",
3128 "android.hardware.cas.native@1.0",
3129 "android.hardware.cas@1.0",
3130 "android.hardware.configstore-utils",
3131 "android.hardware.configstore@1.0",
3132 "android.hardware.configstore@1.1",
3133 "android.hardware.graphics.allocator@2.0",
3134 "android.hardware.graphics.allocator@3.0",
3135 "android.hardware.graphics.bufferqueue@1.0",
3136 "android.hardware.graphics.bufferqueue@2.0",
3137 "android.hardware.graphics.common@1.0",
3138 "android.hardware.graphics.common@1.1",
3139 "android.hardware.graphics.common@1.2",
3140 "android.hardware.graphics.mapper@2.0",
3141 "android.hardware.graphics.mapper@2.1",
3142 "android.hardware.graphics.mapper@3.0",
3143 "android.hardware.media.omx@1.0",
3144 "android.hardware.media@1.0",
3145 "android.hidl.allocator@1.0",
3146 "android.hidl.memory.token@1.0",
3147 "android.hidl.memory@1.0",
3148 "android.hidl.token@1.0",
3149 "android.hidl.token@1.0-utils",
3150 "bionic_libc_platform_headers",
3151 "exoplayer2-extractor",
3152 "exoplayer2-extractor-annotation-stubs",
3153 "gl_headers",
3154 "jsr305",
3155 "libEGL",
3156 "libEGL_blobCache",
3157 "libEGL_getProcAddress",
3158 "libFLAC",
3159 "libFLAC-config",
3160 "libFLAC-headers",
3161 "libGLESv2",
3162 "libaacextractor",
3163 "libamrextractor",
3164 "libarect",
3165 "libaudio_system_headers",
3166 "libaudioclient",
3167 "libaudioclient_headers",
3168 "libaudiofoundation",
3169 "libaudiofoundation_headers",
3170 "libaudiomanager",
3171 "libaudiopolicy",
3172 "libaudioutils",
3173 "libaudioutils_fixedfft",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003174 "libbluetooth-types-header",
3175 "libbufferhub",
3176 "libbufferhub_headers",
3177 "libbufferhubqueue",
3178 "libc_malloc_debug_backtrace",
3179 "libcamera_client",
3180 "libcamera_metadata",
3181 "libdvr_headers",
3182 "libexpat",
3183 "libfifo",
3184 "libflacextractor",
3185 "libgrallocusage",
3186 "libgraphicsenv",
3187 "libgui",
3188 "libgui_headers",
3189 "libhardware_headers",
3190 "libinput",
3191 "liblzma",
3192 "libmath",
3193 "libmedia",
3194 "libmedia_codeclist",
3195 "libmedia_headers",
3196 "libmedia_helper",
3197 "libmedia_helper_headers",
3198 "libmedia_midiiowrapper",
3199 "libmedia_omx",
3200 "libmediautils",
3201 "libmidiextractor",
3202 "libmkvextractor",
3203 "libmp3extractor",
3204 "libmp4extractor",
3205 "libmpeg2extractor",
3206 "libnativebase_headers",
3207 "libnativewindow_headers",
3208 "libnblog",
3209 "liboggextractor",
3210 "libpackagelistparser",
3211 "libpdx",
3212 "libpdx_default_transport",
3213 "libpdx_headers",
3214 "libpdx_uds",
3215 "libprocinfo",
3216 "libspeexresampler",
3217 "libspeexresampler",
3218 "libstagefright_esds",
3219 "libstagefright_flacdec",
3220 "libstagefright_flacdec",
3221 "libstagefright_foundation",
3222 "libstagefright_foundation_headers",
3223 "libstagefright_foundation_without_imemory",
3224 "libstagefright_headers",
3225 "libstagefright_id3",
3226 "libstagefright_metadatautils",
3227 "libstagefright_mpeg2extractor",
3228 "libstagefright_mpeg2support",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003229 "libui",
3230 "libui_headers",
3231 "libunwindstack",
3232 "libvibrator",
3233 "libvorbisidec",
3234 "libwavextractor",
3235 "libwebm",
3236 "media_ndk_headers",
3237 "media_plugin_headers",
3238 "updatable-media",
3239 }
3240 //
3241 // Module separator
3242 //
3243 m["com.android.media.swcodec"] = []string{
3244 "android.frameworks.bufferhub@1.0",
3245 "android.hardware.common-ndk_platform",
3246 "android.hardware.configstore-utils",
3247 "android.hardware.configstore@1.0",
3248 "android.hardware.configstore@1.1",
3249 "android.hardware.graphics.allocator@2.0",
3250 "android.hardware.graphics.allocator@3.0",
3251 "android.hardware.graphics.allocator@4.0",
3252 "android.hardware.graphics.bufferqueue@1.0",
3253 "android.hardware.graphics.bufferqueue@2.0",
3254 "android.hardware.graphics.common-ndk_platform",
3255 "android.hardware.graphics.common@1.0",
3256 "android.hardware.graphics.common@1.1",
3257 "android.hardware.graphics.common@1.2",
3258 "android.hardware.graphics.mapper@2.0",
3259 "android.hardware.graphics.mapper@2.1",
3260 "android.hardware.graphics.mapper@3.0",
3261 "android.hardware.graphics.mapper@4.0",
3262 "android.hardware.media.bufferpool@2.0",
3263 "android.hardware.media.c2@1.0",
3264 "android.hardware.media.c2@1.1",
3265 "android.hardware.media.omx@1.0",
3266 "android.hardware.media@1.0",
3267 "android.hardware.media@1.0",
3268 "android.hidl.memory.token@1.0",
3269 "android.hidl.memory@1.0",
3270 "android.hidl.safe_union@1.0",
3271 "android.hidl.token@1.0",
3272 "android.hidl.token@1.0-utils",
3273 "libEGL",
3274 "libFLAC",
3275 "libFLAC-config",
3276 "libFLAC-headers",
3277 "libFraunhoferAAC",
3278 "libLibGuiProperties",
3279 "libarect",
3280 "libaudio_system_headers",
3281 "libaudioutils",
3282 "libaudioutils",
3283 "libaudioutils_fixedfft",
3284 "libavcdec",
3285 "libavcenc",
3286 "libavservices_minijail",
3287 "libavservices_minijail",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003288 "libbinderthreadstateutils",
3289 "libbluetooth-types-header",
3290 "libbufferhub_headers",
3291 "libcodec2",
3292 "libcodec2_headers",
3293 "libcodec2_hidl@1.0",
3294 "libcodec2_hidl@1.1",
3295 "libcodec2_internal",
3296 "libcodec2_soft_aacdec",
3297 "libcodec2_soft_aacenc",
3298 "libcodec2_soft_amrnbdec",
3299 "libcodec2_soft_amrnbenc",
3300 "libcodec2_soft_amrwbdec",
3301 "libcodec2_soft_amrwbenc",
3302 "libcodec2_soft_av1dec_gav1",
3303 "libcodec2_soft_avcdec",
3304 "libcodec2_soft_avcenc",
3305 "libcodec2_soft_common",
3306 "libcodec2_soft_flacdec",
3307 "libcodec2_soft_flacenc",
3308 "libcodec2_soft_g711alawdec",
3309 "libcodec2_soft_g711mlawdec",
3310 "libcodec2_soft_gsmdec",
3311 "libcodec2_soft_h263dec",
3312 "libcodec2_soft_h263enc",
3313 "libcodec2_soft_hevcdec",
3314 "libcodec2_soft_hevcenc",
3315 "libcodec2_soft_mp3dec",
3316 "libcodec2_soft_mpeg2dec",
3317 "libcodec2_soft_mpeg4dec",
3318 "libcodec2_soft_mpeg4enc",
3319 "libcodec2_soft_opusdec",
3320 "libcodec2_soft_opusenc",
3321 "libcodec2_soft_rawdec",
3322 "libcodec2_soft_vorbisdec",
3323 "libcodec2_soft_vp8dec",
3324 "libcodec2_soft_vp8enc",
3325 "libcodec2_soft_vp9dec",
3326 "libcodec2_soft_vp9enc",
3327 "libcodec2_vndk",
3328 "libdvr_headers",
3329 "libfmq",
3330 "libfmq",
3331 "libgav1",
3332 "libgralloctypes",
3333 "libgrallocusage",
3334 "libgraphicsenv",
3335 "libgsm",
3336 "libgui_bufferqueue_static",
3337 "libgui_headers",
3338 "libhardware",
3339 "libhardware_headers",
3340 "libhevcdec",
3341 "libhevcenc",
3342 "libion",
3343 "libjpeg",
3344 "liblzma",
3345 "libmath",
3346 "libmedia_codecserviceregistrant",
3347 "libmedia_headers",
3348 "libmpeg2dec",
3349 "libnativebase_headers",
3350 "libnativewindow_headers",
3351 "libpdx_headers",
3352 "libscudo_wrapper",
3353 "libsfplugin_ccodec_utils",
3354 "libspeexresampler",
3355 "libstagefright_amrnb_common",
3356 "libstagefright_amrnbdec",
3357 "libstagefright_amrnbenc",
3358 "libstagefright_amrwbdec",
3359 "libstagefright_amrwbenc",
3360 "libstagefright_bufferpool@2.0.1",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003361 "libstagefright_enc_common",
3362 "libstagefright_flacdec",
3363 "libstagefright_foundation",
3364 "libstagefright_foundation_headers",
3365 "libstagefright_headers",
3366 "libstagefright_m4vh263dec",
3367 "libstagefright_m4vh263enc",
3368 "libstagefright_mp3dec",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003369 "libui",
3370 "libui_headers",
3371 "libunwindstack",
3372 "libvorbisidec",
3373 "libvpx",
3374 "libyuv",
3375 "libyuv_static",
3376 "media_ndk_headers",
3377 "media_plugin_headers",
3378 "mediaswcodec",
3379 }
3380 //
3381 // Module separator
3382 //
3383 m["com.android.mediaprovider"] = []string{
3384 "MediaProvider",
3385 "MediaProviderGoogle",
3386 "fmtlib_ndk",
3387 "libbase_ndk",
3388 "libfuse",
3389 "libfuse_jni",
3390 }
3391 //
3392 // Module separator
3393 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003394 m["com.android.runtime"] = []string{
3395 "bionic_libc_platform_headers",
3396 "libarm-optimized-routines-math",
3397 "libc_aeabi",
3398 "libc_bionic",
3399 "libc_bionic_ndk",
3400 "libc_bootstrap",
3401 "libc_common",
3402 "libc_common_shared",
3403 "libc_common_static",
3404 "libc_dns",
3405 "libc_dynamic_dispatch",
3406 "libc_fortify",
3407 "libc_freebsd",
3408 "libc_freebsd_large_stack",
3409 "libc_gdtoa",
3410 "libc_init_dynamic",
3411 "libc_init_static",
3412 "libc_jemalloc_wrapper",
3413 "libc_netbsd",
3414 "libc_nomalloc",
3415 "libc_nopthread",
3416 "libc_openbsd",
3417 "libc_openbsd_large_stack",
3418 "libc_openbsd_ndk",
3419 "libc_pthread",
3420 "libc_static_dispatch",
3421 "libc_syscalls",
3422 "libc_tzcode",
3423 "libc_unwind_static",
3424 "libdebuggerd",
3425 "libdebuggerd_common_headers",
3426 "libdebuggerd_handler_core",
3427 "libdebuggerd_handler_fallback",
3428 "libdl_static",
3429 "libjemalloc5",
3430 "liblinker_main",
3431 "liblinker_malloc",
3432 "liblz4",
3433 "liblzma",
3434 "libprocinfo",
3435 "libpropertyinfoparser",
3436 "libscudo",
3437 "libstdc++",
3438 "libsystemproperties",
3439 "libtombstoned_client_static",
3440 "libunwindstack",
3441 "libz",
3442 "libziparchive",
3443 }
3444 //
3445 // Module separator
3446 //
3447 m["com.android.tethering"] = []string{
3448 "android.hardware.tetheroffload.config-V1.0-java",
3449 "android.hardware.tetheroffload.control-V1.0-java",
3450 "android.hidl.base-V1.0-java",
3451 "libcgrouprc",
3452 "libcgrouprc_format",
3453 "libtetherutilsjni",
3454 "libvndksupport",
3455 "net-utils-framework-common",
3456 "netd_aidl_interface-V3-java",
3457 "netlink-client",
3458 "networkstack-aidl-interfaces-java",
3459 "tethering-aidl-interfaces-java",
3460 "TetheringApiCurrentLib",
3461 }
3462 //
3463 // Module separator
3464 //
3465 m["com.android.wifi"] = []string{
3466 "PlatformProperties",
3467 "android.hardware.wifi-V1.0-java",
3468 "android.hardware.wifi-V1.0-java-constants",
3469 "android.hardware.wifi-V1.1-java",
3470 "android.hardware.wifi-V1.2-java",
3471 "android.hardware.wifi-V1.3-java",
3472 "android.hardware.wifi-V1.4-java",
3473 "android.hardware.wifi.hostapd-V1.0-java",
3474 "android.hardware.wifi.hostapd-V1.1-java",
3475 "android.hardware.wifi.hostapd-V1.2-java",
3476 "android.hardware.wifi.supplicant-V1.0-java",
3477 "android.hardware.wifi.supplicant-V1.1-java",
3478 "android.hardware.wifi.supplicant-V1.2-java",
3479 "android.hardware.wifi.supplicant-V1.3-java",
3480 "android.hidl.base-V1.0-java",
3481 "android.hidl.manager-V1.0-java",
3482 "android.hidl.manager-V1.1-java",
3483 "android.hidl.manager-V1.2-java",
3484 "bouncycastle-unbundled",
3485 "dnsresolver_aidl_interface-V2-java",
3486 "error_prone_annotations",
3487 "framework-wifi-pre-jarjar",
3488 "framework-wifi-util-lib",
3489 "ipmemorystore-aidl-interfaces-V3-java",
3490 "ipmemorystore-aidl-interfaces-java",
3491 "ksoap2",
3492 "libnanohttpd",
3493 "libwifi-jni",
3494 "net-utils-services-common",
3495 "netd_aidl_interface-V2-java",
3496 "netd_aidl_interface-unstable-java",
3497 "netd_event_listener_interface-java",
3498 "netlink-client",
3499 "networkstack-client",
3500 "services.net",
3501 "wifi-lite-protos",
3502 "wifi-nano-protos",
3503 "wifi-service-pre-jarjar",
3504 "wifi-service-resources",
3505 }
3506 //
3507 // Module separator
3508 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003509 m["com.android.os.statsd"] = []string{
3510 "libstatssocket",
3511 }
3512 //
3513 // Module separator
3514 //
3515 m[android.AvailableToAnyApex] = []string{
3516 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3517 "androidx",
3518 "androidx-constraintlayout_constraintlayout",
3519 "androidx-constraintlayout_constraintlayout-nodeps",
3520 "androidx-constraintlayout_constraintlayout-solver",
3521 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3522 "com.google.android.material_material",
3523 "com.google.android.material_material-nodeps",
3524
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003525 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003526 "libprofile-clang-extras",
3527 "libprofile-clang-extras_ndk",
3528 "libprofile-extras",
3529 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003530 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003531 }
3532 return m
3533}
3534
3535func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003536 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3537 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003538}
3539
Spandan Dasf14e2542021-11-12 00:01:37 +00003540func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3541 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3542 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003543 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003544 With("name", jar).
3545 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3546 Because(jar +
3547 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003548 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003549 " 1. If the offending code is from a statically linked library, consider " +
3550 "removing that dependency and using an alternative already in the " +
3551 "bootclasspath, or perhaps a shared library." +
3552 " 2. Move the offending code into an allowed package.\n" +
3553 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3554 "health implications of bundling that code, particularly if the offending jar " +
3555 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003556
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003557 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003558 }
3559 return rules
3560}
3561
Anton Hanssone1b18362021-12-23 15:05:38 +00003562// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003563// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003564func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003565 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003566 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003567 "android.net.ssl",
3568 "com.android.org.conscrypt",
3569 },
Wei Li40f98732022-05-20 22:08:11 -07003570 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003571 "android.media",
3572 },
3573 }
3574}
3575
Anton Hanssone1b18362021-12-23 15:05:38 +00003576// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003577// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003578func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003579 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003580 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003581 "android.provider",
3582 },
Wei Li40f98732022-05-20 22:08:11 -07003583 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003584 "android.permission",
3585 "android.app.role",
3586 "com.android.permission",
3587 "com.android.role",
3588 },
Wei Li40f98732022-05-20 22:08:11 -07003589 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003590 "android.os.ext",
3591 },
Wei Li40f98732022-05-20 22:08:11 -07003592 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003593 "android.app",
3594 "android.os",
3595 "android.util",
3596 "com.android.internal.statsd",
3597 "com.android.server.stats",
3598 },
Wei Li40f98732022-05-20 22:08:11 -07003599 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003600 "com.android.server.wifi",
3601 "com.android.wifi.x",
3602 "android.hardware.wifi",
3603 "android.net.wifi",
3604 },
Wei Li40f98732022-05-20 22:08:11 -07003605 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003606 "android.net",
3607 },
3608 }
3609}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003610
3611// For Bazel / bp2build
3612
3613type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003614 Manifest bazel.LabelAttribute
3615 Android_manifest bazel.LabelAttribute
3616 File_contexts bazel.LabelAttribute
3617 Key bazel.LabelAttribute
3618 Certificate bazel.LabelAttribute
3619 Min_sdk_version *string
3620 Updatable bazel.BoolAttribute
3621 Installable bazel.BoolAttribute
3622 Binaries bazel.LabelListAttribute
3623 Prebuilts bazel.LabelListAttribute
3624 Native_shared_libs_32 bazel.LabelListAttribute
3625 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003626 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003627 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003628 Logging_parent *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003629}
3630
3631type convertedNativeSharedLibs struct {
3632 Native_shared_libs_32 bazel.LabelListAttribute
3633 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003634}
3635
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003636// ConvertWithBp2build performs bp2build conversion of an apex
3637func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
3638 // We do not convert apex_test modules at this time
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003639 if ctx.ModuleType() != "apex" {
3640 return
3641 }
3642
Wei Li1c66fc72022-05-09 23:59:14 -07003643 attrs, props := convertWithBp2build(a, ctx)
3644 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, &attrs)
3645}
3646
3647func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003648 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003649 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003650
3651 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003652 if a.properties.AndroidManifest != nil {
3653 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003654 }
3655
3656 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003657 if a.properties.File_contexts == nil {
3658 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3659 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3660 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3661 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003662 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003663 } else {
3664 // File_contexts is a file
3665 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003666 }
3667
Albert Martineefabcf2022-03-21 20:11:16 +00003668 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3669 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003670 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003671 if a.properties.Min_sdk_version != nil {
3672 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003673 }
3674
3675 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003676 if a.overridableProperties.Key != nil {
3677 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003678 }
3679
3680 var certificateLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003681 if a.overridableProperties.Certificate != nil {
3682 certificateLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Certificate))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003683 }
3684
Yu Liu4ae55d12022-01-05 17:17:23 -08003685 nativeSharedLibs := &convertedNativeSharedLibs{
3686 Native_shared_libs_32: bazel.LabelListAttribute{},
3687 Native_shared_libs_64: bazel.LabelListAttribute{},
3688 }
3689 compileMultilib := "both"
3690 if a.CompileMultilib() != nil {
3691 compileMultilib = *a.CompileMultilib()
3692 }
3693
3694 // properties.Native_shared_libs is treated as "both"
3695 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3696 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3697 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3698 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3699 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003700
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003701 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003702 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3703 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3704
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003705 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003706 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003707
3708 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003709 if a.properties.Updatable != nil {
3710 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003711 }
3712
3713 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003714 if a.properties.Installable != nil {
3715 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003716 }
3717
Wei Lif034cb42022-01-19 15:54:31 -08003718 var compressibleAttribute bazel.BoolAttribute
3719 if a.overridableProperties.Compressible != nil {
3720 compressibleAttribute.Value = a.overridableProperties.Compressible
3721 }
3722
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003723 var packageName *string
3724 if a.overridableProperties.Package_name != "" {
3725 packageName = &a.overridableProperties.Package_name
3726 }
3727
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003728 var loggingParent *string
3729 if a.overridableProperties.Logging_parent != "" {
3730 loggingParent = &a.overridableProperties.Logging_parent
3731 }
3732
Wei Li1c66fc72022-05-09 23:59:14 -07003733 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003734 Manifest: manifestLabelAttribute,
3735 Android_manifest: androidManifestLabelAttribute,
3736 File_contexts: fileContextsLabelAttribute,
3737 Min_sdk_version: minSdkVersion,
3738 Key: keyLabelAttribute,
3739 Certificate: certificateLabelAttribute,
3740 Updatable: updatableAttribute,
3741 Installable: installableAttribute,
3742 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3743 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3744 Binaries: binariesLabelListAttribute,
3745 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003746 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003747 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003748 Logging_parent: loggingParent,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003749 }
3750
3751 props := bazel.BazelTargetModuleProperties{
3752 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003753 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003754 }
3755
Wei Li1c66fc72022-05-09 23:59:14 -07003756 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003757}
Yu Liu4ae55d12022-01-05 17:17:23 -08003758
3759// The following conversions are based on this table where the rows are the compile_multilib
3760// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3761// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3762// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3763// should not be compiled.
3764// multib/compile_multilib, 32, 64, both, first
3765// 32, 32/32, none/none, 32/32, none/32
3766// 64, none/none, 64/none, 64/none, 64/none
3767// both, 32/32, 64/none, 32&64/32, 64/32
3768// first, 32/32, 64/none, 64/32, 64/32
3769
3770func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3771 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3772 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3773 switch compileMultilb {
3774 case "both", "32":
3775 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3776 case "first":
3777 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3778 case "64":
3779 // Incompatible, ignore
3780 default:
3781 invalidCompileMultilib(ctx, compileMultilb)
3782 }
3783}
3784
3785func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3786 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3787 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3788 switch compileMultilb {
3789 case "both", "64", "first":
3790 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3791 case "32":
3792 // Incompatible, ignore
3793 default:
3794 invalidCompileMultilib(ctx, compileMultilb)
3795 }
3796}
3797
3798func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3799 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3800 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3801 switch compileMultilb {
3802 case "both":
3803 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3804 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3805 case "first":
3806 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3807 case "32":
3808 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3809 case "64":
3810 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3811 default:
3812 invalidCompileMultilib(ctx, compileMultilb)
3813 }
3814}
3815
3816func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3817 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3818 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3819 switch compileMultilb {
3820 case "both", "first":
3821 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3822 case "32":
3823 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3824 case "64":
3825 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3826 default:
3827 invalidCompileMultilib(ctx, compileMultilb)
3828 }
3829}
3830
3831func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3832 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3833 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3834}
3835
3836func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3837 list := bazel.LabelListAttribute{}
3838 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3839 nativeSharedLibs.Native_shared_libs_32.Append(list)
3840}
3841
3842func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3843 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3844 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3845}
3846
3847func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3848 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3849 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3850}
3851
3852func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3853 labelListAttr *bazel.LabelListAttribute) {
3854 list := bazel.LabelListAttribute{}
3855 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3856 labelListAttr.Append(list)
3857}
3858
3859func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3860 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3861}