blob: ff9681900a89124be24696ac10fc9c3596981340 [file] [log] [blame]
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090015// package apex implements build rules for creating the APEX files which are container for
16// lower-level system components. See https://source.android.com/devices/tech/ota/apex
Jiyong Park48ca7dc2018-10-10 14:01:00 +090017package apex
18
19import (
Sasha Smundakfe9a5b82022-07-27 14:51:45 -070020 "android/soong/bazel/cquery"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090021 "fmt"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090022 "path/filepath"
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +000023 "regexp"
Jiyong Parkab3ceb32018-10-10 14:05:29 +090024 "sort"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090025 "strings"
26
Jiyong Park48ca7dc2018-10-10 14:01:00 +090027 "github.com/google/blueprint"
Alex Light778127a2019-02-27 14:19:50 -080028 "github.com/google/blueprint/bootstrap"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090029 "github.com/google/blueprint/proptools"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070030
31 "android/soong/android"
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -040032 "android/soong/bazel"
markchien2f59ec92020-09-02 16:23:38 +080033 "android/soong/bpf"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070034 "android/soong/cc"
35 prebuilt_etc "android/soong/etc"
Jiyong Park12a719c2021-01-07 15:31:24 +090036 "android/soong/filesystem"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070037 "android/soong/java"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090038 "android/soong/multitree"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070039 "android/soong/python"
Jiyong Park99644e92020-11-17 22:21:02 +090040 "android/soong/rust"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070041 "android/soong/sh"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090042)
43
Jiyong Park8e6d52f2020-11-19 14:37:47 +090044func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000045 registerApexBuildComponents(android.InitRegistrationContext)
46}
Jiyong Park8e6d52f2020-11-19 14:37:47 +090047
Paul Duffin667893c2021-03-09 22:34:13 +000048func registerApexBuildComponents(ctx android.RegistrationContext) {
49 ctx.RegisterModuleType("apex", BundleFactory)
50 ctx.RegisterModuleType("apex_test", testApexBundleFactory)
51 ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
52 ctx.RegisterModuleType("apex_defaults", defaultsFactory)
53 ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
Wei Li1c66fc72022-05-09 23:59:14 -070054 ctx.RegisterModuleType("override_apex", OverrideApexFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000055 ctx.RegisterModuleType("apex_set", apexSetFactory)
56
Paul Duffin5dda3e32021-05-05 14:13:27 +010057 ctx.PreArchMutators(registerPreArchMutators)
Paul Duffin667893c2021-03-09 22:34:13 +000058 ctx.PreDepsMutators(RegisterPreDepsMutators)
59 ctx.PostDepsMutators(RegisterPostDepsMutators)
Jiyong Park8e6d52f2020-11-19 14:37:47 +090060}
61
Paul Duffin5dda3e32021-05-05 14:13:27 +010062func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
63 ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
64}
65
Jiyong Park8e6d52f2020-11-19 14:37:47 +090066func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
67 ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
68 ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
69}
70
71func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
Paul Duffin949abc02020-12-08 10:34:30 +000072 ctx.TopDown("apex_info", apexInfoMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090073 ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
74 ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
75 ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
Paul Duffin28bf7ee2021-05-12 16:41:35 +010076 // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
77 // it should create a platform variant.
78 ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090079 ctx.BottomUp("apex", apexMutator).Parallel()
80 ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
81 ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
Spandan Das66773252022-01-15 00:23:18 +000082 // Register after apex_info mutator so that it can use ApexVariationName
83 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090084}
85
86type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090087 // Json manifest file describing meta info of this APEX bundle. Refer to
88 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090089 Manifest *string `android:"path"`
90
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090091 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
92 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090093 AndroidManifest *string `android:"path"`
94
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090095 // Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
96 // device (/apex/<apex_name>). If unspecified, follows the name property.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090097 Apex_name *string
98
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090099 // Determines the file contexts file for setting the security contexts to files in this APEX
100 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
101 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900102 File_contexts *string `android:"path"`
103
Jiyong Park038e8522021-12-13 23:56:35 +0900104 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
105 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
106 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
107 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
108 // capability. If this property is not set, or a file is missing in the file, default config
109 // is used.
110 Canned_fs_config *string `android:"path"`
111
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900112 ApexNativeDependencies
113
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900114 Multilib apexMultilibProperties
115
Sundong Ahn80c04892021-11-23 00:57:19 +0000116 // List of sh binaries that are embedded inside this APEX bundle.
117 Sh_binaries []string
118
Paul Duffin3abc1742021-03-15 19:32:23 +0000119 // List of platform_compat_config files that are embedded inside this APEX bundle.
120 Compat_configs []string
121
Jiyong Park12a719c2021-01-07 15:31:24 +0900122 // List of filesystem images that are embedded inside this APEX bundle.
123 Filesystems []string
124
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900125 // The minimum SDK version that this APEX must support at minimum. This is usually set to
126 // the SDK version that the APEX was first introduced.
127 Min_sdk_version *string
128
129 // Whether this APEX is considered updatable or not. When set to true, this will enforce
130 // additional rules for making sure that the APEX is truly updatable. To be updatable,
131 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000132 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900133 Updatable *bool
134
Jiyong Parkf4020582021-11-29 12:37:10 +0900135 // Marks that this APEX is designed to be updatable in the future, although it's not
136 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
137 // updatable APEXes. Currently, this disables the size optimization, so that the size of
138 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
139 // false.
140 Future_updatable *bool
141
Jiyong Park1bc84122021-06-22 20:23:05 +0900142 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
143 // false`. Default is false.
144 Platform_apis *bool
145
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900146 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
147 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900148 Installable *bool
149
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900150 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
151 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
152 Use_vndk_as_stable *bool
153
Daniel Norman6cfb37af2021-11-16 20:28:29 +0000154 // Whether this is multi-installed APEX should skip installing symbol files.
155 // Multi-installed APEXes share the same apex_name and are installed at the same time.
156 // Default is false.
157 //
158 // Should be set to true for all multi-installed APEXes except the singular
159 // default version within the multi-installed group.
160 // Only the default version can install symbol files in $(PRODUCT_OUT}/apex,
161 // or else conflicting build rules may be created.
162 Multi_install_skip_symbol_files *bool
163
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900164 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
165 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
166 // container. When set to zip, contents are stored in a zip container directly. This type is
167 // mostly for host-side debugging. When set to both, the two types are both built. Default
168 // is 'image'.
169 Payload_type *string
170
Huang Jianan13cac632021-08-02 15:02:17 +0800171 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
172 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900173 Payload_fs_type *string
174
175 // For telling the APEX to ignore special handling for system libraries such as bionic.
176 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900177 Ignore_system_library_special_case *bool
178
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100179 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100180 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100181 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900182
183 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
184 // used in tests.
185 Test_only_unsigned_payload *bool
186
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000187 // Whenever apex should be compressed, regardless of product flag used. Should be only
188 // used in tests.
189 Test_only_force_compression *bool
190
Jooyung Han09c11ad2021-10-27 03:45:31 +0900191 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
192 // with the tool to sign payload contents.
193 Custom_sign_tool *string
194
Dennis Shenaf41bc12022-08-03 16:46:43 +0000195 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
196 // in a special way that include the digest of the lib file under /lib(64)?
197 Dynamic_common_lib_apex *bool
198
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100199 // Canonical name of this APEX bundle. Used to determine the path to the
200 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
201 // apex mutator variations. For override_apex modules, this is the name of the
202 // overridden base module.
203 ApexVariationName string `blueprint:"mutated"`
204
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900205 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900206
207 // List of sanitizer names that this APEX is enabled for
208 SanitizerNames []string `blueprint:"mutated"`
209
210 PreventInstall bool `blueprint:"mutated"`
211
212 HideFromMake bool `blueprint:"mutated"`
213
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900214 // Internal package method for this APEX. When payload_type is image, this can be either
215 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
216 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900217 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900218}
219
220type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900221 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900222 Native_shared_libs []string
223
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900224 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900225 Jni_libs []string
226
Jiyong Park99644e92020-11-17 22:21:02 +0900227 // List of rust dyn libraries
228 Rust_dyn_libs []string
229
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900230 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900231 Binaries []string
232
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900233 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900234 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900235
236 // List of filesystem images that are embedded inside this APEX bundle.
237 Filesystems []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900238}
239
240type apexMultilibProperties struct {
241 // Native dependencies whose compile_multilib is "first"
242 First ApexNativeDependencies
243
244 // Native dependencies whose compile_multilib is "both"
245 Both ApexNativeDependencies
246
247 // Native dependencies whose compile_multilib is "prefer32"
248 Prefer32 ApexNativeDependencies
249
250 // Native dependencies whose compile_multilib is "32"
251 Lib32 ApexNativeDependencies
252
253 // Native dependencies whose compile_multilib is "64"
254 Lib64 ApexNativeDependencies
255}
256
257type apexTargetBundleProperties struct {
258 Target struct {
259 // Multilib properties only for android.
260 Android struct {
261 Multilib apexMultilibProperties
262 }
263
264 // Multilib properties only for host.
265 Host struct {
266 Multilib apexMultilibProperties
267 }
268
269 // Multilib properties only for host linux_bionic.
270 Linux_bionic struct {
271 Multilib apexMultilibProperties
272 }
273
274 // Multilib properties only for host linux_glibc.
275 Linux_glibc struct {
276 Multilib apexMultilibProperties
277 }
278 }
279}
280
Jiyong Park59140302020-12-14 18:44:04 +0900281type apexArchBundleProperties struct {
282 Arch struct {
283 Arm struct {
284 ApexNativeDependencies
285 }
286 Arm64 struct {
287 ApexNativeDependencies
288 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700289 Riscv64 struct {
290 ApexNativeDependencies
291 }
Jiyong Park59140302020-12-14 18:44:04 +0900292 X86 struct {
293 ApexNativeDependencies
294 }
295 X86_64 struct {
296 ApexNativeDependencies
297 }
298 }
299}
300
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900301// These properties can be used in override_apex to override the corresponding properties in the
302// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900303type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900304 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900305 Apps []string
306
Daniel Norman5a3ce132021-08-26 15:44:43 -0700307 // List of prebuilt files that are embedded inside this APEX bundle.
308 Prebuilts []string
309
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900310 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900311 Rros []string
312
markchien7c803b82021-08-26 22:10:06 +0800313 // List of BPF programs inside this APEX bundle.
314 Bpfs []string
315
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900316 // List of bootclasspath fragments that are embedded inside this APEX bundle.
317 Bootclasspath_fragments []string
318
319 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
320 Systemserverclasspath_fragments []string
321
322 // List of java libraries that are embedded inside this APEX bundle.
323 Java_libs []string
324
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900325 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
326 // Soong). This does not completely prevent installation of the overridden binaries, but if
327 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
328 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900329 Overrides []string
330
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900331 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900332 Logging_parent string
333
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900334 // Apex Container package name. Override value for attribute package:name in
335 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900336 Package_name string
337
338 // A txt file containing list of files that are allowed to be included in this APEX.
339 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700340
341 // Name of the apex_key module that provides the private key to sign this APEX bundle.
342 Key *string
343
344 // Specifies the certificate and the private key to sign the zip container of this APEX. If
345 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
346 // as the certificate and the private key, respectively. If this is ":module", then the
347 // certificate and the private key are provided from the android_app_certificate module
348 // named "module".
349 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400350
351 // Whether this APEX can be compressed or not. Setting this property to false means this
352 // APEX will never be compressed. When set to true, APEX will be compressed if other
353 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
354 // Default: false.
355 Compressible *bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900356}
357
358type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900359 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900360 android.ModuleBase
361 android.DefaultableModuleBase
362 android.OverridableModuleBase
363 android.SdkBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400364 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900365 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900366
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900367 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900368 properties apexBundleProperties
369 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900370 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900371 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900372 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900373
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900374 ///////////////////////////////////////////////////////////////////////////////////////////
375 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900376
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900377 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800378 publicKeyFile android.Path
379 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900380
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900381 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800382 containerCertificateFile android.Path
383 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900384
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900385 // Flags for special variants of APEX
386 testApex bool
387 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900388
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900389 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
390 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900391 primaryApexType bool
392
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900393 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900394 suffix string
395
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900396 // File system type of apex_payload.img
397 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900398
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900399 // Whether to create symlink to the system file instead of having a file inside the apex or
400 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900401 linkToSystemLib bool
402
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900403 // List of files to be included in this APEX. This is filled in the first part of
404 // GenerateAndroidBuildActions.
405 filesInfo []apexFile
406
407 // List of other module names that should be installed when this APEX gets installed.
408 requiredDeps []string
409
410 ///////////////////////////////////////////////////////////////////////////////////////////
411 // Outputs (final and intermediates)
412
413 // Processed apex manifest in JSONson format (for Q)
414 manifestJsonOut android.WritablePath
415
416 // Processed apex manifest in PB format (for R+)
417 manifestPbOut android.WritablePath
418
419 // Processed file_contexts files
420 fileContexts android.WritablePath
421
Bob Badourde6a0872022-04-01 18:00:00 +0000422 // Path to notice file in html.gz format.
423 htmlGzNotice android.WritablePath
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900424
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900425 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900426 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900427 outputFile android.WritablePath
428
Jooyung Hana6d36672022-02-24 13:58:07 +0900429 // The built uncompressed .apex file.
430 outputApexFile android.WritablePath
431
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900432 // The built APEX file in app bundle format. This file is not directly installed to the
433 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
434 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
435 // system) to be merged into a single app bundle file that Play accepts. See
436 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
437 bundleModuleFile android.WritablePath
438
Colin Cross6340ea52021-11-04 12:01:18 -0700439 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900440 installDir android.InstallPath
441
Colin Cross6340ea52021-11-04 12:01:18 -0700442 // Path where this APEX was installed.
443 installedFile android.InstallPath
444
445 // Installed locations of symlinks for backward compatibility.
446 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900447
448 // Text file having the list of individual files that are included in this APEX. Used for
449 // debugging purpose.
450 installedFilesFile android.WritablePath
451
452 // List of module names that this APEX is including (to be shown via *-deps-info target).
453 // Used for debugging purpose.
454 android.ApexBundleDepsInfo
455
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900456 // Optional list of lint report zip files for apexes that contain java or app modules
457 lintReports android.Paths
458
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900459 prebuiltFileToDelete string
sophiezc80a2b32020-11-12 16:39:19 +0000460
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000461 isCompressed bool
462
sophiezc80a2b32020-11-12 16:39:19 +0000463 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700464 nativeApisUsedByModuleFile android.ModuleOutPath
465 nativeApisBackedByModuleFile android.ModuleOutPath
466 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800467
468 // Collect the module directory for IDE info in java/jdeps.go.
469 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900470}
471
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900472// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900473type apexFileClass int
474
Jooyung Han72bd2f82019-10-23 16:46:38 +0900475const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900476 app apexFileClass = iota
477 appSet
478 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900479 goBinary
480 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900481 nativeExecutable
482 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900483 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900484 pyBinary
485 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900486)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900487
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900488// apexFile represents a file in an APEX bundle. This is created during the first half of
489// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
490// of the function, this is used to create commands that copies the files into a staging directory,
491// where they are packaged into the APEX file. This struct is also used for creating Make modules
492// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900493type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900494 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000495 builtFile android.Path
496 installDir string
497 customStem string
498 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900499
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900500 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
501 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
502 // suffix>]
503 androidMkModuleName string // becomes LOCAL_MODULE
504 class apexFileClass // becomes LOCAL_MODULE_CLASS
505 moduleDir string // becomes LOCAL_PATH
506 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
507 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
508 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
509 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900510
511 jacocoReportClassesFile android.Path // only for javalibs and apps
512 lintDepSets java.LintDepSets // only for javalibs and apps
513 certificate java.Certificate // only for apps
514 overriddenPackageName string // only for apps
515
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900516 transitiveDep bool
517 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900518
Jiyong Park57621b22021-01-20 20:33:11 +0900519 multilib string
520
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900521 // TODO(jiyong): remove this
522 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900523}
524
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900525// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900526func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
527 ret := apexFile{
528 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900529 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900530 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900531 class: class,
532 module: module,
533 }
534 if module != nil {
535 ret.moduleDir = ctx.OtherModuleDir(module)
536 ret.requiredModuleNames = module.RequiredModuleNames()
537 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
538 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900539 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900540 }
541 return ret
542}
543
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900544func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900545 return af.builtFile != nil && af.builtFile.String() != ""
546}
547
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900548// apexRelativePath returns the relative path of the given path from the install directory of this
549// apexFile.
550// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900551func (af *apexFile) apexRelativePath(path string) string {
552 return filepath.Join(af.installDir, path)
553}
554
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900555// path returns path of this apex file relative to the APEX root
556func (af *apexFile) path() string {
557 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900558}
559
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900560// stem returns the base filename of this apex file
561func (af *apexFile) stem() string {
562 if af.customStem != "" {
563 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900564 }
565 return af.builtFile.Base()
566}
567
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900568// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
569func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900570 var ret []string
571 for _, symlink := range af.symlinks {
572 ret = append(ret, af.apexRelativePath(symlink))
573 }
574 return ret
575}
576
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900577// availableToPlatform tests whether this apexFile is from a module that can be installed to the
578// platform.
579func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900580 if af.module == nil {
581 return false
582 }
583 if am, ok := af.module.(android.ApexModule); ok {
584 return am.AvailableFor(android.AvailableToPlatform)
585 }
586 return false
587}
588
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900589////////////////////////////////////////////////////////////////////////////////////////////////////
590// Mutators
591//
592// Brief description about mutators for APEX. The following three mutators are the most important
593// ones.
594//
595// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
596// to the (direct) dependencies of this APEX bundle.
597//
Paul Duffin949abc02020-12-08 10:34:30 +0000598// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900599// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
600// modules are marked as being included in the APEX via BuildForApex().
601//
Paul Duffin949abc02020-12-08 10:34:30 +0000602// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
603// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900604
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900605type dependencyTag struct {
606 blueprint.BaseDependencyTag
607 name string
608
609 // Determines if the dependent will be part of the APEX payload. Can be false for the
610 // dependencies to the signing key module, etc.
611 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000612
613 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
614 // replacement. This is needed because some prebuilt modules do not provide all the information
615 // needed by the apex.
616 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000617
618 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
619 // also be added as exported members of that SDK.
620 memberType android.SdkMemberType
621}
622
623func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
624 return d.memberType
625}
626
627func (d *dependencyTag) ExportMember() bool {
628 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900629}
630
Paul Duffin520917a2022-05-13 13:01:59 +0000631func (d *dependencyTag) String() string {
632 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
633}
634
635func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000636 return !d.sourceOnly
637}
638
639var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000640var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000641
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900642var (
Paul Duffin520917a2022-05-13 13:01:59 +0000643 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
644 bpfTag = &dependencyTag{name: "bpf", payload: true}
645 certificateTag = &dependencyTag{name: "certificate"}
646 executableTag = &dependencyTag{name: "executable", payload: true}
647 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000648 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
649 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000650 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000651 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
652 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
653 keyTag = &dependencyTag{name: "key"}
654 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
655 rroTag = &dependencyTag{name: "rro", payload: true}
656 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
657 testForTag = &dependencyTag{name: "test for"}
658 testTag = &dependencyTag{name: "test", payload: true}
659 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900660)
661
662// TODO(jiyong): shorten this function signature
663func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900664 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900665 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900666 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900667
668 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900669 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900670 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
671 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900672 }
673
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900674 // Use *FarVariation* to be able to depend on modules having conflicting variations with
675 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
676 // 'arm' or 'arm64' for native shared libs.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900677 ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900678 ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900679 ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
680 ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
Jiyong Park99644e92020-11-17 22:21:02 +0900681 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
Jiyong Park06711462021-02-15 17:54:43 +0900682 ctx.AddFarVariationDependencies(target.Variations(), fsTag, nativeModules.Filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900683}
684
685func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900686 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900687 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
688 } else {
689 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
690 if ctx.Os().Bionic() {
691 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
692 } else {
693 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
694 }
695 }
696}
697
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900698// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
699// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
700func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
701 deviceConfig := ctx.DeviceConfig()
702 if a.vndkApex {
703 return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900704 }
705
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900706 var prefix string
707 var vndkVersion string
708 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000709 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900710 prefix = cc.VendorVariationPrefix
711 vndkVersion = deviceConfig.VndkVersion()
712 } else if a.ProductSpecific() {
713 prefix = cc.ProductVariationPrefix
714 vndkVersion = deviceConfig.ProductVndkVersion()
715 }
716 }
717 if vndkVersion == "current" {
718 vndkVersion = deviceConfig.PlatformVndkVersion()
719 }
720 if vndkVersion != "" {
721 return prefix + vndkVersion
722 }
723
724 return android.CoreVariation // The usual case
725}
726
727func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900728 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
729 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
730 // each target os/architectures, appropriate dependencies are selected by their
731 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900732 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900733 imageVariation := a.getImageVariation(ctx)
734
735 a.combineProperties(ctx)
736
737 has32BitTarget := false
738 for _, target := range targets {
739 if target.Arch.ArchType.Multilib == "lib32" {
740 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000741 }
742 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900743 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900744 // Don't include artifacts for the host cross targets because there is no way for us
745 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900746 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900747 continue
748 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000749
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900750 var depsList []ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000751
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900752 // Add native modules targeting both ABIs. When multilib.* is omitted for
753 // native_shared_libs/jni_libs/tests, it implies multilib.both
754 depsList = append(depsList, a.properties.Multilib.Both)
755 depsList = append(depsList, ApexNativeDependencies{
756 Native_shared_libs: a.properties.Native_shared_libs,
757 Tests: a.properties.Tests,
758 Jni_libs: a.properties.Jni_libs,
759 Binaries: nil,
760 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900761
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900762 // Add native modules targeting the first ABI When multilib.* is omitted for
763 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900764 isPrimaryAbi := i == 0
765 if isPrimaryAbi {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900766 depsList = append(depsList, a.properties.Multilib.First)
767 depsList = append(depsList, ApexNativeDependencies{
768 Native_shared_libs: nil,
769 Tests: nil,
770 Jni_libs: nil,
771 Binaries: a.properties.Binaries,
772 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900773 }
774
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900775 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900776 switch target.Arch.ArchType.Multilib {
777 case "lib32":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900778 depsList = append(depsList, a.properties.Multilib.Lib32)
779 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900780 case "lib64":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900781 depsList = append(depsList, a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900782 if !has32BitTarget {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900783 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900784 }
785 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900786
Jiyong Park59140302020-12-14 18:44:04 +0900787 // Add native modules targeting a specific arch variant
788 switch target.Arch.ArchType {
789 case android.Arm:
790 depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
791 case android.Arm64:
792 depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700793 case android.Riscv64:
794 depsList = append(depsList, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900795 case android.X86:
796 depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
797 case android.X86_64:
798 depsList = append(depsList, a.archProperties.Arch.X86_64.ApexNativeDependencies)
799 default:
800 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
801 }
802
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900803 for _, d := range depsList {
804 addDependenciesForNativeModules(ctx, d, target, imageVariation)
805 }
Sundong Ahn80c04892021-11-23 00:57:19 +0000806 ctx.AddFarVariationDependencies([]blueprint.Variation{
807 {Mutator: "os", Variation: target.OsVariation()},
808 {Mutator: "arch", Variation: target.ArchVariation()},
809 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900810 }
811
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900812 // Common-arch dependencies come next
813 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900814 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000815 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100816}
817
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900818// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900819func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
820 if a.overridableProperties.Allowed_files != nil {
821 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100822 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900823
824 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
825 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800826 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900827 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900828 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
829 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
830 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700831 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
832 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
833 // regardless of the TARGET_PREFER_* setting. See b/144532908
834 arches := ctx.DeviceConfig().Arches()
835 if len(arches) != 0 {
836 archForPrebuiltEtc := arches[0]
837 for _, arch := range arches {
838 // Prefer 64-bit arch if there is any
839 if arch.ArchType.Multilib == "lib64" {
840 archForPrebuiltEtc = arch
841 break
842 }
843 }
844 ctx.AddFarVariationDependencies([]blueprint.Variation{
845 {Mutator: "os", Variation: ctx.Os().String()},
846 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
847 }, prebuiltTag, prebuilts...)
848 }
849 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700850
851 // Dependencies for signing
852 if String(a.overridableProperties.Key) == "" {
853 ctx.PropertyErrorf("key", "missing")
854 return
855 }
856 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
857
858 cert := android.SrcIsModule(a.getCertString(ctx))
859 if cert != "" {
860 ctx.AddDependency(ctx.Module(), certificateTag, cert)
861 // empty cert is not an error. Cert and private keys will be directly found under
862 // PRODUCT_DEFAULT_DEV_CERTIFICATE
863 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100864}
865
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900866type ApexBundleInfo struct {
867 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100868}
869
Paul Duffin949abc02020-12-08 10:34:30 +0000870var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900871
Paul Duffina7d6a892020-12-07 17:39:59 +0000872var _ ApexInfoMutator = (*apexBundle)(nil)
873
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100874func (a *apexBundle) ApexVariationName() string {
875 return a.properties.ApexVariationName
876}
877
Paul Duffina7d6a892020-12-07 17:39:59 +0000878// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900879// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
880// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
881// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
882// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000883//
884// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
885// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
886// The apexMutator uses that list to create module variants for the apexes to which it belongs.
887// The relationship between module variants and apexes is not one-to-one as variants will be
888// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000889func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900890
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900891 // The VNDK APEX is special. For the APEX, the membership is described in a very different
892 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
893 // libraries are self-identified by their vndk.enabled properties. There is no need to run
894 // this mutator for the APEX as nothing will be collected. So, let's return fast.
895 if a.vndkApex {
896 return
897 }
898
899 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
900 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
901 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
902 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
903 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900904 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
905 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900906 if proptools.Bool(a.properties.Use_vndk_as_stable) {
907 if !useVndk {
908 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
909 }
910 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
911 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
912 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
913 }
914 })
915 if mctx.Failed() {
916 return
917 }
Jooyung Handf78e212020-07-22 15:54:47 +0900918 }
919
Colin Cross56a83212020-09-15 18:30:11 -0700920 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900921 am, ok := child.(android.ApexModule)
922 if !ok || !am.CanHaveApexVariants() {
923 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900924 }
Paul Duffin573989d2021-03-17 13:25:29 +0000925 depTag := mctx.OtherModuleDependencyTag(child)
926
927 // Check to see if the tag always requires that the child module has an apex variant for every
928 // apex variant of the parent module. If it does not then it is still possible for something
929 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
930 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
931 return true
932 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000933 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900934 return false
935 }
Jooyung Handf78e212020-07-22 15:54:47 +0900936 if excludeVndkLibs {
937 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
938 return false
939 }
940 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900941 // By default, all the transitive dependencies are collected, unless filtered out
942 // above.
Colin Cross56a83212020-09-15 18:30:11 -0700943 return true
944 }
945
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900946 // Records whether a certain module is included in this apexBundle via direct dependency or
947 // inndirect dependency.
948 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -0700949 mctx.WalkDeps(func(child, parent android.Module) bool {
950 if !continueApexDepsWalk(child, parent) {
951 return false
952 }
Jooyung Han698dd9f2020-07-22 15:17:19 +0900953 // If the parent is apexBundle, this child is directly depended.
954 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900955 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -0700956 contents[depName] = contents[depName].Add(directDep)
957 return true
958 })
959
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900960 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +0900961 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -0700962 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
963 Contents: apexContents,
964 })
965
Jooyung Haned124c32021-01-26 11:43:46 +0900966 minSdkVersion := a.minSdkVersion(mctx)
967 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
968 if minSdkVersion.IsNone() {
969 minSdkVersion = android.FutureApiLevel
970 }
971
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900972 // This is the main part of this mutator. Mark the collected dependencies that they need to
973 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +0900974
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100975 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
976 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -0700977 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100978 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +0900979 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -0700980 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +0900981 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100982 InApexVariants: []string{apexVariationName},
983 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -0700984 ApexContents: []*android.ApexContents{apexContents},
985 }
Colin Cross56a83212020-09-15 18:30:11 -0700986 mctx.WalkDeps(func(child, parent android.Module) bool {
987 if !continueApexDepsWalk(child, parent) {
988 return false
989 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900990 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +0900991 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +0900992 })
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900993}
994
Paul Duffina7d6a892020-12-07 17:39:59 +0000995type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100996 // ApexVariationName returns the name of the APEX variation to use in the apex
997 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
998 ApexVariationName() string
999
Paul Duffina7d6a892020-12-07 17:39:59 +00001000 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1001 // depended upon by an apex and which require an apex specific variant.
1002 ApexInfoMutator(android.TopDownMutatorContext)
1003}
1004
1005// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1006// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001007// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001008func apexInfoMutator(mctx android.TopDownMutatorContext) {
1009 if !mctx.Module().Enabled() {
1010 return
1011 }
1012
1013 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1014 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001015 }
Spandan Das42e89502022-05-06 22:12:55 +00001016 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001017}
1018
Spandan Das66773252022-01-15 00:23:18 +00001019// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1020// This check is enforced for updatable modules
1021func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1022 if !mctx.Module().Enabled() {
1023 return
1024 }
Spandan Das08c911f2022-01-21 22:07:26 +00001025 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001026 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001027 // b/208656169 Do not propagate strict updatability linting to libcore/
1028 // These libs are available on the classpath during compilation
1029 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1030 // Only skip libraries defined in libcore root, not subdirectories
1031 if mctx.OtherModuleDir(child) == "libcore" {
1032 // Do not traverse transitive deps of libcore/ libs
1033 return false
1034 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001035 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1036 return false
1037 }
Spandan Das66773252022-01-15 00:23:18 +00001038 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1039 lintable.SetStrictUpdatabilityLinting(true)
1040 }
1041 // visit transitive deps
1042 return true
1043 })
1044 }
1045}
1046
Spandan Das42e89502022-05-06 22:12:55 +00001047// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1048func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1049 if !mctx.Module().Enabled() {
1050 return
1051 }
1052 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1053 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1054 mctx.VisitDirectDeps(func(module android.Module) {
1055 // ignore android_test_app
1056 if app, ok := module.(*java.AndroidApp); ok {
1057 app.SetUpdatable(true)
1058 }
1059 })
1060 }
1061}
1062
Spandan Das08c911f2022-01-21 22:07:26 +00001063// TODO: b/215736885 Whittle the denylist
1064// Transitive deps of certain mainline modules baseline NewApi errors
1065// Skip these mainline modules for now
1066var (
1067 skipStrictUpdatabilityLintAllowlist = []string{
1068 "com.android.art",
1069 "com.android.art.debug",
1070 "com.android.conscrypt",
1071 "com.android.media",
1072 // test apexes
1073 "test_com.android.art",
1074 "test_com.android.conscrypt",
1075 "test_com.android.media",
1076 "test_jitzygote_com.android.art",
1077 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001078
1079 // TODO: b/215736885 Remove this list
1080 skipLintJavalibAllowlist = []string{
1081 "conscrypt.module.platform.api.stubs",
1082 "conscrypt.module.public.api.stubs",
1083 "conscrypt.module.public.api.stubs.system",
1084 "conscrypt.module.public.api.stubs.module_lib",
1085 "framework-media.stubs",
1086 "framework-media.stubs.system",
1087 "framework-media.stubs.module_lib",
1088 }
Spandan Das08c911f2022-01-21 22:07:26 +00001089)
1090
1091func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1092 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1093}
1094
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001095// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1096// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1097// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001098func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1099 if !mctx.Module().Enabled() {
1100 return
1101 }
1102 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001103 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1104 }
1105}
1106
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001107// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1108// the apex in order to retrieve its contents later.
1109// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001110func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1111 if !mctx.Module().Enabled() {
1112 return
1113 }
Colin Cross56a83212020-09-15 18:30:11 -07001114 if am, ok := mctx.Module().(android.ApexModule); ok {
1115 if testFor := am.TestFor(); len(testFor) > 0 {
1116 mctx.AddFarVariationDependencies([]blueprint.Variation{
1117 {Mutator: "os", Variation: am.Target().OsVariation()},
1118 {"arch", "common"},
1119 }, testForTag, testFor...)
1120 }
1121 }
1122}
1123
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001124// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001125func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1126 if !mctx.Module().Enabled() {
1127 return
1128 }
Colin Cross56a83212020-09-15 18:30:11 -07001129 if _, ok := mctx.Module().(android.ApexModule); ok {
1130 var contents []*android.ApexContents
1131 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1132 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1133 contents = append(contents, abInfo.Contents)
1134 }
1135 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1136 ApexContents: contents,
1137 })
Colin Crossaede88c2020-08-11 12:17:01 -07001138 }
1139}
1140
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001141// markPlatformAvailability marks whether or not a module can be available to platform. A module
1142// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1143// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1144// be) available to platform
1145// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001146func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1147 // Host and recovery are not considered as platform
1148 if mctx.Host() || mctx.Module().InstallInRecovery() {
1149 return
1150 }
1151
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001152 am, ok := mctx.Module().(android.ApexModule)
1153 if !ok {
1154 return
1155 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001156
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001157 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001158
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001159 // If any of the dep is not available to platform, this module is also considered as being
1160 // not available to platform even if it has "//apex_available:platform"
1161 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001162 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001163 // if the dependency crosses apex boundary, don't consider it
1164 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001165 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001166 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1167 availableToPlatform = false
1168 // TODO(b/154889534) trigger an error when 'am' has
1169 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001170 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001171 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001172
Paul Duffinb5769c12021-05-12 16:16:51 +01001173 // Exception 1: check to see if the module always requires it.
1174 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001175 availableToPlatform = true
1176 }
1177
1178 // Exception 2: bootstrap bionic libraries are also always available to platform
1179 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1180 availableToPlatform = true
1181 }
1182
1183 if !availableToPlatform {
1184 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001185 }
1186}
1187
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001188// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001189// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001190func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001191 if !mctx.Module().Enabled() {
1192 return
1193 }
Colin Cross56a83212020-09-15 18:30:11 -07001194
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001195 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001196 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001197 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001198 return
1199 }
1200
1201 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001202 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1203 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001204 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001205 if strings.HasPrefix(apexBundleName, "com.android.art") {
1206 // Create an alias from the platform variant. This is done to make
1207 // test_for dependencies work for modules that are split by the APEX
1208 // mutator, since test_for dependencies always go to the platform variant.
1209 // This doesn't happen for normal APEXes that are disjunct, so only do
1210 // this for the overlapping ART APEXes.
1211 // TODO(b/183882457): Remove this if the test_for functionality is
1212 // refactored to depend on the proper APEX variants instead of platform.
1213 mctx.CreateAliasVariation("", apexBundleName)
1214 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001215 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1216 apexBundleName := o.GetOverriddenModuleName()
1217 if apexBundleName == "" {
1218 mctx.ModuleErrorf("base property is not set")
1219 return
1220 }
1221 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001222 if strings.HasPrefix(apexBundleName, "com.android.art") {
1223 // TODO(b/183882457): See note for CreateAliasVariation above.
1224 mctx.CreateAliasVariation("", apexBundleName)
1225 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001226 }
1227}
Sundong Ahne9b55722019-09-06 17:37:42 +09001228
Paul Duffin6717d882021-06-15 19:09:41 +01001229// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1230// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001231func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001232 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001233 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001234 return !a.vndkApex
1235 }
1236
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001237 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001238}
1239
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001240// See android.UpdateDirectlyInAnyApex
1241// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001242func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1243 if !mctx.Module().Enabled() {
1244 return
1245 }
1246 if am, ok := mctx.Module().(android.ApexModule); ok {
1247 android.UpdateDirectlyInAnyApex(mctx, am)
1248 }
1249}
1250
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001251// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001252type apexPackaging int
1253
1254const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001255 // imageApex is a packaging method where contents are included in a filesystem image which
1256 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001257 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001258
1259 // zipApex is a packaging method where contents are directly included in the zip container.
1260 // This is used for host-side testing - because the contents are easily accessible by
1261 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001262 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001263
1264 // flattendApex is a packaging method where contents are not included in the APEX file, but
1265 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1266 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001267 flattenedApex
1268)
1269
1270const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001271 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001272 imageApexSuffix = ".apex"
1273 imageCapexSuffix = ".capex"
1274 zipApexSuffix = ".zipapex"
1275 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001276
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001277 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001278 imageApexType = "image"
1279 zipApexType = "zip"
1280 flattenedApexType = "flattened"
1281
Dan Willemsen47e1a752021-10-16 18:36:13 -07001282 ext4FsType = "ext4"
1283 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001284 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001285)
1286
1287// The suffix for the output "file", not the module
1288func (a apexPackaging) suffix() string {
1289 switch a {
1290 case imageApex:
1291 return imageApexSuffix
1292 case zipApex:
1293 return zipApexSuffix
1294 default:
1295 panic(fmt.Errorf("unknown APEX type %d", a))
1296 }
1297}
1298
1299func (a apexPackaging) name() string {
1300 switch a {
1301 case imageApex:
1302 return imageApexType
1303 case zipApex:
1304 return zipApexType
1305 default:
1306 panic(fmt.Errorf("unknown APEX type %d", a))
1307 }
1308}
1309
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001310// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1311// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001312func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001313 if !mctx.Module().Enabled() {
1314 return
1315 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001316 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001317 var variants []string
1318 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1319 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001320 // This is the normal case. Note that both image and flattend APEXes are
1321 // created. The image type is installed to the system partition, while the
1322 // flattened APEX is (optionally) installed to the system_ext partition.
1323 // This is mostly for GSI which has to support wide range of devices. If GSI
1324 // is installed on a newer (APEX-capable) device, the image APEX in the
1325 // system will be used. However, if the same GSI is installed on an old
1326 // device which can't support image APEX, the flattened APEX in the
1327 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001328 variants = append(variants, imageApexType, flattenedApexType)
1329 case "zip":
1330 variants = append(variants, zipApexType)
1331 case "both":
1332 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1333 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001334 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001335 return
1336 }
1337
1338 modules := mctx.CreateLocalVariations(variants...)
1339
1340 for i, v := range variants {
1341 switch v {
1342 case imageApexType:
1343 modules[i].(*apexBundle).properties.ApexType = imageApex
1344 case zipApexType:
1345 modules[i].(*apexBundle).properties.ApexType = zipApex
1346 case flattenedApexType:
1347 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001348 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001349 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001350 modules[i].(*apexBundle).MakeAsSystemExt()
1351 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001352 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001353 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001354 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001355 // payload_type is forcibly overridden to "image"
1356 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001357 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001358 }
1359}
1360
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001361var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001362
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001363// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001364func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001365 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001366 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001367 return true
1368}
1369
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001370var _ android.OutputFileProducer = (*apexBundle)(nil)
1371
1372// Implements android.OutputFileProducer
1373func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1374 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001375 case "", android.DefaultDistTag:
1376 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001377 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001378 case imageApexSuffix:
1379 // uncompressed one
1380 if a.outputApexFile != nil {
1381 return android.Paths{a.outputApexFile}, nil
1382 }
1383 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001384 default:
1385 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1386 }
1387}
1388
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001389var _ multitree.Exportable = (*apexBundle)(nil)
1390
1391func (a *apexBundle) Exportable() bool {
1392 if a.properties.ApexType == flattenedApex {
1393 return false
1394 }
1395 return true
1396}
1397
1398func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1399 ret := make(map[string]android.Paths)
1400 ret["apex"] = android.Paths{a.outputFile}
1401 return ret
1402}
1403
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001404var _ cc.Coverage = (*apexBundle)(nil)
1405
1406// Implements cc.Coverage
1407func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1408 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1409}
1410
1411// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001412func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001413 a.properties.PreventInstall = true
1414}
1415
1416// Implements cc.Coverage
1417func (a *apexBundle) HideFromMake() {
1418 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001419 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1420 // TODO(ccross): untangle these
1421 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001422}
1423
1424// Implements cc.Coverage
1425func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1426 a.properties.IsCoverageVariant = coverage
1427}
1428
1429// Implements cc.Coverage
1430func (a *apexBundle) EnableCoverageIfNeeded() {}
1431
1432var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1433
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001434// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001435func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001436 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001437}
1438
Jiyong Parkf4020582021-11-29 12:37:10 +09001439func (a *apexBundle) FutureUpdatable() bool {
1440 return proptools.BoolDefault(a.properties.Future_updatable, false)
1441}
1442
Jiyong Park1bc84122021-06-22 20:23:05 +09001443func (a *apexBundle) UsePlatformApis() bool {
1444 return proptools.BoolDefault(a.properties.Platform_apis, false)
1445}
1446
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001447// getCertString returns the name of the cert that should be used to sign this APEX. This is
1448// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001449func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001450 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001451 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1452 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1453 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001454 if a.vndkApex {
1455 moduleName = vndkApexName
1456 }
1457 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001458 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001459 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001460 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001461 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001462}
1463
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001464// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001465func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001466 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001467}
1468
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001469// See the generate_hashtree property
1470func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001471 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001472}
1473
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001474// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001475func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1476 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1477}
1478
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001479// See the test_only_force_compression property
1480func (a *apexBundle) testOnlyShouldForceCompression() bool {
1481 return proptools.Bool(a.properties.Test_only_force_compression)
1482}
1483
Dennis Shenaf41bc12022-08-03 16:46:43 +00001484// See the dynamic_common_lib_apex property
1485func (a *apexBundle) dynamic_common_lib_apex() bool {
1486 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1487}
1488
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001489// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1490// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1491// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001492
Jiyong Parkf97782b2019-02-13 20:28:58 +09001493func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1494 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1495 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1496 }
1497}
1498
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001499func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001500 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1501 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001502 }
1503
1504 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001505 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001506 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001507 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001508 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001509 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001510 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001511 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001512 }
1513 }
1514 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001515}
1516
Jooyung Han8ce8db92020-05-15 19:05:05 +09001517func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001518 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1519 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001520 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001521 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001522 for _, target := range ctx.MultiTargets() {
1523 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001524 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001525 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001526 Tests: nil,
1527 Jni_libs: nil,
1528 Binaries: nil,
1529 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001530 break
1531 }
1532 }
1533 }
1534}
1535
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001536// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1537// returned apexFile saves information about the Soong module that will be used for creating the
1538// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001539func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001540 // Decide the APEX-local directory by the multilib of the library In the future, we may
1541 // query this to the module.
1542 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001543 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001544 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001545 case "lib32":
1546 dirInApex = "lib"
1547 case "lib64":
1548 dirInApex = "lib64"
1549 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001550 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001551 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001552 }
Jooyung Han35155c42020-02-06 17:33:20 +09001553 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001554 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001555 // Special case for Bionic libs and other libs installed with them. This is to
1556 // prevent those libs from being included in the search path
1557 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1558 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1559 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1560 // will be loaded into the default linker namespace (aka "platform" namespace). If
1561 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1562 // be loaded again into the runtime linker namespace, which will result in double
1563 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001564 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001565 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001566
Colin Cross1d487152022-10-03 19:14:46 -07001567 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001568 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1569 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001570}
1571
Jiyong Park1833cef2019-12-13 13:28:36 +09001572func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001573 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001574 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001575 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001576 }
Jooyung Han35155c42020-02-06 17:33:20 +09001577 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001578 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001579 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1580 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001581 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001582 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001583 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001584}
1585
Jiyong Park99644e92020-11-17 22:21:02 +09001586func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1587 dirInApex := "bin"
1588 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1589 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1590 }
Colin Cross1d487152022-10-03 19:14:46 -07001591 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001592 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1593 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1594 return af
1595}
1596
1597func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1598 // Decide the APEX-local directory by the multilib of the library
1599 // In the future, we may query this to the module.
1600 var dirInApex string
1601 switch rustm.Arch().ArchType.Multilib {
1602 case "lib32":
1603 dirInApex = "lib"
1604 case "lib64":
1605 dirInApex = "lib64"
1606 }
1607 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1608 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1609 }
Colin Cross1d487152022-10-03 19:14:46 -07001610 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001611 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1612 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1613}
1614
Jiyong Park1833cef2019-12-13 13:28:36 +09001615func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001616 dirInApex := "bin"
1617 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001618 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001619}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001620
Jiyong Park1833cef2019-12-13 13:28:36 +09001621func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001622 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001623 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001624 // NB: Since go binaries are static we don't need the module for anything here, which is
1625 // good since the go tool is a blueprint.Module not an android.Module like we would
1626 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001627 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001628}
1629
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001630func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001631 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001632 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1633 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1634 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001635 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001636 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001637 af.symlinks = sh.Symlinks()
1638 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001639}
1640
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001641func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001642 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001643 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001644 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001645}
1646
atrost6e126252020-01-27 17:01:16 +00001647func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1648 dirInApex := filepath.Join("etc", config.SubDir())
1649 fileToCopy := config.CompatConfig()
1650 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1651}
1652
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001653// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1654// way.
1655type javaModule interface {
1656 android.Module
1657 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001658 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001659 JacocoReportClassesFile() android.Path
1660 LintDepSets() java.LintDepSets
1661 Stem() string
1662}
1663
1664var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001665var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001666var _ javaModule = (*java.SdkLibrary)(nil)
1667var _ javaModule = (*java.DexImport)(nil)
1668var _ javaModule = (*java.SdkLibraryImport)(nil)
1669
Paul Duffin190fdef2021-04-26 10:33:59 +01001670// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001671func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001672 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001673}
1674
1675// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1676func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001677 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001678 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001679 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1680 af.lintDepSets = module.LintDepSets()
1681 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001682 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1683 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1684 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1685 }
1686 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001687 return af
1688}
1689
1690// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1691// the same way.
1692type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001693 android.Module
1694 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001695 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001696 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001697 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001698 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001699 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001700 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001701}
1702
1703var _ androidApp = (*java.AndroidApp)(nil)
1704var _ androidApp = (*java.AndroidAppImport)(nil)
1705
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001706func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1707 buildId := ctx.Config().BuildId()
1708
1709 // The build ID is used as a suffix for a filename, so ensure that
1710 // the set of characters being used are sanitized.
1711 // - any word character: [a-zA-Z0-9_]
1712 // - dots: .
1713 // - dashes: -
1714 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1715 if !validRegex.MatchString(buildId) {
1716 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1717 }
1718 return buildId
1719}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001720
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001721func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001722 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001723 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001724 appDir = "priv-app"
1725 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001726
1727 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1728 // so that PackageManager correctly invalidates the existing installed apk
1729 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001730 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001731 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001732
Yo Chiange8128052020-07-23 20:09:18 +08001733 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001734 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001735 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001736 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001737
1738 if app, ok := aapp.(interface {
1739 OverriddenManifestPackageName() string
1740 }); ok {
1741 af.overriddenPackageName = app.OverriddenManifestPackageName()
1742 }
Jiyong Park618922e2020-01-08 13:35:43 +09001743 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001744}
1745
Jiyong Park69aeba92020-04-24 21:16:36 +09001746func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1747 rroDir := "overlay"
1748 dirInApex := filepath.Join(rroDir, rro.Theme())
1749 fileToCopy := rro.OutputFile()
1750 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1751 af.certificate = rro.Certificate()
1752
1753 if a, ok := rro.(interface {
1754 OverriddenManifestPackageName() string
1755 }); ok {
1756 af.overriddenPackageName = a.OverriddenManifestPackageName()
1757 }
1758 return af
1759}
1760
Ken Chenfad7f9d2021-11-10 22:02:57 +08001761func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1762 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001763 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1764}
1765
Jiyong Park12a719c2021-01-07 15:31:24 +09001766func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1767 dirInApex := filepath.Join("etc", "fs")
1768 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1769}
1770
Paul Duffin064b70c2020-11-02 17:32:38 +00001771// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001772// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1773// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1774// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001775func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001776 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001777 am, ok := child.(android.ApexModule)
1778 if !ok || !am.CanHaveApexVariants() {
1779 return false
1780 }
1781
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001782 // Filter-out unwanted depedendencies
1783 depTag := ctx.OtherModuleDependencyTag(child)
1784 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1785 return false
1786 }
Paul Duffin520917a2022-05-13 13:01:59 +00001787 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001788 return false
1789 }
1790
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001791 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001792 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001793
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001794 // Visit actually
1795 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001796 })
1797}
1798
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001799// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1800type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001801
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001802const (
1803 ext4 fsType = iota
1804 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001805 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001806)
Artur Satayev849f8442020-04-28 14:57:42 +01001807
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001808func (f fsType) string() string {
1809 switch f {
1810 case ext4:
1811 return ext4FsType
1812 case f2fs:
1813 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001814 case erofs:
1815 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001816 default:
1817 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001818 }
1819}
1820
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001821var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1822
1823func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1824 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1825}
1826
1827func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1828 bazelCtx := ctx.Config().BazelContext
1829 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1830}
1831
1832func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1833 if !a.commonBuildActions(ctx) {
1834 return
1835 }
1836
1837 a.setApexTypeAndSuffix(ctx)
1838 a.setPayloadFsType(ctx)
1839 a.setSystemLibLink(ctx)
1840
1841 if a.properties.ApexType != zipApex {
1842 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1843 }
1844
1845 bazelCtx := ctx.Config().BazelContext
1846 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1847 if err != nil {
1848 ctx.ModuleErrorf(err.Error())
1849 return
1850 }
1851 a.installDir = android.PathForModuleInstall(ctx, "apex")
1852 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1853 a.outputFile = a.outputApexFile
1854 a.setCompression(ctx)
1855
1856 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[0])
1857 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[1])
1858 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[0])
1859 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[1])
1860 apexType := a.properties.ApexType
1861 switch apexType {
1862 case imageApex:
1863 // TODO(asmundak): Bazel does not create these files yet.
1864 // b/190817312
1865 a.htmlGzNotice = android.PathForBazelOut(ctx, "NOTICE.html.gz")
1866 // b/239081457
1867 a.bundleModuleFile = android.PathForBazelOut(ctx, a.Name()+apexType.suffix()+"-base.zip")
1868 // b/239081455
1869 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.txt"))
1870 // b/239081456
1871 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_backing.txt"))
1872 // b/239084755
1873 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.xml"))
1874 installSuffix := imageApexSuffix
1875 if a.isCompressed {
1876 installSuffix = imageCapexSuffix
1877 }
1878 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1879 a.compatSymlinks.Paths()...)
1880 default:
1881 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1882 }
1883
1884 /*
1885 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1886 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1887 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1888 To find out what Soong build puts there, run:
1889 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1890 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1891 return a.depVisitor(&vctx, ctx, child, parent)
1892 })
1893 vctx.normalizeFileInfo()
1894 */
1895
1896}
1897
1898func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1899 if a.properties.ApexType != imageApex {
1900 a.isCompressed = false
1901 } else if a.testOnlyShouldForceCompression() {
1902 a.isCompressed = true
1903 } else {
1904 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1905 }
1906}
1907
1908func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1909 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1910 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1911 // the same library in the system partition, thus effectively sharing the same libraries
1912 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1913 // in the APEX.
1914 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1915
1916 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1917 // So we can't link them to /system/lib libs which are core variants.
1918 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1919 a.linkToSystemLib = false
1920 }
1921
1922 forced := ctx.Config().ForceApexSymlinkOptimization()
1923 updatable := a.Updatable() || a.FutureUpdatable()
1924
1925 // We don't need the optimization for updatable APEXes, as it might give false signal
1926 // to the system health when the APEXes are still bundled (b/149805758).
1927 if !forced && updatable && a.properties.ApexType == imageApex {
1928 a.linkToSystemLib = false
1929 }
1930
1931 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1932 if ctx.Host() {
1933 a.linkToSystemLib = false
1934 }
1935}
1936
1937func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1938 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
1939 case ext4FsType:
1940 a.payloadFsType = ext4
1941 case f2fsFsType:
1942 a.payloadFsType = f2fs
1943 case erofsFsType:
1944 a.payloadFsType = erofs
1945 default:
1946 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
1947 }
1948}
1949
1950func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
1951 // Set suffix and primaryApexType depending on the ApexType
1952 buildFlattenedAsDefault := ctx.Config().FlattenApex()
1953 switch a.properties.ApexType {
1954 case imageApex:
1955 if buildFlattenedAsDefault {
1956 a.suffix = imageApexSuffix
1957 } else {
1958 a.suffix = ""
1959 a.primaryApexType = true
1960
1961 if ctx.Config().InstallExtraFlattenedApexes() {
1962 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
1963 }
1964 }
1965 case zipApex:
1966 if proptools.String(a.properties.Payload_type) == "zip" {
1967 a.suffix = ""
1968 a.primaryApexType = true
1969 } else {
1970 a.suffix = zipApexSuffix
1971 }
1972 case flattenedApex:
1973 if buildFlattenedAsDefault {
1974 a.suffix = ""
1975 a.primaryApexType = true
1976 } else {
1977 a.suffix = flattenedSuffix
1978 }
1979 }
1980}
1981
1982func (a apexBundle) isCompressable() bool {
1983 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
1984}
1985
1986func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
1987 a.checkApexAvailability(ctx)
1988 a.checkUpdatable(ctx)
1989 a.CheckMinSdkVersion(ctx)
1990 a.checkStaticLinkingToStubLibraries(ctx)
1991 a.checkStaticExecutables(ctx)
1992 if len(a.properties.Tests) > 0 && !a.testApex {
1993 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
1994 return false
1995 }
1996 return true
1997}
1998
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001999type visitorContext struct {
2000 // all the files that will be included in this APEX
2001 filesInfo []apexFile
2002
2003 // native lib dependencies
2004 provideNativeLibs []string
2005 requireNativeLibs []string
2006
2007 handleSpecialLibs bool
2008}
2009
2010func (vctx *visitorContext) normalizeFileInfo() {
2011 encountered := make(map[string]apexFile)
2012 for _, f := range vctx.filesInfo {
2013 dest := filepath.Join(f.installDir, f.builtFile.Base())
2014 if e, ok := encountered[dest]; !ok {
2015 encountered[dest] = f
2016 } else {
2017 // If a module is directly included and also transitively depended on
2018 // consider it as directly included.
2019 e.transitiveDep = e.transitiveDep && f.transitiveDep
2020 encountered[dest] = e
2021 }
2022 }
2023 vctx.filesInfo = vctx.filesInfo[:0]
2024 for _, v := range encountered {
2025 vctx.filesInfo = append(vctx.filesInfo, v)
2026 }
2027 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2028 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2029 // changes.
2030 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2031 })
2032}
2033
2034func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2035 depTag := ctx.OtherModuleDependencyTag(child)
2036 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2037 return false
2038 }
2039 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2040 return false
2041 }
2042 depName := ctx.OtherModuleName(child)
2043 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2044 switch depTag {
2045 case sharedLibTag, jniLibTag:
2046 isJniLib := depTag == jniLibTag
2047 switch ch := child.(type) {
2048 case *cc.Module:
2049 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2050 fi.isJniLib = isJniLib
2051 vctx.filesInfo = append(vctx.filesInfo, fi)
2052 // Collect the list of stub-providing libs except:
2053 // - VNDK libs are only for vendors
2054 // - bootstrap bionic libs are treated as provided by system
2055 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2056 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2057 }
2058 return true // track transitive dependencies
2059 case *rust.Module:
2060 fi := apexFileForRustLibrary(ctx, ch)
2061 fi.isJniLib = isJniLib
2062 vctx.filesInfo = append(vctx.filesInfo, fi)
2063 return true // track transitive dependencies
2064 default:
2065 propertyName := "native_shared_libs"
2066 if isJniLib {
2067 propertyName = "jni_libs"
2068 }
2069 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2070 }
2071 case executableTag:
2072 switch ch := child.(type) {
2073 case *cc.Module:
2074 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2075 return true // track transitive dependencies
2076 case *python.Module:
2077 if ch.HostToolPath().Valid() {
2078 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2079 }
2080 case bootstrap.GoBinaryTool:
2081 if a.Host() {
2082 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2083 }
2084 case *rust.Module:
2085 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2086 return true // track transitive dependencies
2087 default:
2088 ctx.PropertyErrorf("binaries",
2089 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2090 }
2091 case shBinaryTag:
2092 if csh, ok := child.(*sh.ShBinary); ok {
2093 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2094 } else {
2095 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2096 }
2097 case bcpfTag:
2098 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2099 if !ok {
2100 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2101 return false
2102 }
2103
2104 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2105 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2106 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2107 }
2108 return true
2109 case sscpfTag:
2110 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2111 ctx.PropertyErrorf("systemserverclasspath_fragments",
2112 "%q is not a systemserverclasspath_fragment module", depName)
2113 return false
2114 }
2115 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2116 vctx.filesInfo = append(vctx.filesInfo, *af)
2117 }
2118 return true
2119 case javaLibTag:
2120 switch child.(type) {
2121 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2122 af := apexFileForJavaModule(ctx, child.(javaModule))
2123 if !af.ok() {
2124 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2125 return false
2126 }
2127 vctx.filesInfo = append(vctx.filesInfo, af)
2128 return true // track transitive dependencies
2129 default:
2130 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2131 }
2132 case androidAppTag:
2133 switch ap := child.(type) {
2134 case *java.AndroidApp:
2135 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2136 return true // track transitive dependencies
2137 case *java.AndroidAppImport:
2138 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2139 case *java.AndroidTestHelperApp:
2140 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2141 case *java.AndroidAppSet:
2142 appDir := "app"
2143 if ap.Privileged() {
2144 appDir = "priv-app"
2145 }
2146 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2147 // suffixed so that PackageManager correctly invalidates the
2148 // existing installed apk in favour of the new APK-in-APEX.
2149 // See bugs for more information.
2150 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2151 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2152 af.certificate = java.PresignedCertificate
2153 vctx.filesInfo = append(vctx.filesInfo, af)
2154 default:
2155 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2156 }
2157 case rroTag:
2158 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2159 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2160 } else {
2161 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2162 }
2163 case bpfTag:
2164 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2165 filesToCopy, _ := bpfProgram.OutputFiles("")
2166 apex_sub_dir := bpfProgram.SubDir()
2167 for _, bpfFile := range filesToCopy {
2168 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2169 }
2170 } else {
2171 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2172 }
2173 case fsTag:
2174 if fs, ok := child.(filesystem.Filesystem); ok {
2175 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2176 } else {
2177 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2178 }
2179 case prebuiltTag:
2180 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2181 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2182 } else {
2183 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2184 }
2185 case compatConfigTag:
2186 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2187 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2188 } else {
2189 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2190 }
2191 case testTag:
2192 if ccTest, ok := child.(*cc.Module); ok {
2193 if ccTest.IsTestPerSrcAllTestsVariation() {
2194 // Multiple-output test module (where `test_per_src: true`).
2195 //
2196 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2197 // We do not add this variation to `filesInfo`, as it has no output;
2198 // however, we do add the other variations of this module as indirect
2199 // dependencies (see below).
2200 } else {
2201 // Single-output test module (where `test_per_src: false`).
2202 af := apexFileForExecutable(ctx, ccTest)
2203 af.class = nativeTest
2204 vctx.filesInfo = append(vctx.filesInfo, af)
2205 }
2206 return true // track transitive dependencies
2207 } else {
2208 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2209 }
2210 case keyTag:
2211 if key, ok := child.(*apexKey); ok {
2212 a.privateKeyFile = key.privateKeyFile
2213 a.publicKeyFile = key.publicKeyFile
2214 } else {
2215 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2216 }
2217 case certificateTag:
2218 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2219 a.containerCertificateFile = dep.Certificate.Pem
2220 a.containerPrivateKeyFile = dep.Certificate.Key
2221 } else {
2222 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2223 }
2224 case android.PrebuiltDepTag:
2225 // If the prebuilt is force disabled, remember to delete the prebuilt file
2226 // that might have been installed in the previous builds
2227 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2228 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2229 }
2230 }
2231 return false
2232 }
2233
2234 if a.vndkApex {
2235 return false
2236 }
2237
2238 // indirect dependencies
2239 am, ok := child.(android.ApexModule)
2240 if !ok {
2241 return false
2242 }
2243 // We cannot use a switch statement on `depTag` here as the checked
2244 // tags used below are private (e.g. `cc.sharedDepTag`).
2245 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2246 if ch, ok := child.(*cc.Module); ok {
2247 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2248 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2249 return false
2250 }
2251 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2252 af.transitiveDep = true
2253
2254 // Always track transitive dependencies for host.
2255 if a.Host() {
2256 vctx.filesInfo = append(vctx.filesInfo, af)
2257 return true
2258 }
2259
2260 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2261 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2262 // If the dependency is a stubs lib, don't include it in this APEX,
2263 // but make sure that the lib is installed on the device.
2264 // In case no APEX is having the lib, the lib is installed to the system
2265 // partition.
2266 //
2267 // Always include if we are a host-apex however since those won't have any
2268 // system libraries.
2269 if !am.DirectlyInAnyApex() {
2270 // we need a module name for Make
2271 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2272 if !android.InList(name, a.requiredDeps) {
2273 a.requiredDeps = append(a.requiredDeps, name)
2274 }
2275 }
2276 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2277 // Don't track further
2278 return false
2279 }
2280
2281 // If the dep is not considered to be in the same
2282 // apex, don't add it to filesInfo so that it is not
2283 // included in this APEX.
2284 // TODO(jiyong): move this to at the top of the
2285 // else-if clause for the indirect dependencies.
2286 // Currently, that's impossible because we would
2287 // like to record requiredNativeLibs even when
2288 // DepIsInSameAPex is false. We also shouldn't do
2289 // this for host.
2290 //
2291 // TODO(jiyong): explain why the same module is passed in twice.
2292 // Switching the first am to parent breaks lots of tests.
2293 if !android.IsDepInSameApex(ctx, am, am) {
2294 return false
2295 }
2296
2297 vctx.filesInfo = append(vctx.filesInfo, af)
2298 return true // track transitive dependencies
2299 } else if rm, ok := child.(*rust.Module); ok {
2300 af := apexFileForRustLibrary(ctx, rm)
2301 af.transitiveDep = true
2302 vctx.filesInfo = append(vctx.filesInfo, af)
2303 return true // track transitive dependencies
2304 }
2305 } else if cc.IsTestPerSrcDepTag(depTag) {
2306 if ch, ok := child.(*cc.Module); ok {
2307 af := apexFileForExecutable(ctx, ch)
2308 // Handle modules created as `test_per_src` variations of a single test module:
2309 // use the name of the generated test binary (`fileToCopy`) instead of the name
2310 // of the original test module (`depName`, shared by all `test_per_src`
2311 // variations of that module).
2312 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2313 // these are not considered transitive dep
2314 af.transitiveDep = false
2315 vctx.filesInfo = append(vctx.filesInfo, af)
2316 return true // track transitive dependencies
2317 }
2318 } else if cc.IsHeaderDepTag(depTag) {
2319 // nothing
2320 } else if java.IsJniDepTag(depTag) {
2321 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2322 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2323 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2324 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2325 }
2326 } else if rust.IsDylibDepTag(depTag) {
2327 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2328 af := apexFileForRustLibrary(ctx, rustm)
2329 af.transitiveDep = true
2330 vctx.filesInfo = append(vctx.filesInfo, af)
2331 return true // track transitive dependencies
2332 }
2333 } else if rust.IsRlibDepTag(depTag) {
2334 // Rlib is statically linked, but it might have shared lib
2335 // dependencies. Track them.
2336 return true
2337 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2338 // Add the contents of the bootclasspath fragment to the apex.
2339 switch child.(type) {
2340 case *java.Library, *java.SdkLibrary:
2341 javaModule := child.(javaModule)
2342 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2343 if !af.ok() {
2344 ctx.PropertyErrorf("bootclasspath_fragments",
2345 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2346 return false
2347 }
2348 vctx.filesInfo = append(vctx.filesInfo, af)
2349 return true // track transitive dependencies
2350 default:
2351 ctx.PropertyErrorf("bootclasspath_fragments",
2352 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2353 }
2354 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2355 // Add the contents of the systemserverclasspath fragment to the apex.
2356 switch child.(type) {
2357 case *java.Library, *java.SdkLibrary:
2358 af := apexFileForJavaModule(ctx, child.(javaModule))
2359 vctx.filesInfo = append(vctx.filesInfo, af)
2360 return true // track transitive dependencies
2361 default:
2362 ctx.PropertyErrorf("systemserverclasspath_fragments",
2363 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2364 }
2365 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2366 // nothing
2367 } else if depTag == android.DarwinUniversalVariantTag {
2368 // nothing
2369 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2370 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2371 }
2372 return false
2373}
2374
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002375// Creates build rules for an APEX. It consists of the following major steps:
2376//
2377// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2378// 2) traverse the dependency tree to collect apexFile structs from them.
2379// 3) some fields in apexBundle struct are configured
2380// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002381func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002382 ////////////////////////////////////////////////////////////////////////////////////////////
2383 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002384 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002385 return
2386 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002387 ////////////////////////////////////////////////////////////////////////////////////////////
2388 // 2) traverse the dependency tree to collect apexFile structs from them.
2389
braleeb0c1f0c2021-06-07 22:49:13 +08002390 // Collect the module directory for IDE info in java/jdeps.go.
2391 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2392
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002393 // TODO(jiyong): do this using WalkPayloadDeps
2394 // TODO(jiyong): make this clean!!!
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002395 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2396 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
2397 vctx.normalizeFileInfo()
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002398 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002399 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002400 return
2401 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002402
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002403 ////////////////////////////////////////////////////////////////////////////////////////////
2404 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002405 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002406 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002407
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002408 a.setApexTypeAndSuffix(ctx)
2409 a.setPayloadFsType(ctx)
2410 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002411 if a.properties.ApexType != zipApex {
2412 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2413 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002414
2415 ////////////////////////////////////////////////////////////////////////////////////////////
2416 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002417 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002418 if a.properties.ApexType == flattenedApex {
2419 a.buildFlattenedApex(ctx)
2420 } else {
2421 a.buildUnflattenedApex(ctx)
2422 }
Jiyong Park956305c2020-01-09 12:32:06 +09002423 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002424 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002425
2426 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2427 if a.installable() {
2428 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2429 // along with other ordinary files. (Note that this is done by apexer for
2430 // non-flattened APEXes)
2431 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2432
2433 // Place the public key as apex_pubkey. This is also done by apexer for
2434 // non-flattened APEXes case.
2435 // TODO(jiyong): Why do we need this CP rule?
2436 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2437 ctx.Build(pctx, android.BuildParams{
2438 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002439 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002440 Output: copiedPubkey,
2441 })
2442 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2443 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002444}
2445
Paul Duffincc33ec82021-04-25 23:14:55 +01002446// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2447// the bootclasspath_fragment contributes to the apex.
2448func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2449 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2450 var filesToAdd []apexFile
2451
2452 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002453 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2454 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2455 dirInApex := filepath.Join("javalib", arch.String())
2456 for _, f := range files {
2457 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2458 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2459 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2460 filesToAdd = append(filesToAdd, af)
2461 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002462 }
2463 }
2464
satayev3db35472021-05-06 23:59:58 +01002465 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002466 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2467 filesToAdd = append(filesToAdd, *af)
2468 }
satayev3db35472021-05-06 23:59:58 +01002469
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002470 if pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex(); pathInApex != "" {
2471 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2472 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2473
2474 if pathOnHost != nil {
2475 // We need to copy the profile to a temporary path with the right filename because the apexer
2476 // will take the filename as is.
2477 ctx.Build(pctx, android.BuildParams{
2478 Rule: android.Cp,
2479 Input: pathOnHost,
2480 Output: tempPath,
2481 })
2482 } else {
2483 // At this point, the boot image profile cannot be generated. It is probably because the boot
2484 // image profile source file does not exist on the branch, or it is not available for the
2485 // current build target.
2486 // However, we cannot enforce the boot image profile to be generated because some build
2487 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2488 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2489 // only if the APEX is being built.
2490 ctx.Build(pctx, android.BuildParams{
2491 Rule: android.ErrorRule,
2492 Output: tempPath,
2493 Args: map[string]string{
2494 "error": "Boot image profile cannot be generated",
2495 },
2496 })
2497 }
2498
2499 androidMkModuleName := filepath.Base(pathInApex)
2500 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2501 filesToAdd = append(filesToAdd, af)
2502 }
2503
Paul Duffincc33ec82021-04-25 23:14:55 +01002504 return filesToAdd
2505}
2506
satayevb98371c2021-06-15 16:49:50 +01002507// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2508// the module contributes to the apex; or nil if the proto config was not generated.
2509func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2510 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2511 if !info.ClasspathFragmentProtoGenerated {
2512 return nil
2513 }
2514 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2515 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2516 return &af
satayev14e49132021-05-17 21:03:07 +01002517}
2518
Paul Duffincc33ec82021-04-25 23:14:55 +01002519// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2520// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002521func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2522 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2523
2524 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2525 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002526 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2527 if err != nil {
2528 ctx.ModuleErrorf("%s", err)
2529 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002530
2531 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2532 // bootclasspath_fragment.
2533 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2534 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002535}
2536
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002537///////////////////////////////////////////////////////////////////////////////////////////////////
2538// Factory functions
2539//
2540
2541func newApexBundle() *apexBundle {
2542 module := &apexBundle{}
2543
2544 module.AddProperties(&module.properties)
2545 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002546 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002547 module.AddProperties(&module.overridableProperties)
2548
2549 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2550 android.InitDefaultableModule(module)
2551 android.InitSdkAwareModule(module)
2552 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002553 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002554 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002555 return module
2556}
2557
Paul Duffineb8051d2021-10-18 17:49:39 +01002558func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002559 bundle := newApexBundle()
2560 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002561 return bundle
2562}
2563
2564// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2565// certain compatibility checks such as apex_available are not done for apex_test.
2566func testApexBundleFactory() android.Module {
2567 bundle := newApexBundle()
2568 bundle.testApex = true
2569 return bundle
2570}
2571
2572// apex packages other modules into an APEX file which is a packaging format for system-level
2573// components like binaries, shared libraries, etc.
2574func BundleFactory() android.Module {
2575 return newApexBundle()
2576}
2577
2578type Defaults struct {
2579 android.ModuleBase
2580 android.DefaultsModuleBase
2581}
2582
2583// apex_defaults provides defaultable properties to other apex modules.
2584func defaultsFactory() android.Module {
2585 return DefaultsFactory()
2586}
2587
2588func DefaultsFactory(props ...interface{}) android.Module {
2589 module := &Defaults{}
2590
2591 module.AddProperties(props...)
2592 module.AddProperties(
2593 &apexBundleProperties{},
2594 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002595 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002596 &overridableProperties{},
2597 )
2598
2599 android.InitDefaultsModule(module)
2600 return module
2601}
2602
2603type OverrideApex struct {
2604 android.ModuleBase
2605 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002606 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002607}
2608
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002609func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002610 // All the overrides happen in the base module.
2611}
2612
2613// override_apex is used to create an apex module based on another apex module by overriding some of
2614// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002615func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002616 m := &OverrideApex{}
2617
2618 m.AddProperties(&overridableProperties{})
2619
2620 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2621 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002622 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002623 return m
2624}
2625
Wei Li1c66fc72022-05-09 23:59:14 -07002626func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2627 if ctx.ModuleType() != "override_apex" {
2628 return
2629 }
2630
2631 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2632 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2633 if !baseApexExists {
2634 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2635 }
2636
2637 a, baseModuleIsApex := baseModule.(*apexBundle)
2638 if !baseModuleIsApex {
2639 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2640 }
2641 attrs, props := convertWithBp2build(a, ctx)
2642
2643 for _, p := range o.GetProperties() {
2644 overridableProperties, ok := p.(*overridableProperties)
2645 if !ok {
2646 continue
2647 }
Wei Li40f98732022-05-20 22:08:11 -07002648
2649 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2650 // After it is converted in convertWithBp2build(baseApex, ctx),
2651 // the attrs.Manifest.Value.Label is the file path relative to the directory
2652 // of base apex. So the following code converts it to a label that looks like
2653 // <package of base apex>:<path of manifest file> if base apex and override
2654 // apex are not in the same package.
2655 baseApexPackage := ctx.OtherModuleDir(a)
2656 overrideApexPackage := ctx.ModuleDir()
2657 if baseApexPackage != overrideApexPackage {
2658 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2659 }
2660
Wei Li1c66fc72022-05-09 23:59:14 -07002661 // Key
2662 if overridableProperties.Key != nil {
2663 attrs.Key = bazel.LabelAttribute{}
2664 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2665 }
2666
2667 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002668 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002669 // If overridableProperties.Certificate is nil, clear this out as
2670 // well with zeroed structs, so the override_apex does not use the
2671 // base apex's certificate.
2672 attrs.Certificate = bazel.LabelAttribute{}
2673 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002674 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002675 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002676 }
2677
2678 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002679 if overridableProperties.Prebuilts != nil {
2680 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2681 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2682 }
Wei Li1c66fc72022-05-09 23:59:14 -07002683
2684 // Compressible
2685 if overridableProperties.Compressible != nil {
2686 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2687 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002688
2689 // Package name
2690 //
2691 // e.g. com.android.adbd's package name is com.android.adbd, but
2692 // com.google.android.adbd overrides the package name to com.google.android.adbd
2693 //
2694 // TODO: this can be overridden from the product configuration, see
2695 // getOverrideManifestPackageName and
2696 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2697 //
2698 // Instead of generating the BUILD files differently based on the product config
2699 // at the point of conversion, this should be handled by the BUILD file loading
2700 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2701 if overridableProperties.Package_name != "" {
2702 attrs.Package_name = &overridableProperties.Package_name
2703 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002704
2705 // Logging parent
2706 if overridableProperties.Logging_parent != "" {
2707 attrs.Logging_parent = &overridableProperties.Logging_parent
2708 }
Wei Li1c66fc72022-05-09 23:59:14 -07002709 }
2710
2711 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2712}
2713
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002714///////////////////////////////////////////////////////////////////////////////////////////////////
2715// Vality check routines
2716//
2717// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2718// certain conditions are not met.
2719//
2720// TODO(jiyong): move these checks to a separate go file.
2721
satayevad991492021-12-03 18:58:32 +00002722var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2723
Spandan Dasa5f39a12022-08-05 02:35:52 +00002724// Ensures that min_sdk_version of the included modules are equal or less than the min_sdk_version
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002725// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002726func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002727 if a.testApex || a.vndkApex {
2728 return
2729 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002730 // apexBundle::minSdkVersion reports its own errors.
2731 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002732 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002733}
2734
Albert Martineefabcf2022-03-21 20:11:16 +00002735// Returns apex's min_sdk_version string value, honoring overrides
2736func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2737 // Only override the minSdkVersion value on Apexes which already specify
2738 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2739 // min_sdk_version value is lower than the one to override with.
Colin Cross56534df2022-10-04 09:58:58 -07002740 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2741 if minApiLevel.IsNone() {
2742 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002743 }
2744
Colin Cross56534df2022-10-04 09:58:58 -07002745 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2746 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2747 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2748 minApiLevel = overrideApiLevel
2749 }
2750
2751 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002752}
2753
2754// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002755func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2756 return android.SdkSpec{
2757 Kind: android.SdkNone,
2758 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002759 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002760 }
2761}
2762
Albert Martineefabcf2022-03-21 20:11:16 +00002763// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002764func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002765 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2766}
2767
2768// Construct ApiLevel object from min_sdk_version string value
2769func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2770 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002771 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002772 }
Albert Martineefabcf2022-03-21 20:11:16 +00002773 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002774 if err != nil {
2775 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2776 return android.NoneApiLevel
2777 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002778 return apiLevel
2779}
2780
2781// Ensures that a lib providing stub isn't statically linked
2782func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2783 // Practically, we only care about regular APEXes on the device.
2784 if ctx.Host() || a.testApex || a.vndkApex {
2785 return
2786 }
2787
2788 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2789
2790 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2791 if ccm, ok := to.(*cc.Module); ok {
2792 apexName := ctx.ModuleName()
2793 fromName := ctx.OtherModuleName(from)
2794 toName := ctx.OtherModuleName(to)
2795
2796 // If `to` is not actually in the same APEX as `from` then it does not need
2797 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002798 //
2799 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002800 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2801 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2802 return false
2803 }
2804
2805 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2806 // exception to this rule. It can't make the static dependencies dynamic
2807 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002808 // Same rule should be applied to linkerconfig, because it should be executed
2809 // only with static linked libraries before linker is available with ld.config.txt
2810 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002811 return false
2812 }
2813
2814 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2815 if isStubLibraryFromOtherApex && !externalDep {
2816 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2817 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2818 }
2819
2820 }
2821 return true
2822 })
2823}
2824
satayevb98371c2021-06-15 16:49:50 +01002825// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002826func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2827 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002828 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002829 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2830 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002831 if a.UsePlatformApis() {
2832 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2833 }
Daniel Norman69109112021-12-02 12:52:42 -08002834 if a.SocSpecific() || a.DeviceSpecific() {
2835 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2836 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002837 if a.FutureUpdatable() {
2838 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2839 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002840 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002841 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002842 }
2843}
2844
satayevb98371c2021-06-15 16:49:50 +01002845// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2846func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2847 ctx.VisitDirectDeps(func(module android.Module) {
2848 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2849 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2850 if !info.ClasspathFragmentProtoGenerated {
2851 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2852 }
2853 }
2854 })
2855}
2856
2857// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002858func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002859 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2860 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002861 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2862 tag := ctx.OtherModuleDependencyTag(module)
2863 switch tag {
2864 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002865 if m, ok := module.(interface {
2866 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2867 }); ok {
2868 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002869 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2870 }
2871 }
2872 }
2873 })
2874}
2875
satayevb98371c2021-06-15 16:49:50 +01002876// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002877func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2878 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2879 if ctx.Host() || a.testApex || a.vndkApex {
2880 return
2881 }
2882
2883 // Because APEXes targeting other than system/system_ext partitions can't set
2884 // apex_available, we skip checks for these APEXes
2885 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2886 return
2887 }
2888
2889 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2890 // Requiring them and their transitive depencies with apex_available is not right
2891 // because they just add noise.
2892 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2893 return
2894 }
2895
2896 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2897 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2898 if externalDep {
2899 return false
2900 }
2901
2902 apexName := ctx.ModuleName()
2903 fromName := ctx.OtherModuleName(from)
2904 toName := ctx.OtherModuleName(to)
2905
2906 // If `to` is not actually in the same APEX as `from` then it does not need
2907 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002908 //
2909 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002910 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2911 // As soon as the dependency graph crosses the APEX boundary, don't go
2912 // further.
2913 return false
2914 }
2915
2916 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
2917 return true
2918 }
Jiyong Park767dbd92021-03-04 13:03:10 +09002919 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2920 "\n\nDependency path:%s\n\n"+
2921 "Consider adding %q to 'apex_available' property of %q",
2922 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002923 // Visit this module's dependencies to check and report any issues with their availability.
2924 return true
2925 })
2926}
2927
Jiyong Park192600a2021-08-03 07:52:17 +00002928// checkStaticExecutable ensures that executables in an APEX are not static.
2929func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09002930 // No need to run this for host APEXes
2931 if ctx.Host() {
2932 return
2933 }
2934
Jiyong Park192600a2021-08-03 07:52:17 +00002935 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2936 if ctx.OtherModuleDependencyTag(module) != executableTag {
2937 return
2938 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09002939
2940 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00002941 apex := a.ApexVariationName()
2942 exec := ctx.OtherModuleName(module)
2943 if isStaticExecutableAllowed(apex, exec) {
2944 return
2945 }
2946 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
2947 }
2948 })
2949}
2950
2951// A small list of exceptions where static executables are allowed in APEXes.
2952func isStaticExecutableAllowed(apex string, exec string) bool {
2953 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07002954 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00002955 "linker",
2956 "linkerconfig",
2957 },
2958 }
2959 execNames, ok := m[apex]
2960 return ok && android.InList(exec, execNames)
2961}
2962
braleeb0c1f0c2021-06-07 22:49:13 +08002963// Collect information for opening IDE project files in java/jdeps.go.
2964func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09002965 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
2966 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
2967 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08002968 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
2969}
2970
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002971var (
2972 apexAvailBaseline = makeApexAvailableBaseline()
2973 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
2974)
2975
Colin Cross440e0d02020-06-11 11:32:11 -07002976func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002977 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002978 moduleName = normalizeModuleName(moduleName)
2979
Colin Cross440e0d02020-06-11 11:32:11 -07002980 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002981 return true
2982 }
2983
2984 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07002985 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002986 return true
2987 }
2988
2989 return false
2990}
2991
2992func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09002993 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
2994 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00002995 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09002996 if strings.HasPrefix(moduleName, "libclang_rt.") {
2997 // This module has many arch variants that depend on the product being built.
2998 // We don't want to list them all
2999 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003000 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003001 if strings.HasPrefix(moduleName, "androidx.") {
3002 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3003 moduleName = "androidx"
3004 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003005 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003006}
3007
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003008// Transform the map of apex -> modules to module -> apexes.
3009func invertApexBaseline(m map[string][]string) map[string][]string {
3010 r := make(map[string][]string)
3011 for apex, modules := range m {
3012 for _, module := range modules {
3013 r[module] = append(r[module], apex)
3014 }
3015 }
3016 return r
3017}
3018
3019// Retrieve the baseline of apexes to which the supplied module belongs.
3020func BaselineApexAvailable(moduleName string) []string {
3021 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3022}
3023
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003024// This is a map from apex to modules, which overrides the apex_available setting for that
3025// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003026// TODO(b/147364041): remove this
3027func makeApexAvailableBaseline() map[string][]string {
3028 // The "Module separator"s below are employed to minimize merge conflicts.
3029 m := make(map[string][]string)
3030 //
3031 // Module separator
3032 //
3033 m["com.android.appsearch"] = []string{
3034 "icing-java-proto-lite",
3035 "libprotobuf-java-lite",
3036 }
3037 //
3038 // Module separator
3039 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003040 m["com.android.btservices"] = []string{
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003041 "bluetooth-protos-lite",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003042 "internal_include_headers",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003043 "libaudio-a2dp-hw-utils",
3044 "libaudio-hearing-aid-hw-utils",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003045 "libbluetooth",
3046 "libbluetooth-types",
3047 "libbluetooth-types-header",
3048 "libbluetooth_gd",
3049 "libbluetooth_headers",
3050 "libbluetooth_jni",
3051 "libbt-audio-hal-interface",
3052 "libbt-bta",
3053 "libbt-common",
3054 "libbt-hci",
3055 "libbt-platform-protos-lite",
3056 "libbt-protos-lite",
3057 "libbt-sbc-decoder",
3058 "libbt-sbc-encoder",
3059 "libbt-stack",
3060 "libbt-utils",
3061 "libbtcore",
3062 "libbtdevice",
3063 "libbte",
3064 "libbtif",
3065 "libchrome",
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003066 }
3067 //
3068 // Module separator
3069 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003070 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3071 //
3072 // Module separator
3073 //
3074 m["com.android.extservices"] = []string{
3075 "error_prone_annotations",
3076 "ExtServices-core",
3077 "ExtServices",
3078 "libtextclassifier-java",
3079 "libz_current",
3080 "textclassifier-statsd",
3081 "TextClassifierNotificationLibNoManifest",
3082 "TextClassifierServiceLibNoManifest",
3083 }
3084 //
3085 // Module separator
3086 //
3087 m["com.android.neuralnetworks"] = []string{
3088 "android.hardware.neuralnetworks@1.0",
3089 "android.hardware.neuralnetworks@1.1",
3090 "android.hardware.neuralnetworks@1.2",
3091 "android.hardware.neuralnetworks@1.3",
3092 "android.hidl.allocator@1.0",
3093 "android.hidl.memory.token@1.0",
3094 "android.hidl.memory@1.0",
3095 "android.hidl.safe_union@1.0",
3096 "libarect",
3097 "libbuildversion",
3098 "libmath",
3099 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003100 }
3101 //
3102 // Module separator
3103 //
3104 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003105 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003106 }
3107 //
3108 // Module separator
3109 //
3110 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003111 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003112 }
3113 //
3114 // Module separator
3115 //
3116 m["com.android.mediaprovider"] = []string{
3117 "MediaProvider",
3118 "MediaProviderGoogle",
3119 "fmtlib_ndk",
3120 "libbase_ndk",
3121 "libfuse",
3122 "libfuse_jni",
3123 }
3124 //
3125 // Module separator
3126 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003127 m["com.android.runtime"] = []string{
3128 "bionic_libc_platform_headers",
3129 "libarm-optimized-routines-math",
3130 "libc_aeabi",
3131 "libc_bionic",
3132 "libc_bionic_ndk",
3133 "libc_bootstrap",
3134 "libc_common",
3135 "libc_common_shared",
3136 "libc_common_static",
3137 "libc_dns",
3138 "libc_dynamic_dispatch",
3139 "libc_fortify",
3140 "libc_freebsd",
3141 "libc_freebsd_large_stack",
3142 "libc_gdtoa",
3143 "libc_init_dynamic",
3144 "libc_init_static",
3145 "libc_jemalloc_wrapper",
3146 "libc_netbsd",
3147 "libc_nomalloc",
3148 "libc_nopthread",
3149 "libc_openbsd",
3150 "libc_openbsd_large_stack",
3151 "libc_openbsd_ndk",
3152 "libc_pthread",
3153 "libc_static_dispatch",
3154 "libc_syscalls",
3155 "libc_tzcode",
3156 "libc_unwind_static",
3157 "libdebuggerd",
3158 "libdebuggerd_common_headers",
3159 "libdebuggerd_handler_core",
3160 "libdebuggerd_handler_fallback",
3161 "libdl_static",
3162 "libjemalloc5",
3163 "liblinker_main",
3164 "liblinker_malloc",
3165 "liblz4",
3166 "liblzma",
3167 "libprocinfo",
3168 "libpropertyinfoparser",
3169 "libscudo",
3170 "libstdc++",
3171 "libsystemproperties",
3172 "libtombstoned_client_static",
3173 "libunwindstack",
3174 "libz",
3175 "libziparchive",
3176 }
3177 //
3178 // Module separator
3179 //
3180 m["com.android.tethering"] = []string{
3181 "android.hardware.tetheroffload.config-V1.0-java",
3182 "android.hardware.tetheroffload.control-V1.0-java",
3183 "android.hidl.base-V1.0-java",
3184 "libcgrouprc",
3185 "libcgrouprc_format",
3186 "libtetherutilsjni",
3187 "libvndksupport",
3188 "net-utils-framework-common",
3189 "netd_aidl_interface-V3-java",
3190 "netlink-client",
3191 "networkstack-aidl-interfaces-java",
3192 "tethering-aidl-interfaces-java",
3193 "TetheringApiCurrentLib",
3194 }
3195 //
3196 // Module separator
3197 //
3198 m["com.android.wifi"] = []string{
3199 "PlatformProperties",
3200 "android.hardware.wifi-V1.0-java",
3201 "android.hardware.wifi-V1.0-java-constants",
3202 "android.hardware.wifi-V1.1-java",
3203 "android.hardware.wifi-V1.2-java",
3204 "android.hardware.wifi-V1.3-java",
3205 "android.hardware.wifi-V1.4-java",
3206 "android.hardware.wifi.hostapd-V1.0-java",
3207 "android.hardware.wifi.hostapd-V1.1-java",
3208 "android.hardware.wifi.hostapd-V1.2-java",
3209 "android.hardware.wifi.supplicant-V1.0-java",
3210 "android.hardware.wifi.supplicant-V1.1-java",
3211 "android.hardware.wifi.supplicant-V1.2-java",
3212 "android.hardware.wifi.supplicant-V1.3-java",
3213 "android.hidl.base-V1.0-java",
3214 "android.hidl.manager-V1.0-java",
3215 "android.hidl.manager-V1.1-java",
3216 "android.hidl.manager-V1.2-java",
3217 "bouncycastle-unbundled",
3218 "dnsresolver_aidl_interface-V2-java",
3219 "error_prone_annotations",
3220 "framework-wifi-pre-jarjar",
3221 "framework-wifi-util-lib",
3222 "ipmemorystore-aidl-interfaces-V3-java",
3223 "ipmemorystore-aidl-interfaces-java",
3224 "ksoap2",
3225 "libnanohttpd",
3226 "libwifi-jni",
3227 "net-utils-services-common",
3228 "netd_aidl_interface-V2-java",
3229 "netd_aidl_interface-unstable-java",
3230 "netd_event_listener_interface-java",
3231 "netlink-client",
3232 "networkstack-client",
3233 "services.net",
3234 "wifi-lite-protos",
3235 "wifi-nano-protos",
3236 "wifi-service-pre-jarjar",
3237 "wifi-service-resources",
3238 }
3239 //
3240 // Module separator
3241 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003242 m["com.android.os.statsd"] = []string{
3243 "libstatssocket",
3244 }
3245 //
3246 // Module separator
3247 //
3248 m[android.AvailableToAnyApex] = []string{
3249 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3250 "androidx",
3251 "androidx-constraintlayout_constraintlayout",
3252 "androidx-constraintlayout_constraintlayout-nodeps",
3253 "androidx-constraintlayout_constraintlayout-solver",
3254 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3255 "com.google.android.material_material",
3256 "com.google.android.material_material-nodeps",
3257
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003258 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003259 "libprofile-clang-extras",
3260 "libprofile-clang-extras_ndk",
3261 "libprofile-extras",
3262 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003263 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003264 }
3265 return m
3266}
3267
3268func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003269 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3270 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003271}
3272
Spandan Dasf14e2542021-11-12 00:01:37 +00003273func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3274 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3275 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003276 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003277 With("name", jar).
3278 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3279 Because(jar +
3280 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003281 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003282 " 1. If the offending code is from a statically linked library, consider " +
3283 "removing that dependency and using an alternative already in the " +
3284 "bootclasspath, or perhaps a shared library." +
3285 " 2. Move the offending code into an allowed package.\n" +
3286 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3287 "health implications of bundling that code, particularly if the offending jar " +
3288 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003289
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003290 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003291 }
3292 return rules
3293}
3294
Anton Hanssone1b18362021-12-23 15:05:38 +00003295// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003296// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003297func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003298 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003299 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003300 "android.net.ssl",
3301 "com.android.org.conscrypt",
3302 },
Wei Li40f98732022-05-20 22:08:11 -07003303 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003304 "android.media",
3305 },
3306 }
3307}
3308
Anton Hanssone1b18362021-12-23 15:05:38 +00003309// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003310// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003311func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003312 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003313 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003314 "android.provider",
3315 },
Wei Li40f98732022-05-20 22:08:11 -07003316 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003317 "android.permission",
3318 "android.app.role",
3319 "com.android.permission",
3320 "com.android.role",
3321 },
Wei Li40f98732022-05-20 22:08:11 -07003322 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003323 "android.os.ext",
3324 },
Wei Li40f98732022-05-20 22:08:11 -07003325 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003326 "android.app",
3327 "android.os",
3328 "android.util",
3329 "com.android.internal.statsd",
3330 "com.android.server.stats",
3331 },
Wei Li40f98732022-05-20 22:08:11 -07003332 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003333 "com.android.server.wifi",
3334 "com.android.wifi.x",
3335 "android.hardware.wifi",
3336 "android.net.wifi",
3337 },
Wei Li40f98732022-05-20 22:08:11 -07003338 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003339 "android.net",
3340 },
3341 }
3342}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003343
3344// For Bazel / bp2build
3345
3346type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003347 Manifest bazel.LabelAttribute
3348 Android_manifest bazel.LabelAttribute
3349 File_contexts bazel.LabelAttribute
3350 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003351 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3352 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Yu Liu4ae55d12022-01-05 17:17:23 -08003353 Min_sdk_version *string
3354 Updatable bazel.BoolAttribute
3355 Installable bazel.BoolAttribute
3356 Binaries bazel.LabelListAttribute
3357 Prebuilts bazel.LabelListAttribute
3358 Native_shared_libs_32 bazel.LabelListAttribute
3359 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003360 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003361 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003362 Logging_parent *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003363}
3364
3365type convertedNativeSharedLibs struct {
3366 Native_shared_libs_32 bazel.LabelListAttribute
3367 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003368}
3369
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003370// ConvertWithBp2build performs bp2build conversion of an apex
3371func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
3372 // We do not convert apex_test modules at this time
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003373 if ctx.ModuleType() != "apex" {
3374 return
3375 }
3376
Wei Li1c66fc72022-05-09 23:59:14 -07003377 attrs, props := convertWithBp2build(a, ctx)
3378 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, &attrs)
3379}
3380
3381func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003382 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003383 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003384
3385 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003386 if a.properties.AndroidManifest != nil {
3387 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003388 }
3389
3390 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003391 if a.properties.File_contexts == nil {
3392 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3393 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3394 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3395 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003396 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003397 } else {
3398 // File_contexts is a file
3399 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003400 }
3401
Albert Martineefabcf2022-03-21 20:11:16 +00003402 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3403 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003404 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003405 if a.properties.Min_sdk_version != nil {
3406 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003407 }
3408
3409 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003410 if a.overridableProperties.Key != nil {
3411 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003412 }
3413
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003414 // Certificate
3415 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003416
Yu Liu4ae55d12022-01-05 17:17:23 -08003417 nativeSharedLibs := &convertedNativeSharedLibs{
3418 Native_shared_libs_32: bazel.LabelListAttribute{},
3419 Native_shared_libs_64: bazel.LabelListAttribute{},
3420 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003421
3422 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3423 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3424 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3425 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3426 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003427 if a.CompileMultilib() != nil {
3428 compileMultilib = *a.CompileMultilib()
3429 }
3430
3431 // properties.Native_shared_libs is treated as "both"
3432 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3433 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3434 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3435 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3436 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003437
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003438 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003439 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3440 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3441
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003442 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003443 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003444
3445 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003446 if a.properties.Updatable != nil {
3447 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003448 }
3449
3450 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003451 if a.properties.Installable != nil {
3452 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003453 }
3454
Wei Lif034cb42022-01-19 15:54:31 -08003455 var compressibleAttribute bazel.BoolAttribute
3456 if a.overridableProperties.Compressible != nil {
3457 compressibleAttribute.Value = a.overridableProperties.Compressible
3458 }
3459
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003460 var packageName *string
3461 if a.overridableProperties.Package_name != "" {
3462 packageName = &a.overridableProperties.Package_name
3463 }
3464
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003465 var loggingParent *string
3466 if a.overridableProperties.Logging_parent != "" {
3467 loggingParent = &a.overridableProperties.Logging_parent
3468 }
3469
Wei Li1c66fc72022-05-09 23:59:14 -07003470 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003471 Manifest: manifestLabelAttribute,
3472 Android_manifest: androidManifestLabelAttribute,
3473 File_contexts: fileContextsLabelAttribute,
3474 Min_sdk_version: minSdkVersion,
3475 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003476 Certificate: certificate,
3477 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003478 Updatable: updatableAttribute,
3479 Installable: installableAttribute,
3480 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3481 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3482 Binaries: binariesLabelListAttribute,
3483 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003484 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003485 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003486 Logging_parent: loggingParent,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003487 }
3488
3489 props := bazel.BazelTargetModuleProperties{
3490 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003491 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003492 }
3493
Wei Li1c66fc72022-05-09 23:59:14 -07003494 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003495}
Yu Liu4ae55d12022-01-05 17:17:23 -08003496
3497// The following conversions are based on this table where the rows are the compile_multilib
3498// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3499// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3500// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3501// should not be compiled.
3502// multib/compile_multilib, 32, 64, both, first
3503// 32, 32/32, none/none, 32/32, none/32
3504// 64, none/none, 64/none, 64/none, 64/none
3505// both, 32/32, 64/none, 32&64/32, 64/32
3506// first, 32/32, 64/none, 64/32, 64/32
3507
3508func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3509 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3510 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3511 switch compileMultilb {
3512 case "both", "32":
3513 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3514 case "first":
3515 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3516 case "64":
3517 // Incompatible, ignore
3518 default:
3519 invalidCompileMultilib(ctx, compileMultilb)
3520 }
3521}
3522
3523func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3524 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3525 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3526 switch compileMultilb {
3527 case "both", "64", "first":
3528 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3529 case "32":
3530 // Incompatible, ignore
3531 default:
3532 invalidCompileMultilib(ctx, compileMultilb)
3533 }
3534}
3535
3536func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3537 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3538 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3539 switch compileMultilb {
3540 case "both":
3541 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3542 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3543 case "first":
3544 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3545 case "32":
3546 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3547 case "64":
3548 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3549 default:
3550 invalidCompileMultilib(ctx, compileMultilb)
3551 }
3552}
3553
3554func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3555 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3556 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3557 switch compileMultilb {
3558 case "both", "first":
3559 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3560 case "32":
3561 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3562 case "64":
3563 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3564 default:
3565 invalidCompileMultilib(ctx, compileMultilb)
3566 }
3567}
3568
3569func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3570 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3571 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3572}
3573
3574func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3575 list := bazel.LabelListAttribute{}
3576 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3577 nativeSharedLibs.Native_shared_libs_32.Append(list)
3578}
3579
3580func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3581 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3582 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3583}
3584
3585func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3586 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3587 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3588}
3589
3590func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3591 labelListAttr *bazel.LabelListAttribute) {
3592 list := bazel.LabelListAttribute{}
3593 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3594 labelListAttr.Append(list)
3595}
3596
3597func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3598 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3599}