blob: 498c8c0ff23280abed73fc34c6a7b044b8d982f9 [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 }
289 X86 struct {
290 ApexNativeDependencies
291 }
292 X86_64 struct {
293 ApexNativeDependencies
294 }
295 }
296}
297
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900298// These properties can be used in override_apex to override the corresponding properties in the
299// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900300type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900301 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900302 Apps []string
303
Daniel Norman5a3ce132021-08-26 15:44:43 -0700304 // List of prebuilt files that are embedded inside this APEX bundle.
305 Prebuilts []string
306
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900307 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900308 Rros []string
309
markchien7c803b82021-08-26 22:10:06 +0800310 // List of BPF programs inside this APEX bundle.
311 Bpfs []string
312
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900313 // List of bootclasspath fragments that are embedded inside this APEX bundle.
314 Bootclasspath_fragments []string
315
316 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
317 Systemserverclasspath_fragments []string
318
319 // List of java libraries that are embedded inside this APEX bundle.
320 Java_libs []string
321
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900322 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
323 // Soong). This does not completely prevent installation of the overridden binaries, but if
324 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
325 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900326 Overrides []string
327
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900328 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900329 Logging_parent string
330
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900331 // Apex Container package name. Override value for attribute package:name in
332 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900333 Package_name string
334
335 // A txt file containing list of files that are allowed to be included in this APEX.
336 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700337
338 // Name of the apex_key module that provides the private key to sign this APEX bundle.
339 Key *string
340
341 // Specifies the certificate and the private key to sign the zip container of this APEX. If
342 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
343 // as the certificate and the private key, respectively. If this is ":module", then the
344 // certificate and the private key are provided from the android_app_certificate module
345 // named "module".
346 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400347
348 // Whether this APEX can be compressed or not. Setting this property to false means this
349 // APEX will never be compressed. When set to true, APEX will be compressed if other
350 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
351 // Default: false.
352 Compressible *bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900353}
354
355type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900356 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900357 android.ModuleBase
358 android.DefaultableModuleBase
359 android.OverridableModuleBase
360 android.SdkBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400361 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900362 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900363
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900364 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900365 properties apexBundleProperties
366 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900367 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900368 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900369 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900370
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900371 ///////////////////////////////////////////////////////////////////////////////////////////
372 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900373
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900374 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800375 publicKeyFile android.Path
376 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900377
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900378 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800379 containerCertificateFile android.Path
380 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900381
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900382 // Flags for special variants of APEX
383 testApex bool
384 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900385
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900386 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
387 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900388 primaryApexType bool
389
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900390 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900391 suffix string
392
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900393 // File system type of apex_payload.img
394 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900395
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900396 // Whether to create symlink to the system file instead of having a file inside the apex or
397 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900398 linkToSystemLib bool
399
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900400 // List of files to be included in this APEX. This is filled in the first part of
401 // GenerateAndroidBuildActions.
402 filesInfo []apexFile
403
404 // List of other module names that should be installed when this APEX gets installed.
405 requiredDeps []string
406
407 ///////////////////////////////////////////////////////////////////////////////////////////
408 // Outputs (final and intermediates)
409
410 // Processed apex manifest in JSONson format (for Q)
411 manifestJsonOut android.WritablePath
412
413 // Processed apex manifest in PB format (for R+)
414 manifestPbOut android.WritablePath
415
416 // Processed file_contexts files
417 fileContexts android.WritablePath
418
Bob Badourde6a0872022-04-01 18:00:00 +0000419 // Path to notice file in html.gz format.
420 htmlGzNotice android.WritablePath
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900421
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900422 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900423 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900424 outputFile android.WritablePath
425
Jooyung Hana6d36672022-02-24 13:58:07 +0900426 // The built uncompressed .apex file.
427 outputApexFile android.WritablePath
428
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900429 // The built APEX file in app bundle format. This file is not directly installed to the
430 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
431 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
432 // system) to be merged into a single app bundle file that Play accepts. See
433 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
434 bundleModuleFile android.WritablePath
435
Colin Cross6340ea52021-11-04 12:01:18 -0700436 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900437 installDir android.InstallPath
438
Colin Cross6340ea52021-11-04 12:01:18 -0700439 // Path where this APEX was installed.
440 installedFile android.InstallPath
441
442 // Installed locations of symlinks for backward compatibility.
443 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900444
445 // Text file having the list of individual files that are included in this APEX. Used for
446 // debugging purpose.
447 installedFilesFile android.WritablePath
448
449 // List of module names that this APEX is including (to be shown via *-deps-info target).
450 // Used for debugging purpose.
451 android.ApexBundleDepsInfo
452
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900453 // Optional list of lint report zip files for apexes that contain java or app modules
454 lintReports android.Paths
455
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900456 prebuiltFileToDelete string
sophiezc80a2b32020-11-12 16:39:19 +0000457
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000458 isCompressed bool
459
sophiezc80a2b32020-11-12 16:39:19 +0000460 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700461 nativeApisUsedByModuleFile android.ModuleOutPath
462 nativeApisBackedByModuleFile android.ModuleOutPath
463 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800464
465 // Collect the module directory for IDE info in java/jdeps.go.
466 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900467}
468
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900469// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900470type apexFileClass int
471
Jooyung Han72bd2f82019-10-23 16:46:38 +0900472const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900473 app apexFileClass = iota
474 appSet
475 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900476 goBinary
477 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900478 nativeExecutable
479 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900480 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900481 pyBinary
482 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900483)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900484
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900485// apexFile represents a file in an APEX bundle. This is created during the first half of
486// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
487// of the function, this is used to create commands that copies the files into a staging directory,
488// where they are packaged into the APEX file. This struct is also used for creating Make modules
489// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900490type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900491 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000492 builtFile android.Path
493 installDir string
494 customStem string
495 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900496
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900497 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
498 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
499 // suffix>]
500 androidMkModuleName string // becomes LOCAL_MODULE
501 class apexFileClass // becomes LOCAL_MODULE_CLASS
502 moduleDir string // becomes LOCAL_PATH
503 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
504 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
505 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
506 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900507
508 jacocoReportClassesFile android.Path // only for javalibs and apps
509 lintDepSets java.LintDepSets // only for javalibs and apps
510 certificate java.Certificate // only for apps
511 overriddenPackageName string // only for apps
512
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900513 transitiveDep bool
514 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900515
Jiyong Park57621b22021-01-20 20:33:11 +0900516 multilib string
517
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900518 // TODO(jiyong): remove this
519 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900520}
521
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900522// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900523func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
524 ret := apexFile{
525 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900526 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900527 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900528 class: class,
529 module: module,
530 }
531 if module != nil {
532 ret.moduleDir = ctx.OtherModuleDir(module)
533 ret.requiredModuleNames = module.RequiredModuleNames()
534 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
535 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900536 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900537 }
538 return ret
539}
540
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900541func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900542 return af.builtFile != nil && af.builtFile.String() != ""
543}
544
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900545// apexRelativePath returns the relative path of the given path from the install directory of this
546// apexFile.
547// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900548func (af *apexFile) apexRelativePath(path string) string {
549 return filepath.Join(af.installDir, path)
550}
551
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900552// path returns path of this apex file relative to the APEX root
553func (af *apexFile) path() string {
554 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900555}
556
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900557// stem returns the base filename of this apex file
558func (af *apexFile) stem() string {
559 if af.customStem != "" {
560 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900561 }
562 return af.builtFile.Base()
563}
564
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900565// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
566func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900567 var ret []string
568 for _, symlink := range af.symlinks {
569 ret = append(ret, af.apexRelativePath(symlink))
570 }
571 return ret
572}
573
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900574// availableToPlatform tests whether this apexFile is from a module that can be installed to the
575// platform.
576func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900577 if af.module == nil {
578 return false
579 }
580 if am, ok := af.module.(android.ApexModule); ok {
581 return am.AvailableFor(android.AvailableToPlatform)
582 }
583 return false
584}
585
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900586////////////////////////////////////////////////////////////////////////////////////////////////////
587// Mutators
588//
589// Brief description about mutators for APEX. The following three mutators are the most important
590// ones.
591//
592// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
593// to the (direct) dependencies of this APEX bundle.
594//
Paul Duffin949abc02020-12-08 10:34:30 +0000595// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900596// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
597// modules are marked as being included in the APEX via BuildForApex().
598//
Paul Duffin949abc02020-12-08 10:34:30 +0000599// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
600// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900601
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900602type dependencyTag struct {
603 blueprint.BaseDependencyTag
604 name string
605
606 // Determines if the dependent will be part of the APEX payload. Can be false for the
607 // dependencies to the signing key module, etc.
608 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000609
610 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
611 // replacement. This is needed because some prebuilt modules do not provide all the information
612 // needed by the apex.
613 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000614
615 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
616 // also be added as exported members of that SDK.
617 memberType android.SdkMemberType
618}
619
620func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
621 return d.memberType
622}
623
624func (d *dependencyTag) ExportMember() bool {
625 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900626}
627
Paul Duffin520917a2022-05-13 13:01:59 +0000628func (d *dependencyTag) String() string {
629 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
630}
631
632func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000633 return !d.sourceOnly
634}
635
636var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000637var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000638
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900639var (
Paul Duffin520917a2022-05-13 13:01:59 +0000640 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
641 bpfTag = &dependencyTag{name: "bpf", payload: true}
642 certificateTag = &dependencyTag{name: "certificate"}
643 executableTag = &dependencyTag{name: "executable", payload: true}
644 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000645 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
646 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000647 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000648 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
649 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
650 keyTag = &dependencyTag{name: "key"}
651 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
652 rroTag = &dependencyTag{name: "rro", payload: true}
653 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
654 testForTag = &dependencyTag{name: "test for"}
655 testTag = &dependencyTag{name: "test", payload: true}
656 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900657)
658
659// TODO(jiyong): shorten this function signature
660func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900661 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900662 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900663 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900664
665 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900666 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900667 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
668 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900669 }
670
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900671 // Use *FarVariation* to be able to depend on modules having conflicting variations with
672 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
673 // 'arm' or 'arm64' for native shared libs.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900674 ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900675 ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900676 ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
677 ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
Jiyong Park99644e92020-11-17 22:21:02 +0900678 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
Jiyong Park06711462021-02-15 17:54:43 +0900679 ctx.AddFarVariationDependencies(target.Variations(), fsTag, nativeModules.Filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900680}
681
682func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900683 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900684 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
685 } else {
686 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
687 if ctx.Os().Bionic() {
688 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
689 } else {
690 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
691 }
692 }
693}
694
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900695// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
696// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
697func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
698 deviceConfig := ctx.DeviceConfig()
699 if a.vndkApex {
700 return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900701 }
702
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900703 var prefix string
704 var vndkVersion string
705 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000706 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900707 prefix = cc.VendorVariationPrefix
708 vndkVersion = deviceConfig.VndkVersion()
709 } else if a.ProductSpecific() {
710 prefix = cc.ProductVariationPrefix
711 vndkVersion = deviceConfig.ProductVndkVersion()
712 }
713 }
714 if vndkVersion == "current" {
715 vndkVersion = deviceConfig.PlatformVndkVersion()
716 }
717 if vndkVersion != "" {
718 return prefix + vndkVersion
719 }
720
721 return android.CoreVariation // The usual case
722}
723
724func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900725 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
726 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
727 // each target os/architectures, appropriate dependencies are selected by their
728 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900729 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900730 imageVariation := a.getImageVariation(ctx)
731
732 a.combineProperties(ctx)
733
734 has32BitTarget := false
735 for _, target := range targets {
736 if target.Arch.ArchType.Multilib == "lib32" {
737 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000738 }
739 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900740 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900741 // Don't include artifacts for the host cross targets because there is no way for us
742 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900743 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900744 continue
745 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000746
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900747 var depsList []ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000748
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900749 // Add native modules targeting both ABIs. When multilib.* is omitted for
750 // native_shared_libs/jni_libs/tests, it implies multilib.both
751 depsList = append(depsList, a.properties.Multilib.Both)
752 depsList = append(depsList, ApexNativeDependencies{
753 Native_shared_libs: a.properties.Native_shared_libs,
754 Tests: a.properties.Tests,
755 Jni_libs: a.properties.Jni_libs,
756 Binaries: nil,
757 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900758
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900759 // Add native modules targeting the first ABI When multilib.* is omitted for
760 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900761 isPrimaryAbi := i == 0
762 if isPrimaryAbi {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900763 depsList = append(depsList, a.properties.Multilib.First)
764 depsList = append(depsList, ApexNativeDependencies{
765 Native_shared_libs: nil,
766 Tests: nil,
767 Jni_libs: nil,
768 Binaries: a.properties.Binaries,
769 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900770 }
771
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900772 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900773 switch target.Arch.ArchType.Multilib {
774 case "lib32":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900775 depsList = append(depsList, a.properties.Multilib.Lib32)
776 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900777 case "lib64":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900778 depsList = append(depsList, a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900779 if !has32BitTarget {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900780 depsList = append(depsList, a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900781 }
782 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900783
Jiyong Park59140302020-12-14 18:44:04 +0900784 // Add native modules targeting a specific arch variant
785 switch target.Arch.ArchType {
786 case android.Arm:
787 depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
788 case android.Arm64:
789 depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
790 case android.X86:
791 depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
792 case android.X86_64:
793 depsList = append(depsList, a.archProperties.Arch.X86_64.ApexNativeDependencies)
794 default:
795 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
796 }
797
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900798 for _, d := range depsList {
799 addDependenciesForNativeModules(ctx, d, target, imageVariation)
800 }
Sundong Ahn80c04892021-11-23 00:57:19 +0000801 ctx.AddFarVariationDependencies([]blueprint.Variation{
802 {Mutator: "os", Variation: target.OsVariation()},
803 {Mutator: "arch", Variation: target.ArchVariation()},
804 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900805 }
806
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900807 // Common-arch dependencies come next
808 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900809 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000810 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100811}
812
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900813// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900814func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
815 if a.overridableProperties.Allowed_files != nil {
816 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100817 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900818
819 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
820 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800821 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900822 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900823 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
824 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
825 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700826 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
827 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
828 // regardless of the TARGET_PREFER_* setting. See b/144532908
829 arches := ctx.DeviceConfig().Arches()
830 if len(arches) != 0 {
831 archForPrebuiltEtc := arches[0]
832 for _, arch := range arches {
833 // Prefer 64-bit arch if there is any
834 if arch.ArchType.Multilib == "lib64" {
835 archForPrebuiltEtc = arch
836 break
837 }
838 }
839 ctx.AddFarVariationDependencies([]blueprint.Variation{
840 {Mutator: "os", Variation: ctx.Os().String()},
841 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
842 }, prebuiltTag, prebuilts...)
843 }
844 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700845
846 // Dependencies for signing
847 if String(a.overridableProperties.Key) == "" {
848 ctx.PropertyErrorf("key", "missing")
849 return
850 }
851 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
852
853 cert := android.SrcIsModule(a.getCertString(ctx))
854 if cert != "" {
855 ctx.AddDependency(ctx.Module(), certificateTag, cert)
856 // empty cert is not an error. Cert and private keys will be directly found under
857 // PRODUCT_DEFAULT_DEV_CERTIFICATE
858 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100859}
860
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900861type ApexBundleInfo struct {
862 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100863}
864
Paul Duffin949abc02020-12-08 10:34:30 +0000865var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900866
Paul Duffina7d6a892020-12-07 17:39:59 +0000867var _ ApexInfoMutator = (*apexBundle)(nil)
868
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100869func (a *apexBundle) ApexVariationName() string {
870 return a.properties.ApexVariationName
871}
872
Paul Duffina7d6a892020-12-07 17:39:59 +0000873// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900874// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
875// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
876// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
877// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000878//
879// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
880// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
881// The apexMutator uses that list to create module variants for the apexes to which it belongs.
882// The relationship between module variants and apexes is not one-to-one as variants will be
883// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000884func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900885
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900886 // The VNDK APEX is special. For the APEX, the membership is described in a very different
887 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
888 // libraries are self-identified by their vndk.enabled properties. There is no need to run
889 // this mutator for the APEX as nothing will be collected. So, let's return fast.
890 if a.vndkApex {
891 return
892 }
893
894 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
895 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
896 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
897 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
898 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900899 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
900 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900901 if proptools.Bool(a.properties.Use_vndk_as_stable) {
902 if !useVndk {
903 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
904 }
905 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
906 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
907 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
908 }
909 })
910 if mctx.Failed() {
911 return
912 }
Jooyung Handf78e212020-07-22 15:54:47 +0900913 }
914
Colin Cross56a83212020-09-15 18:30:11 -0700915 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900916 am, ok := child.(android.ApexModule)
917 if !ok || !am.CanHaveApexVariants() {
918 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900919 }
Paul Duffin573989d2021-03-17 13:25:29 +0000920 depTag := mctx.OtherModuleDependencyTag(child)
921
922 // Check to see if the tag always requires that the child module has an apex variant for every
923 // apex variant of the parent module. If it does not then it is still possible for something
924 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
925 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
926 return true
927 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000928 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900929 return false
930 }
Jooyung Handf78e212020-07-22 15:54:47 +0900931 if excludeVndkLibs {
932 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
933 return false
934 }
935 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900936 // By default, all the transitive dependencies are collected, unless filtered out
937 // above.
Colin Cross56a83212020-09-15 18:30:11 -0700938 return true
939 }
940
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900941 // Records whether a certain module is included in this apexBundle via direct dependency or
942 // inndirect dependency.
943 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -0700944 mctx.WalkDeps(func(child, parent android.Module) bool {
945 if !continueApexDepsWalk(child, parent) {
946 return false
947 }
Jooyung Han698dd9f2020-07-22 15:17:19 +0900948 // If the parent is apexBundle, this child is directly depended.
949 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900950 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -0700951 contents[depName] = contents[depName].Add(directDep)
952 return true
953 })
954
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900955 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +0900956 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -0700957 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
958 Contents: apexContents,
959 })
960
Jooyung Haned124c32021-01-26 11:43:46 +0900961 minSdkVersion := a.minSdkVersion(mctx)
962 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
963 if minSdkVersion.IsNone() {
964 minSdkVersion = android.FutureApiLevel
965 }
966
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900967 // This is the main part of this mutator. Mark the collected dependencies that they need to
968 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +0900969
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100970 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
971 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -0700972 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100973 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +0900974 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -0700975 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +0900976 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100977 InApexVariants: []string{apexVariationName},
978 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -0700979 ApexContents: []*android.ApexContents{apexContents},
980 }
Colin Cross56a83212020-09-15 18:30:11 -0700981 mctx.WalkDeps(func(child, parent android.Module) bool {
982 if !continueApexDepsWalk(child, parent) {
983 return false
984 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900985 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +0900986 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +0900987 })
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900988}
989
Paul Duffina7d6a892020-12-07 17:39:59 +0000990type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100991 // ApexVariationName returns the name of the APEX variation to use in the apex
992 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
993 ApexVariationName() string
994
Paul Duffina7d6a892020-12-07 17:39:59 +0000995 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
996 // depended upon by an apex and which require an apex specific variant.
997 ApexInfoMutator(android.TopDownMutatorContext)
998}
999
1000// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1001// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001002// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001003func apexInfoMutator(mctx android.TopDownMutatorContext) {
1004 if !mctx.Module().Enabled() {
1005 return
1006 }
1007
1008 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1009 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001010 }
Spandan Das42e89502022-05-06 22:12:55 +00001011 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001012}
1013
Spandan Das66773252022-01-15 00:23:18 +00001014// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1015// This check is enforced for updatable modules
1016func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1017 if !mctx.Module().Enabled() {
1018 return
1019 }
Spandan Das08c911f2022-01-21 22:07:26 +00001020 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001021 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001022 // b/208656169 Do not propagate strict updatability linting to libcore/
1023 // These libs are available on the classpath during compilation
1024 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1025 // Only skip libraries defined in libcore root, not subdirectories
1026 if mctx.OtherModuleDir(child) == "libcore" {
1027 // Do not traverse transitive deps of libcore/ libs
1028 return false
1029 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001030 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1031 return false
1032 }
Spandan Das66773252022-01-15 00:23:18 +00001033 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1034 lintable.SetStrictUpdatabilityLinting(true)
1035 }
1036 // visit transitive deps
1037 return true
1038 })
1039 }
1040}
1041
Spandan Das42e89502022-05-06 22:12:55 +00001042// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1043func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1044 if !mctx.Module().Enabled() {
1045 return
1046 }
1047 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1048 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1049 mctx.VisitDirectDeps(func(module android.Module) {
1050 // ignore android_test_app
1051 if app, ok := module.(*java.AndroidApp); ok {
1052 app.SetUpdatable(true)
1053 }
1054 })
1055 }
1056}
1057
Spandan Das08c911f2022-01-21 22:07:26 +00001058// TODO: b/215736885 Whittle the denylist
1059// Transitive deps of certain mainline modules baseline NewApi errors
1060// Skip these mainline modules for now
1061var (
1062 skipStrictUpdatabilityLintAllowlist = []string{
1063 "com.android.art",
1064 "com.android.art.debug",
1065 "com.android.conscrypt",
1066 "com.android.media",
1067 // test apexes
1068 "test_com.android.art",
1069 "test_com.android.conscrypt",
1070 "test_com.android.media",
1071 "test_jitzygote_com.android.art",
1072 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001073
1074 // TODO: b/215736885 Remove this list
1075 skipLintJavalibAllowlist = []string{
1076 "conscrypt.module.platform.api.stubs",
1077 "conscrypt.module.public.api.stubs",
1078 "conscrypt.module.public.api.stubs.system",
1079 "conscrypt.module.public.api.stubs.module_lib",
1080 "framework-media.stubs",
1081 "framework-media.stubs.system",
1082 "framework-media.stubs.module_lib",
1083 }
Spandan Das08c911f2022-01-21 22:07:26 +00001084)
1085
1086func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1087 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1088}
1089
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001090// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1091// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1092// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001093func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1094 if !mctx.Module().Enabled() {
1095 return
1096 }
1097 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001098 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1099 }
1100}
1101
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001102// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1103// the apex in order to retrieve its contents later.
1104// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001105func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1106 if !mctx.Module().Enabled() {
1107 return
1108 }
Colin Cross56a83212020-09-15 18:30:11 -07001109 if am, ok := mctx.Module().(android.ApexModule); ok {
1110 if testFor := am.TestFor(); len(testFor) > 0 {
1111 mctx.AddFarVariationDependencies([]blueprint.Variation{
1112 {Mutator: "os", Variation: am.Target().OsVariation()},
1113 {"arch", "common"},
1114 }, testForTag, testFor...)
1115 }
1116 }
1117}
1118
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001119// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001120func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1121 if !mctx.Module().Enabled() {
1122 return
1123 }
Colin Cross56a83212020-09-15 18:30:11 -07001124 if _, ok := mctx.Module().(android.ApexModule); ok {
1125 var contents []*android.ApexContents
1126 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1127 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1128 contents = append(contents, abInfo.Contents)
1129 }
1130 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1131 ApexContents: contents,
1132 })
Colin Crossaede88c2020-08-11 12:17:01 -07001133 }
1134}
1135
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001136// markPlatformAvailability marks whether or not a module can be available to platform. A module
1137// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1138// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1139// be) available to platform
1140// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001141func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1142 // Host and recovery are not considered as platform
1143 if mctx.Host() || mctx.Module().InstallInRecovery() {
1144 return
1145 }
1146
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001147 am, ok := mctx.Module().(android.ApexModule)
1148 if !ok {
1149 return
1150 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001151
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001152 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001153
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001154 // If any of the dep is not available to platform, this module is also considered as being
1155 // not available to platform even if it has "//apex_available:platform"
1156 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001157 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001158 // if the dependency crosses apex boundary, don't consider it
1159 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001160 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001161 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1162 availableToPlatform = false
1163 // TODO(b/154889534) trigger an error when 'am' has
1164 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001165 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001166 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001167
Paul Duffinb5769c12021-05-12 16:16:51 +01001168 // Exception 1: check to see if the module always requires it.
1169 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001170 availableToPlatform = true
1171 }
1172
1173 // Exception 2: bootstrap bionic libraries are also always available to platform
1174 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1175 availableToPlatform = true
1176 }
1177
1178 if !availableToPlatform {
1179 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001180 }
1181}
1182
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001183// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001184// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001185func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001186 if !mctx.Module().Enabled() {
1187 return
1188 }
Colin Cross56a83212020-09-15 18:30:11 -07001189
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001190 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001191 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001192 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001193 return
1194 }
1195
1196 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001197 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1198 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001199 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001200 if strings.HasPrefix(apexBundleName, "com.android.art") {
1201 // Create an alias from the platform variant. This is done to make
1202 // test_for dependencies work for modules that are split by the APEX
1203 // mutator, since test_for dependencies always go to the platform variant.
1204 // This doesn't happen for normal APEXes that are disjunct, so only do
1205 // this for the overlapping ART APEXes.
1206 // TODO(b/183882457): Remove this if the test_for functionality is
1207 // refactored to depend on the proper APEX variants instead of platform.
1208 mctx.CreateAliasVariation("", apexBundleName)
1209 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001210 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1211 apexBundleName := o.GetOverriddenModuleName()
1212 if apexBundleName == "" {
1213 mctx.ModuleErrorf("base property is not set")
1214 return
1215 }
1216 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001217 if strings.HasPrefix(apexBundleName, "com.android.art") {
1218 // TODO(b/183882457): See note for CreateAliasVariation above.
1219 mctx.CreateAliasVariation("", apexBundleName)
1220 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001221 }
1222}
Sundong Ahne9b55722019-09-06 17:37:42 +09001223
Paul Duffin6717d882021-06-15 19:09:41 +01001224// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1225// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001226func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001227 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001228 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001229 return !a.vndkApex
1230 }
1231
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001232 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001233}
1234
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001235// See android.UpdateDirectlyInAnyApex
1236// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001237func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1238 if !mctx.Module().Enabled() {
1239 return
1240 }
1241 if am, ok := mctx.Module().(android.ApexModule); ok {
1242 android.UpdateDirectlyInAnyApex(mctx, am)
1243 }
1244}
1245
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001246// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001247type apexPackaging int
1248
1249const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001250 // imageApex is a packaging method where contents are included in a filesystem image which
1251 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001252 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001253
1254 // zipApex is a packaging method where contents are directly included in the zip container.
1255 // This is used for host-side testing - because the contents are easily accessible by
1256 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001257 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001258
1259 // flattendApex is a packaging method where contents are not included in the APEX file, but
1260 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1261 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001262 flattenedApex
1263)
1264
1265const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001266 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001267 imageApexSuffix = ".apex"
1268 imageCapexSuffix = ".capex"
1269 zipApexSuffix = ".zipapex"
1270 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001271
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001272 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001273 imageApexType = "image"
1274 zipApexType = "zip"
1275 flattenedApexType = "flattened"
1276
Dan Willemsen47e1a752021-10-16 18:36:13 -07001277 ext4FsType = "ext4"
1278 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001279 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001280)
1281
1282// The suffix for the output "file", not the module
1283func (a apexPackaging) suffix() string {
1284 switch a {
1285 case imageApex:
1286 return imageApexSuffix
1287 case zipApex:
1288 return zipApexSuffix
1289 default:
1290 panic(fmt.Errorf("unknown APEX type %d", a))
1291 }
1292}
1293
1294func (a apexPackaging) name() string {
1295 switch a {
1296 case imageApex:
1297 return imageApexType
1298 case zipApex:
1299 return zipApexType
1300 default:
1301 panic(fmt.Errorf("unknown APEX type %d", a))
1302 }
1303}
1304
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001305// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1306// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001307func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001308 if !mctx.Module().Enabled() {
1309 return
1310 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001311 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001312 var variants []string
1313 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1314 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001315 // This is the normal case. Note that both image and flattend APEXes are
1316 // created. The image type is installed to the system partition, while the
1317 // flattened APEX is (optionally) installed to the system_ext partition.
1318 // This is mostly for GSI which has to support wide range of devices. If GSI
1319 // is installed on a newer (APEX-capable) device, the image APEX in the
1320 // system will be used. However, if the same GSI is installed on an old
1321 // device which can't support image APEX, the flattened APEX in the
1322 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001323 variants = append(variants, imageApexType, flattenedApexType)
1324 case "zip":
1325 variants = append(variants, zipApexType)
1326 case "both":
1327 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1328 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001329 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001330 return
1331 }
1332
1333 modules := mctx.CreateLocalVariations(variants...)
1334
1335 for i, v := range variants {
1336 switch v {
1337 case imageApexType:
1338 modules[i].(*apexBundle).properties.ApexType = imageApex
1339 case zipApexType:
1340 modules[i].(*apexBundle).properties.ApexType = zipApex
1341 case flattenedApexType:
1342 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001343 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001344 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001345 modules[i].(*apexBundle).MakeAsSystemExt()
1346 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001347 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001348 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001349 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001350 // payload_type is forcibly overridden to "image"
1351 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001352 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001353 }
1354}
1355
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001356var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001357
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001358// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001359func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001360 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001361 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001362 return true
1363}
1364
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001365var _ android.OutputFileProducer = (*apexBundle)(nil)
1366
1367// Implements android.OutputFileProducer
1368func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1369 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001370 case "", android.DefaultDistTag:
1371 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001372 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001373 case imageApexSuffix:
1374 // uncompressed one
1375 if a.outputApexFile != nil {
1376 return android.Paths{a.outputApexFile}, nil
1377 }
1378 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001379 default:
1380 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1381 }
1382}
1383
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001384var _ multitree.Exportable = (*apexBundle)(nil)
1385
1386func (a *apexBundle) Exportable() bool {
1387 if a.properties.ApexType == flattenedApex {
1388 return false
1389 }
1390 return true
1391}
1392
1393func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1394 ret := make(map[string]android.Paths)
1395 ret["apex"] = android.Paths{a.outputFile}
1396 return ret
1397}
1398
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001399var _ cc.Coverage = (*apexBundle)(nil)
1400
1401// Implements cc.Coverage
1402func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1403 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1404}
1405
1406// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001407func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001408 a.properties.PreventInstall = true
1409}
1410
1411// Implements cc.Coverage
1412func (a *apexBundle) HideFromMake() {
1413 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001414 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1415 // TODO(ccross): untangle these
1416 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001417}
1418
1419// Implements cc.Coverage
1420func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1421 a.properties.IsCoverageVariant = coverage
1422}
1423
1424// Implements cc.Coverage
1425func (a *apexBundle) EnableCoverageIfNeeded() {}
1426
1427var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1428
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001429// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001430func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001431 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001432}
1433
Jiyong Parkf4020582021-11-29 12:37:10 +09001434func (a *apexBundle) FutureUpdatable() bool {
1435 return proptools.BoolDefault(a.properties.Future_updatable, false)
1436}
1437
Jiyong Park1bc84122021-06-22 20:23:05 +09001438func (a *apexBundle) UsePlatformApis() bool {
1439 return proptools.BoolDefault(a.properties.Platform_apis, false)
1440}
1441
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001442// getCertString returns the name of the cert that should be used to sign this APEX. This is
1443// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001444func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001445 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001446 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1447 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1448 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001449 if a.vndkApex {
1450 moduleName = vndkApexName
1451 }
1452 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001453 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001454 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001455 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001456 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001457}
1458
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001459// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001460func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001461 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001462}
1463
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001464// See the generate_hashtree property
1465func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001466 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001467}
1468
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001469// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001470func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1471 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1472}
1473
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001474// See the test_only_force_compression property
1475func (a *apexBundle) testOnlyShouldForceCompression() bool {
1476 return proptools.Bool(a.properties.Test_only_force_compression)
1477}
1478
Dennis Shenaf41bc12022-08-03 16:46:43 +00001479// See the dynamic_common_lib_apex property
1480func (a *apexBundle) dynamic_common_lib_apex() bool {
1481 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1482}
1483
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001484// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1485// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1486// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001487
Jiyong Parkf97782b2019-02-13 20:28:58 +09001488func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1489 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1490 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1491 }
1492}
1493
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001494func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001495 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1496 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001497 }
1498
1499 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001500 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001501 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001502 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001503 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001504 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001505 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001506 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001507 }
1508 }
1509 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001510}
1511
Jooyung Han8ce8db92020-05-15 19:05:05 +09001512func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001513 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1514 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001515 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001516 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001517 for _, target := range ctx.MultiTargets() {
1518 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001519 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001520 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001521 Tests: nil,
1522 Jni_libs: nil,
1523 Binaries: nil,
1524 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001525 break
1526 }
1527 }
1528 }
1529}
1530
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001531// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1532// returned apexFile saves information about the Soong module that will be used for creating the
1533// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001534func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001535 // Decide the APEX-local directory by the multilib of the library In the future, we may
1536 // query this to the module.
1537 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001538 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001539 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001540 case "lib32":
1541 dirInApex = "lib"
1542 case "lib64":
1543 dirInApex = "lib64"
1544 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001545 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001546 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001547 }
Jooyung Han35155c42020-02-06 17:33:20 +09001548 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001549 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001550 // Special case for Bionic libs and other libs installed with them. This is to
1551 // prevent those libs from being included in the search path
1552 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1553 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1554 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1555 // will be loaded into the default linker namespace (aka "platform" namespace). If
1556 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1557 // be loaded again into the runtime linker namespace, which will result in double
1558 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001559 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001560 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001561
Jiyong Parkf653b052019-11-18 15:39:01 +09001562 fileToCopy := ccMod.OutputFile().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001563 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1564 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001565}
1566
Jiyong Park1833cef2019-12-13 13:28:36 +09001567func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001568 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001569 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001570 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001571 }
Jooyung Han35155c42020-02-06 17:33:20 +09001572 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Jiyong Parkf653b052019-11-18 15:39:01 +09001573 fileToCopy := cc.OutputFile().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001574 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1575 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001576 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001577 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001578 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001579}
1580
Jiyong Park99644e92020-11-17 22:21:02 +09001581func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1582 dirInApex := "bin"
1583 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1584 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1585 }
1586 fileToCopy := rustm.OutputFile().Path()
1587 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1588 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1589 return af
1590}
1591
1592func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1593 // Decide the APEX-local directory by the multilib of the library
1594 // In the future, we may query this to the module.
1595 var dirInApex string
1596 switch rustm.Arch().ArchType.Multilib {
1597 case "lib32":
1598 dirInApex = "lib"
1599 case "lib64":
1600 dirInApex = "lib64"
1601 }
1602 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1603 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1604 }
1605 fileToCopy := rustm.OutputFile().Path()
1606 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1607 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1608}
1609
Jiyong Park1833cef2019-12-13 13:28:36 +09001610func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001611 dirInApex := "bin"
1612 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001613 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001614}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001615
Jiyong Park1833cef2019-12-13 13:28:36 +09001616func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001617 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001618 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001619 // NB: Since go binaries are static we don't need the module for anything here, which is
1620 // good since the go tool is a blueprint.Module not an android.Module like we would
1621 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001622 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001623}
1624
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001625func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001626 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001627 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1628 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1629 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001630 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001631 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001632 af.symlinks = sh.Symlinks()
1633 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001634}
1635
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001636func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001637 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001638 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001639 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001640}
1641
atrost6e126252020-01-27 17:01:16 +00001642func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1643 dirInApex := filepath.Join("etc", config.SubDir())
1644 fileToCopy := config.CompatConfig()
1645 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1646}
1647
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001648// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1649// way.
1650type javaModule interface {
1651 android.Module
1652 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001653 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001654 JacocoReportClassesFile() android.Path
1655 LintDepSets() java.LintDepSets
1656 Stem() string
1657}
1658
1659var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001660var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001661var _ javaModule = (*java.SdkLibrary)(nil)
1662var _ javaModule = (*java.DexImport)(nil)
1663var _ javaModule = (*java.SdkLibraryImport)(nil)
1664
Paul Duffin190fdef2021-04-26 10:33:59 +01001665// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001666func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001667 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001668}
1669
1670// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1671func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001672 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001673 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001674 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1675 af.lintDepSets = module.LintDepSets()
1676 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001677 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1678 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1679 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1680 }
1681 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001682 return af
1683}
1684
1685// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1686// the same way.
1687type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001688 android.Module
1689 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001690 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001691 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001692 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001693 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001694 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001695 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001696}
1697
1698var _ androidApp = (*java.AndroidApp)(nil)
1699var _ androidApp = (*java.AndroidAppImport)(nil)
1700
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001701func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1702 buildId := ctx.Config().BuildId()
1703
1704 // The build ID is used as a suffix for a filename, so ensure that
1705 // the set of characters being used are sanitized.
1706 // - any word character: [a-zA-Z0-9_]
1707 // - dots: .
1708 // - dashes: -
1709 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1710 if !validRegex.MatchString(buildId) {
1711 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1712 }
1713 return buildId
1714}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001715
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001716func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001717 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001718 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001719 appDir = "priv-app"
1720 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001721
1722 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1723 // so that PackageManager correctly invalidates the existing installed apk
1724 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001725 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001726 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001727
Yo Chiange8128052020-07-23 20:09:18 +08001728 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001729 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001730 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001731 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001732
1733 if app, ok := aapp.(interface {
1734 OverriddenManifestPackageName() string
1735 }); ok {
1736 af.overriddenPackageName = app.OverriddenManifestPackageName()
1737 }
Jiyong Park618922e2020-01-08 13:35:43 +09001738 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001739}
1740
Jiyong Park69aeba92020-04-24 21:16:36 +09001741func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1742 rroDir := "overlay"
1743 dirInApex := filepath.Join(rroDir, rro.Theme())
1744 fileToCopy := rro.OutputFile()
1745 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1746 af.certificate = rro.Certificate()
1747
1748 if a, ok := rro.(interface {
1749 OverriddenManifestPackageName() string
1750 }); ok {
1751 af.overriddenPackageName = a.OverriddenManifestPackageName()
1752 }
1753 return af
1754}
1755
Ken Chenfad7f9d2021-11-10 22:02:57 +08001756func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1757 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001758 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1759}
1760
Jiyong Park12a719c2021-01-07 15:31:24 +09001761func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1762 dirInApex := filepath.Join("etc", "fs")
1763 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1764}
1765
Paul Duffin064b70c2020-11-02 17:32:38 +00001766// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001767// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1768// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1769// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001770func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001771 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001772 am, ok := child.(android.ApexModule)
1773 if !ok || !am.CanHaveApexVariants() {
1774 return false
1775 }
1776
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001777 // Filter-out unwanted depedendencies
1778 depTag := ctx.OtherModuleDependencyTag(child)
1779 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1780 return false
1781 }
Paul Duffin520917a2022-05-13 13:01:59 +00001782 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001783 return false
1784 }
1785
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001786 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001787 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001788
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001789 // Visit actually
1790 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001791 })
1792}
1793
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001794// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1795type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001796
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001797const (
1798 ext4 fsType = iota
1799 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001800 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001801)
Artur Satayev849f8442020-04-28 14:57:42 +01001802
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001803func (f fsType) string() string {
1804 switch f {
1805 case ext4:
1806 return ext4FsType
1807 case f2fs:
1808 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001809 case erofs:
1810 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001811 default:
1812 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001813 }
1814}
1815
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001816var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1817
1818func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1819 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1820}
1821
1822func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1823 bazelCtx := ctx.Config().BazelContext
1824 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1825}
1826
1827func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1828 if !a.commonBuildActions(ctx) {
1829 return
1830 }
1831
1832 a.setApexTypeAndSuffix(ctx)
1833 a.setPayloadFsType(ctx)
1834 a.setSystemLibLink(ctx)
1835
1836 if a.properties.ApexType != zipApex {
1837 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1838 }
1839
1840 bazelCtx := ctx.Config().BazelContext
1841 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1842 if err != nil {
1843 ctx.ModuleErrorf(err.Error())
1844 return
1845 }
1846 a.installDir = android.PathForModuleInstall(ctx, "apex")
1847 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1848 a.outputFile = a.outputApexFile
1849 a.setCompression(ctx)
1850
1851 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[0])
1852 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[1])
1853 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[0])
1854 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[1])
1855 apexType := a.properties.ApexType
1856 switch apexType {
1857 case imageApex:
1858 // TODO(asmundak): Bazel does not create these files yet.
1859 // b/190817312
1860 a.htmlGzNotice = android.PathForBazelOut(ctx, "NOTICE.html.gz")
1861 // b/239081457
1862 a.bundleModuleFile = android.PathForBazelOut(ctx, a.Name()+apexType.suffix()+"-base.zip")
1863 // b/239081455
1864 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.txt"))
1865 // b/239081456
1866 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_backing.txt"))
1867 // b/239084755
1868 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.xml"))
1869 installSuffix := imageApexSuffix
1870 if a.isCompressed {
1871 installSuffix = imageCapexSuffix
1872 }
1873 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1874 a.compatSymlinks.Paths()...)
1875 default:
1876 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1877 }
1878
1879 /*
1880 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1881 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1882 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1883 To find out what Soong build puts there, run:
1884 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1885 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1886 return a.depVisitor(&vctx, ctx, child, parent)
1887 })
1888 vctx.normalizeFileInfo()
1889 */
1890
1891}
1892
1893func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1894 if a.properties.ApexType != imageApex {
1895 a.isCompressed = false
1896 } else if a.testOnlyShouldForceCompression() {
1897 a.isCompressed = true
1898 } else {
1899 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1900 }
1901}
1902
1903func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1904 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1905 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1906 // the same library in the system partition, thus effectively sharing the same libraries
1907 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1908 // in the APEX.
1909 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1910
1911 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1912 // So we can't link them to /system/lib libs which are core variants.
1913 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1914 a.linkToSystemLib = false
1915 }
1916
1917 forced := ctx.Config().ForceApexSymlinkOptimization()
1918 updatable := a.Updatable() || a.FutureUpdatable()
1919
1920 // We don't need the optimization for updatable APEXes, as it might give false signal
1921 // to the system health when the APEXes are still bundled (b/149805758).
1922 if !forced && updatable && a.properties.ApexType == imageApex {
1923 a.linkToSystemLib = false
1924 }
1925
1926 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1927 if ctx.Host() {
1928 a.linkToSystemLib = false
1929 }
1930}
1931
1932func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1933 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
1934 case ext4FsType:
1935 a.payloadFsType = ext4
1936 case f2fsFsType:
1937 a.payloadFsType = f2fs
1938 case erofsFsType:
1939 a.payloadFsType = erofs
1940 default:
1941 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
1942 }
1943}
1944
1945func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
1946 // Set suffix and primaryApexType depending on the ApexType
1947 buildFlattenedAsDefault := ctx.Config().FlattenApex()
1948 switch a.properties.ApexType {
1949 case imageApex:
1950 if buildFlattenedAsDefault {
1951 a.suffix = imageApexSuffix
1952 } else {
1953 a.suffix = ""
1954 a.primaryApexType = true
1955
1956 if ctx.Config().InstallExtraFlattenedApexes() {
1957 a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
1958 }
1959 }
1960 case zipApex:
1961 if proptools.String(a.properties.Payload_type) == "zip" {
1962 a.suffix = ""
1963 a.primaryApexType = true
1964 } else {
1965 a.suffix = zipApexSuffix
1966 }
1967 case flattenedApex:
1968 if buildFlattenedAsDefault {
1969 a.suffix = ""
1970 a.primaryApexType = true
1971 } else {
1972 a.suffix = flattenedSuffix
1973 }
1974 }
1975}
1976
1977func (a apexBundle) isCompressable() bool {
1978 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
1979}
1980
1981func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
1982 a.checkApexAvailability(ctx)
1983 a.checkUpdatable(ctx)
1984 a.CheckMinSdkVersion(ctx)
1985 a.checkStaticLinkingToStubLibraries(ctx)
1986 a.checkStaticExecutables(ctx)
1987 if len(a.properties.Tests) > 0 && !a.testApex {
1988 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
1989 return false
1990 }
1991 return true
1992}
1993
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001994type visitorContext struct {
1995 // all the files that will be included in this APEX
1996 filesInfo []apexFile
1997
1998 // native lib dependencies
1999 provideNativeLibs []string
2000 requireNativeLibs []string
2001
2002 handleSpecialLibs bool
2003}
2004
2005func (vctx *visitorContext) normalizeFileInfo() {
2006 encountered := make(map[string]apexFile)
2007 for _, f := range vctx.filesInfo {
2008 dest := filepath.Join(f.installDir, f.builtFile.Base())
2009 if e, ok := encountered[dest]; !ok {
2010 encountered[dest] = f
2011 } else {
2012 // If a module is directly included and also transitively depended on
2013 // consider it as directly included.
2014 e.transitiveDep = e.transitiveDep && f.transitiveDep
2015 encountered[dest] = e
2016 }
2017 }
2018 vctx.filesInfo = vctx.filesInfo[:0]
2019 for _, v := range encountered {
2020 vctx.filesInfo = append(vctx.filesInfo, v)
2021 }
2022 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2023 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2024 // changes.
2025 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2026 })
2027}
2028
2029func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2030 depTag := ctx.OtherModuleDependencyTag(child)
2031 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2032 return false
2033 }
2034 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2035 return false
2036 }
2037 depName := ctx.OtherModuleName(child)
2038 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2039 switch depTag {
2040 case sharedLibTag, jniLibTag:
2041 isJniLib := depTag == jniLibTag
2042 switch ch := child.(type) {
2043 case *cc.Module:
2044 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2045 fi.isJniLib = isJniLib
2046 vctx.filesInfo = append(vctx.filesInfo, fi)
2047 // Collect the list of stub-providing libs except:
2048 // - VNDK libs are only for vendors
2049 // - bootstrap bionic libs are treated as provided by system
2050 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2051 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2052 }
2053 return true // track transitive dependencies
2054 case *rust.Module:
2055 fi := apexFileForRustLibrary(ctx, ch)
2056 fi.isJniLib = isJniLib
2057 vctx.filesInfo = append(vctx.filesInfo, fi)
2058 return true // track transitive dependencies
2059 default:
2060 propertyName := "native_shared_libs"
2061 if isJniLib {
2062 propertyName = "jni_libs"
2063 }
2064 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2065 }
2066 case executableTag:
2067 switch ch := child.(type) {
2068 case *cc.Module:
2069 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2070 return true // track transitive dependencies
2071 case *python.Module:
2072 if ch.HostToolPath().Valid() {
2073 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2074 }
2075 case bootstrap.GoBinaryTool:
2076 if a.Host() {
2077 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2078 }
2079 case *rust.Module:
2080 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2081 return true // track transitive dependencies
2082 default:
2083 ctx.PropertyErrorf("binaries",
2084 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2085 }
2086 case shBinaryTag:
2087 if csh, ok := child.(*sh.ShBinary); ok {
2088 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2089 } else {
2090 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2091 }
2092 case bcpfTag:
2093 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2094 if !ok {
2095 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2096 return false
2097 }
2098
2099 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2100 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
2101 a.requiredDeps = append(a.requiredDeps, makeModuleName)
2102 }
2103 return true
2104 case sscpfTag:
2105 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2106 ctx.PropertyErrorf("systemserverclasspath_fragments",
2107 "%q is not a systemserverclasspath_fragment module", depName)
2108 return false
2109 }
2110 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2111 vctx.filesInfo = append(vctx.filesInfo, *af)
2112 }
2113 return true
2114 case javaLibTag:
2115 switch child.(type) {
2116 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2117 af := apexFileForJavaModule(ctx, child.(javaModule))
2118 if !af.ok() {
2119 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2120 return false
2121 }
2122 vctx.filesInfo = append(vctx.filesInfo, af)
2123 return true // track transitive dependencies
2124 default:
2125 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2126 }
2127 case androidAppTag:
2128 switch ap := child.(type) {
2129 case *java.AndroidApp:
2130 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2131 return true // track transitive dependencies
2132 case *java.AndroidAppImport:
2133 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2134 case *java.AndroidTestHelperApp:
2135 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2136 case *java.AndroidAppSet:
2137 appDir := "app"
2138 if ap.Privileged() {
2139 appDir = "priv-app"
2140 }
2141 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2142 // suffixed so that PackageManager correctly invalidates the
2143 // existing installed apk in favour of the new APK-in-APEX.
2144 // See bugs for more information.
2145 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2146 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2147 af.certificate = java.PresignedCertificate
2148 vctx.filesInfo = append(vctx.filesInfo, af)
2149 default:
2150 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2151 }
2152 case rroTag:
2153 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2154 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2155 } else {
2156 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2157 }
2158 case bpfTag:
2159 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2160 filesToCopy, _ := bpfProgram.OutputFiles("")
2161 apex_sub_dir := bpfProgram.SubDir()
2162 for _, bpfFile := range filesToCopy {
2163 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2164 }
2165 } else {
2166 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2167 }
2168 case fsTag:
2169 if fs, ok := child.(filesystem.Filesystem); ok {
2170 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2171 } else {
2172 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2173 }
2174 case prebuiltTag:
2175 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2176 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2177 } else {
2178 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2179 }
2180 case compatConfigTag:
2181 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2182 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2183 } else {
2184 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2185 }
2186 case testTag:
2187 if ccTest, ok := child.(*cc.Module); ok {
2188 if ccTest.IsTestPerSrcAllTestsVariation() {
2189 // Multiple-output test module (where `test_per_src: true`).
2190 //
2191 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2192 // We do not add this variation to `filesInfo`, as it has no output;
2193 // however, we do add the other variations of this module as indirect
2194 // dependencies (see below).
2195 } else {
2196 // Single-output test module (where `test_per_src: false`).
2197 af := apexFileForExecutable(ctx, ccTest)
2198 af.class = nativeTest
2199 vctx.filesInfo = append(vctx.filesInfo, af)
2200 }
2201 return true // track transitive dependencies
2202 } else {
2203 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2204 }
2205 case keyTag:
2206 if key, ok := child.(*apexKey); ok {
2207 a.privateKeyFile = key.privateKeyFile
2208 a.publicKeyFile = key.publicKeyFile
2209 } else {
2210 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2211 }
2212 case certificateTag:
2213 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2214 a.containerCertificateFile = dep.Certificate.Pem
2215 a.containerPrivateKeyFile = dep.Certificate.Key
2216 } else {
2217 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2218 }
2219 case android.PrebuiltDepTag:
2220 // If the prebuilt is force disabled, remember to delete the prebuilt file
2221 // that might have been installed in the previous builds
2222 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2223 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2224 }
2225 }
2226 return false
2227 }
2228
2229 if a.vndkApex {
2230 return false
2231 }
2232
2233 // indirect dependencies
2234 am, ok := child.(android.ApexModule)
2235 if !ok {
2236 return false
2237 }
2238 // We cannot use a switch statement on `depTag` here as the checked
2239 // tags used below are private (e.g. `cc.sharedDepTag`).
2240 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2241 if ch, ok := child.(*cc.Module); ok {
2242 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2243 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2244 return false
2245 }
2246 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2247 af.transitiveDep = true
2248
2249 // Always track transitive dependencies for host.
2250 if a.Host() {
2251 vctx.filesInfo = append(vctx.filesInfo, af)
2252 return true
2253 }
2254
2255 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2256 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2257 // If the dependency is a stubs lib, don't include it in this APEX,
2258 // but make sure that the lib is installed on the device.
2259 // In case no APEX is having the lib, the lib is installed to the system
2260 // partition.
2261 //
2262 // Always include if we are a host-apex however since those won't have any
2263 // system libraries.
2264 if !am.DirectlyInAnyApex() {
2265 // we need a module name for Make
2266 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2267 if !android.InList(name, a.requiredDeps) {
2268 a.requiredDeps = append(a.requiredDeps, name)
2269 }
2270 }
2271 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2272 // Don't track further
2273 return false
2274 }
2275
2276 // If the dep is not considered to be in the same
2277 // apex, don't add it to filesInfo so that it is not
2278 // included in this APEX.
2279 // TODO(jiyong): move this to at the top of the
2280 // else-if clause for the indirect dependencies.
2281 // Currently, that's impossible because we would
2282 // like to record requiredNativeLibs even when
2283 // DepIsInSameAPex is false. We also shouldn't do
2284 // this for host.
2285 //
2286 // TODO(jiyong): explain why the same module is passed in twice.
2287 // Switching the first am to parent breaks lots of tests.
2288 if !android.IsDepInSameApex(ctx, am, am) {
2289 return false
2290 }
2291
2292 vctx.filesInfo = append(vctx.filesInfo, af)
2293 return true // track transitive dependencies
2294 } else if rm, ok := child.(*rust.Module); ok {
2295 af := apexFileForRustLibrary(ctx, rm)
2296 af.transitiveDep = true
2297 vctx.filesInfo = append(vctx.filesInfo, af)
2298 return true // track transitive dependencies
2299 }
2300 } else if cc.IsTestPerSrcDepTag(depTag) {
2301 if ch, ok := child.(*cc.Module); ok {
2302 af := apexFileForExecutable(ctx, ch)
2303 // Handle modules created as `test_per_src` variations of a single test module:
2304 // use the name of the generated test binary (`fileToCopy`) instead of the name
2305 // of the original test module (`depName`, shared by all `test_per_src`
2306 // variations of that module).
2307 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2308 // these are not considered transitive dep
2309 af.transitiveDep = false
2310 vctx.filesInfo = append(vctx.filesInfo, af)
2311 return true // track transitive dependencies
2312 }
2313 } else if cc.IsHeaderDepTag(depTag) {
2314 // nothing
2315 } else if java.IsJniDepTag(depTag) {
2316 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2317 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2318 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2319 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2320 }
2321 } else if rust.IsDylibDepTag(depTag) {
2322 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2323 af := apexFileForRustLibrary(ctx, rustm)
2324 af.transitiveDep = true
2325 vctx.filesInfo = append(vctx.filesInfo, af)
2326 return true // track transitive dependencies
2327 }
2328 } else if rust.IsRlibDepTag(depTag) {
2329 // Rlib is statically linked, but it might have shared lib
2330 // dependencies. Track them.
2331 return true
2332 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2333 // Add the contents of the bootclasspath fragment to the apex.
2334 switch child.(type) {
2335 case *java.Library, *java.SdkLibrary:
2336 javaModule := child.(javaModule)
2337 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2338 if !af.ok() {
2339 ctx.PropertyErrorf("bootclasspath_fragments",
2340 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2341 return false
2342 }
2343 vctx.filesInfo = append(vctx.filesInfo, af)
2344 return true // track transitive dependencies
2345 default:
2346 ctx.PropertyErrorf("bootclasspath_fragments",
2347 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2348 }
2349 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2350 // Add the contents of the systemserverclasspath fragment to the apex.
2351 switch child.(type) {
2352 case *java.Library, *java.SdkLibrary:
2353 af := apexFileForJavaModule(ctx, child.(javaModule))
2354 vctx.filesInfo = append(vctx.filesInfo, af)
2355 return true // track transitive dependencies
2356 default:
2357 ctx.PropertyErrorf("systemserverclasspath_fragments",
2358 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2359 }
2360 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2361 // nothing
2362 } else if depTag == android.DarwinUniversalVariantTag {
2363 // nothing
2364 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2365 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2366 }
2367 return false
2368}
2369
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002370// Creates build rules for an APEX. It consists of the following major steps:
2371//
2372// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2373// 2) traverse the dependency tree to collect apexFile structs from them.
2374// 3) some fields in apexBundle struct are configured
2375// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002376func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002377 ////////////////////////////////////////////////////////////////////////////////////////////
2378 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002379 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002380 return
2381 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002382 ////////////////////////////////////////////////////////////////////////////////////////////
2383 // 2) traverse the dependency tree to collect apexFile structs from them.
2384
braleeb0c1f0c2021-06-07 22:49:13 +08002385 // Collect the module directory for IDE info in java/jdeps.go.
2386 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2387
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002388 // TODO(jiyong): do this using WalkPayloadDeps
2389 // TODO(jiyong): make this clean!!!
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002390 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2391 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
2392 vctx.normalizeFileInfo()
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002393 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002394 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002395 return
2396 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002397
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002398 ////////////////////////////////////////////////////////////////////////////////////////////
2399 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002400 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002401 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002402
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002403 a.setApexTypeAndSuffix(ctx)
2404 a.setPayloadFsType(ctx)
2405 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002406 if a.properties.ApexType != zipApex {
2407 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2408 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002409
2410 ////////////////////////////////////////////////////////////////////////////////////////////
2411 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002412 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002413 if a.properties.ApexType == flattenedApex {
2414 a.buildFlattenedApex(ctx)
2415 } else {
2416 a.buildUnflattenedApex(ctx)
2417 }
Jiyong Park956305c2020-01-09 12:32:06 +09002418 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002419 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002420
2421 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2422 if a.installable() {
2423 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2424 // along with other ordinary files. (Note that this is done by apexer for
2425 // non-flattened APEXes)
2426 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2427
2428 // Place the public key as apex_pubkey. This is also done by apexer for
2429 // non-flattened APEXes case.
2430 // TODO(jiyong): Why do we need this CP rule?
2431 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2432 ctx.Build(pctx, android.BuildParams{
2433 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002434 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002435 Output: copiedPubkey,
2436 })
2437 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2438 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002439}
2440
Paul Duffincc33ec82021-04-25 23:14:55 +01002441// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2442// the bootclasspath_fragment contributes to the apex.
2443func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2444 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2445 var filesToAdd []apexFile
2446
2447 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002448 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2449 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2450 dirInApex := filepath.Join("javalib", arch.String())
2451 for _, f := range files {
2452 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2453 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2454 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2455 filesToAdd = append(filesToAdd, af)
2456 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002457 }
2458 }
2459
satayev3db35472021-05-06 23:59:58 +01002460 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002461 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2462 filesToAdd = append(filesToAdd, *af)
2463 }
satayev3db35472021-05-06 23:59:58 +01002464
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002465 if pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex(); pathInApex != "" {
2466 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2467 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2468
2469 if pathOnHost != nil {
2470 // We need to copy the profile to a temporary path with the right filename because the apexer
2471 // will take the filename as is.
2472 ctx.Build(pctx, android.BuildParams{
2473 Rule: android.Cp,
2474 Input: pathOnHost,
2475 Output: tempPath,
2476 })
2477 } else {
2478 // At this point, the boot image profile cannot be generated. It is probably because the boot
2479 // image profile source file does not exist on the branch, or it is not available for the
2480 // current build target.
2481 // However, we cannot enforce the boot image profile to be generated because some build
2482 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2483 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2484 // only if the APEX is being built.
2485 ctx.Build(pctx, android.BuildParams{
2486 Rule: android.ErrorRule,
2487 Output: tempPath,
2488 Args: map[string]string{
2489 "error": "Boot image profile cannot be generated",
2490 },
2491 })
2492 }
2493
2494 androidMkModuleName := filepath.Base(pathInApex)
2495 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2496 filesToAdd = append(filesToAdd, af)
2497 }
2498
Paul Duffincc33ec82021-04-25 23:14:55 +01002499 return filesToAdd
2500}
2501
satayevb98371c2021-06-15 16:49:50 +01002502// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2503// the module contributes to the apex; or nil if the proto config was not generated.
2504func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2505 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2506 if !info.ClasspathFragmentProtoGenerated {
2507 return nil
2508 }
2509 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2510 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2511 return &af
satayev14e49132021-05-17 21:03:07 +01002512}
2513
Paul Duffincc33ec82021-04-25 23:14:55 +01002514// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2515// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002516func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2517 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2518
2519 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2520 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002521 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2522 if err != nil {
2523 ctx.ModuleErrorf("%s", err)
2524 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002525
2526 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2527 // bootclasspath_fragment.
2528 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2529 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002530}
2531
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002532///////////////////////////////////////////////////////////////////////////////////////////////////
2533// Factory functions
2534//
2535
2536func newApexBundle() *apexBundle {
2537 module := &apexBundle{}
2538
2539 module.AddProperties(&module.properties)
2540 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002541 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002542 module.AddProperties(&module.overridableProperties)
2543
2544 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2545 android.InitDefaultableModule(module)
2546 android.InitSdkAwareModule(module)
2547 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002548 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002549 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002550 return module
2551}
2552
Paul Duffineb8051d2021-10-18 17:49:39 +01002553func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002554 bundle := newApexBundle()
2555 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002556 return bundle
2557}
2558
2559// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2560// certain compatibility checks such as apex_available are not done for apex_test.
2561func testApexBundleFactory() android.Module {
2562 bundle := newApexBundle()
2563 bundle.testApex = true
2564 return bundle
2565}
2566
2567// apex packages other modules into an APEX file which is a packaging format for system-level
2568// components like binaries, shared libraries, etc.
2569func BundleFactory() android.Module {
2570 return newApexBundle()
2571}
2572
2573type Defaults struct {
2574 android.ModuleBase
2575 android.DefaultsModuleBase
2576}
2577
2578// apex_defaults provides defaultable properties to other apex modules.
2579func defaultsFactory() android.Module {
2580 return DefaultsFactory()
2581}
2582
2583func DefaultsFactory(props ...interface{}) android.Module {
2584 module := &Defaults{}
2585
2586 module.AddProperties(props...)
2587 module.AddProperties(
2588 &apexBundleProperties{},
2589 &apexTargetBundleProperties{},
2590 &overridableProperties{},
2591 )
2592
2593 android.InitDefaultsModule(module)
2594 return module
2595}
2596
2597type OverrideApex struct {
2598 android.ModuleBase
2599 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002600 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002601}
2602
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002603func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002604 // All the overrides happen in the base module.
2605}
2606
2607// override_apex is used to create an apex module based on another apex module by overriding some of
2608// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002609func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002610 m := &OverrideApex{}
2611
2612 m.AddProperties(&overridableProperties{})
2613
2614 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2615 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002616 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002617 return m
2618}
2619
Wei Li1c66fc72022-05-09 23:59:14 -07002620func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2621 if ctx.ModuleType() != "override_apex" {
2622 return
2623 }
2624
2625 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2626 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2627 if !baseApexExists {
2628 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2629 }
2630
2631 a, baseModuleIsApex := baseModule.(*apexBundle)
2632 if !baseModuleIsApex {
2633 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2634 }
2635 attrs, props := convertWithBp2build(a, ctx)
2636
2637 for _, p := range o.GetProperties() {
2638 overridableProperties, ok := p.(*overridableProperties)
2639 if !ok {
2640 continue
2641 }
Wei Li40f98732022-05-20 22:08:11 -07002642
2643 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2644 // After it is converted in convertWithBp2build(baseApex, ctx),
2645 // the attrs.Manifest.Value.Label is the file path relative to the directory
2646 // of base apex. So the following code converts it to a label that looks like
2647 // <package of base apex>:<path of manifest file> if base apex and override
2648 // apex are not in the same package.
2649 baseApexPackage := ctx.OtherModuleDir(a)
2650 overrideApexPackage := ctx.ModuleDir()
2651 if baseApexPackage != overrideApexPackage {
2652 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2653 }
2654
Wei Li1c66fc72022-05-09 23:59:14 -07002655 // Key
2656 if overridableProperties.Key != nil {
2657 attrs.Key = bazel.LabelAttribute{}
2658 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2659 }
2660
2661 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002662 if overridableProperties.Certificate == nil {
2663 // delegated to the rule attr default
2664 attrs.Certificate = nil
2665 } else {
2666 certificateName, certificate := java.ParseCertificateToAttribute(ctx, overridableProperties.Certificate)
2667 attrs.Certificate_name = certificateName
2668 attrs.Certificate = certificate
Wei Li1c66fc72022-05-09 23:59:14 -07002669 }
2670
2671 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002672 if overridableProperties.Prebuilts != nil {
2673 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2674 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2675 }
Wei Li1c66fc72022-05-09 23:59:14 -07002676
2677 // Compressible
2678 if overridableProperties.Compressible != nil {
2679 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2680 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002681
2682 // Package name
2683 //
2684 // e.g. com.android.adbd's package name is com.android.adbd, but
2685 // com.google.android.adbd overrides the package name to com.google.android.adbd
2686 //
2687 // TODO: this can be overridden from the product configuration, see
2688 // getOverrideManifestPackageName and
2689 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2690 //
2691 // Instead of generating the BUILD files differently based on the product config
2692 // at the point of conversion, this should be handled by the BUILD file loading
2693 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2694 if overridableProperties.Package_name != "" {
2695 attrs.Package_name = &overridableProperties.Package_name
2696 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002697
2698 // Logging parent
2699 if overridableProperties.Logging_parent != "" {
2700 attrs.Logging_parent = &overridableProperties.Logging_parent
2701 }
Wei Li1c66fc72022-05-09 23:59:14 -07002702 }
2703
2704 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2705}
2706
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002707///////////////////////////////////////////////////////////////////////////////////////////////////
2708// Vality check routines
2709//
2710// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2711// certain conditions are not met.
2712//
2713// TODO(jiyong): move these checks to a separate go file.
2714
satayevad991492021-12-03 18:58:32 +00002715var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2716
Spandan Dasa5f39a12022-08-05 02:35:52 +00002717// 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 +09002718// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002719func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002720 if a.testApex || a.vndkApex {
2721 return
2722 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002723 // apexBundle::minSdkVersion reports its own errors.
2724 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002725 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002726}
2727
Albert Martineefabcf2022-03-21 20:11:16 +00002728// Returns apex's min_sdk_version string value, honoring overrides
2729func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2730 // Only override the minSdkVersion value on Apexes which already specify
2731 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2732 // min_sdk_version value is lower than the one to override with.
2733 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2734 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2735 originalMinApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2736 isMinSdkSet := a.properties.Min_sdk_version != nil
2737 isOverrideValueHigher := overrideApiLevel.CompareTo(originalMinApiLevel) > 0
2738 if overrideMinSdkValue != "" && isMinSdkSet && isOverrideValueHigher {
2739 return overrideMinSdkValue
2740 }
2741
2742 return proptools.String(a.properties.Min_sdk_version)
2743}
2744
2745// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002746func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2747 return android.SdkSpec{
2748 Kind: android.SdkNone,
2749 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002750 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002751 }
2752}
2753
Albert Martineefabcf2022-03-21 20:11:16 +00002754// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002755func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002756 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2757}
2758
2759// Construct ApiLevel object from min_sdk_version string value
2760func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2761 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002762 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002763 }
Albert Martineefabcf2022-03-21 20:11:16 +00002764 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002765 if err != nil {
2766 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2767 return android.NoneApiLevel
2768 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002769 return apiLevel
2770}
2771
2772// Ensures that a lib providing stub isn't statically linked
2773func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2774 // Practically, we only care about regular APEXes on the device.
2775 if ctx.Host() || a.testApex || a.vndkApex {
2776 return
2777 }
2778
2779 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2780
2781 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2782 if ccm, ok := to.(*cc.Module); ok {
2783 apexName := ctx.ModuleName()
2784 fromName := ctx.OtherModuleName(from)
2785 toName := ctx.OtherModuleName(to)
2786
2787 // If `to` is not actually in the same APEX as `from` then it does not need
2788 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002789 //
2790 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002791 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2792 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2793 return false
2794 }
2795
2796 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2797 // exception to this rule. It can't make the static dependencies dynamic
2798 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002799 // Same rule should be applied to linkerconfig, because it should be executed
2800 // only with static linked libraries before linker is available with ld.config.txt
2801 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002802 return false
2803 }
2804
2805 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2806 if isStubLibraryFromOtherApex && !externalDep {
2807 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2808 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2809 }
2810
2811 }
2812 return true
2813 })
2814}
2815
satayevb98371c2021-06-15 16:49:50 +01002816// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002817func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2818 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002819 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002820 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2821 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002822 if a.UsePlatformApis() {
2823 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2824 }
Daniel Norman69109112021-12-02 12:52:42 -08002825 if a.SocSpecific() || a.DeviceSpecific() {
2826 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2827 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002828 if a.FutureUpdatable() {
2829 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2830 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002831 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002832 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002833 }
2834}
2835
satayevb98371c2021-06-15 16:49:50 +01002836// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2837func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2838 ctx.VisitDirectDeps(func(module android.Module) {
2839 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2840 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2841 if !info.ClasspathFragmentProtoGenerated {
2842 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2843 }
2844 }
2845 })
2846}
2847
2848// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002849func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002850 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2851 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002852 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2853 tag := ctx.OtherModuleDependencyTag(module)
2854 switch tag {
2855 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002856 if m, ok := module.(interface {
2857 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2858 }); ok {
2859 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002860 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2861 }
2862 }
2863 }
2864 })
2865}
2866
satayevb98371c2021-06-15 16:49:50 +01002867// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002868func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2869 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2870 if ctx.Host() || a.testApex || a.vndkApex {
2871 return
2872 }
2873
2874 // Because APEXes targeting other than system/system_ext partitions can't set
2875 // apex_available, we skip checks for these APEXes
2876 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2877 return
2878 }
2879
2880 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2881 // Requiring them and their transitive depencies with apex_available is not right
2882 // because they just add noise.
2883 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2884 return
2885 }
2886
2887 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2888 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2889 if externalDep {
2890 return false
2891 }
2892
2893 apexName := ctx.ModuleName()
2894 fromName := ctx.OtherModuleName(from)
2895 toName := ctx.OtherModuleName(to)
2896
2897 // If `to` is not actually in the same APEX as `from` then it does not need
2898 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002899 //
2900 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002901 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2902 // As soon as the dependency graph crosses the APEX boundary, don't go
2903 // further.
2904 return false
2905 }
2906
2907 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
2908 return true
2909 }
Jiyong Park767dbd92021-03-04 13:03:10 +09002910 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2911 "\n\nDependency path:%s\n\n"+
2912 "Consider adding %q to 'apex_available' property of %q",
2913 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002914 // Visit this module's dependencies to check and report any issues with their availability.
2915 return true
2916 })
2917}
2918
Jiyong Park192600a2021-08-03 07:52:17 +00002919// checkStaticExecutable ensures that executables in an APEX are not static.
2920func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09002921 // No need to run this for host APEXes
2922 if ctx.Host() {
2923 return
2924 }
2925
Jiyong Park192600a2021-08-03 07:52:17 +00002926 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2927 if ctx.OtherModuleDependencyTag(module) != executableTag {
2928 return
2929 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09002930
2931 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00002932 apex := a.ApexVariationName()
2933 exec := ctx.OtherModuleName(module)
2934 if isStaticExecutableAllowed(apex, exec) {
2935 return
2936 }
2937 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
2938 }
2939 })
2940}
2941
2942// A small list of exceptions where static executables are allowed in APEXes.
2943func isStaticExecutableAllowed(apex string, exec string) bool {
2944 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07002945 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00002946 "linker",
2947 "linkerconfig",
2948 },
2949 }
2950 execNames, ok := m[apex]
2951 return ok && android.InList(exec, execNames)
2952}
2953
braleeb0c1f0c2021-06-07 22:49:13 +08002954// Collect information for opening IDE project files in java/jdeps.go.
2955func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09002956 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
2957 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
2958 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08002959 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
2960}
2961
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002962var (
2963 apexAvailBaseline = makeApexAvailableBaseline()
2964 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
2965)
2966
Colin Cross440e0d02020-06-11 11:32:11 -07002967func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002968 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002969 moduleName = normalizeModuleName(moduleName)
2970
Colin Cross440e0d02020-06-11 11:32:11 -07002971 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002972 return true
2973 }
2974
2975 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07002976 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002977 return true
2978 }
2979
2980 return false
2981}
2982
2983func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09002984 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
2985 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00002986 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09002987 if strings.HasPrefix(moduleName, "libclang_rt.") {
2988 // This module has many arch variants that depend on the product being built.
2989 // We don't want to list them all
2990 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002991 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09002992 if strings.HasPrefix(moduleName, "androidx.") {
2993 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
2994 moduleName = "androidx"
2995 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00002996 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00002997}
2998
Jiyong Park8e6d52f2020-11-19 14:37:47 +09002999// Transform the map of apex -> modules to module -> apexes.
3000func invertApexBaseline(m map[string][]string) map[string][]string {
3001 r := make(map[string][]string)
3002 for apex, modules := range m {
3003 for _, module := range modules {
3004 r[module] = append(r[module], apex)
3005 }
3006 }
3007 return r
3008}
3009
3010// Retrieve the baseline of apexes to which the supplied module belongs.
3011func BaselineApexAvailable(moduleName string) []string {
3012 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3013}
3014
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003015// This is a map from apex to modules, which overrides the apex_available setting for that
3016// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003017// TODO(b/147364041): remove this
3018func makeApexAvailableBaseline() map[string][]string {
3019 // The "Module separator"s below are employed to minimize merge conflicts.
3020 m := make(map[string][]string)
3021 //
3022 // Module separator
3023 //
3024 m["com.android.appsearch"] = []string{
3025 "icing-java-proto-lite",
3026 "libprotobuf-java-lite",
3027 }
3028 //
3029 // Module separator
3030 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003031 m["com.android.btservices"] = []string{
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003032 "bluetooth-protos-lite",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003033 "internal_include_headers",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003034 "libaudio-a2dp-hw-utils",
3035 "libaudio-hearing-aid-hw-utils",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003036 "libbluetooth",
3037 "libbluetooth-types",
3038 "libbluetooth-types-header",
3039 "libbluetooth_gd",
3040 "libbluetooth_headers",
3041 "libbluetooth_jni",
3042 "libbt-audio-hal-interface",
3043 "libbt-bta",
3044 "libbt-common",
3045 "libbt-hci",
3046 "libbt-platform-protos-lite",
3047 "libbt-protos-lite",
3048 "libbt-sbc-decoder",
3049 "libbt-sbc-encoder",
3050 "libbt-stack",
3051 "libbt-utils",
3052 "libbtcore",
3053 "libbtdevice",
3054 "libbte",
3055 "libbtif",
3056 "libchrome",
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003057 }
3058 //
3059 // Module separator
3060 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003061 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3062 //
3063 // Module separator
3064 //
3065 m["com.android.extservices"] = []string{
3066 "error_prone_annotations",
3067 "ExtServices-core",
3068 "ExtServices",
3069 "libtextclassifier-java",
3070 "libz_current",
3071 "textclassifier-statsd",
3072 "TextClassifierNotificationLibNoManifest",
3073 "TextClassifierServiceLibNoManifest",
3074 }
3075 //
3076 // Module separator
3077 //
3078 m["com.android.neuralnetworks"] = []string{
3079 "android.hardware.neuralnetworks@1.0",
3080 "android.hardware.neuralnetworks@1.1",
3081 "android.hardware.neuralnetworks@1.2",
3082 "android.hardware.neuralnetworks@1.3",
3083 "android.hidl.allocator@1.0",
3084 "android.hidl.memory.token@1.0",
3085 "android.hidl.memory@1.0",
3086 "android.hidl.safe_union@1.0",
3087 "libarect",
3088 "libbuildversion",
3089 "libmath",
3090 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003091 }
3092 //
3093 // Module separator
3094 //
3095 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003096 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003097 }
3098 //
3099 // Module separator
3100 //
3101 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003102 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003103 }
3104 //
3105 // Module separator
3106 //
3107 m["com.android.mediaprovider"] = []string{
3108 "MediaProvider",
3109 "MediaProviderGoogle",
3110 "fmtlib_ndk",
3111 "libbase_ndk",
3112 "libfuse",
3113 "libfuse_jni",
3114 }
3115 //
3116 // Module separator
3117 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003118 m["com.android.runtime"] = []string{
3119 "bionic_libc_platform_headers",
3120 "libarm-optimized-routines-math",
3121 "libc_aeabi",
3122 "libc_bionic",
3123 "libc_bionic_ndk",
3124 "libc_bootstrap",
3125 "libc_common",
3126 "libc_common_shared",
3127 "libc_common_static",
3128 "libc_dns",
3129 "libc_dynamic_dispatch",
3130 "libc_fortify",
3131 "libc_freebsd",
3132 "libc_freebsd_large_stack",
3133 "libc_gdtoa",
3134 "libc_init_dynamic",
3135 "libc_init_static",
3136 "libc_jemalloc_wrapper",
3137 "libc_netbsd",
3138 "libc_nomalloc",
3139 "libc_nopthread",
3140 "libc_openbsd",
3141 "libc_openbsd_large_stack",
3142 "libc_openbsd_ndk",
3143 "libc_pthread",
3144 "libc_static_dispatch",
3145 "libc_syscalls",
3146 "libc_tzcode",
3147 "libc_unwind_static",
3148 "libdebuggerd",
3149 "libdebuggerd_common_headers",
3150 "libdebuggerd_handler_core",
3151 "libdebuggerd_handler_fallback",
3152 "libdl_static",
3153 "libjemalloc5",
3154 "liblinker_main",
3155 "liblinker_malloc",
3156 "liblz4",
3157 "liblzma",
3158 "libprocinfo",
3159 "libpropertyinfoparser",
3160 "libscudo",
3161 "libstdc++",
3162 "libsystemproperties",
3163 "libtombstoned_client_static",
3164 "libunwindstack",
3165 "libz",
3166 "libziparchive",
3167 }
3168 //
3169 // Module separator
3170 //
3171 m["com.android.tethering"] = []string{
3172 "android.hardware.tetheroffload.config-V1.0-java",
3173 "android.hardware.tetheroffload.control-V1.0-java",
3174 "android.hidl.base-V1.0-java",
3175 "libcgrouprc",
3176 "libcgrouprc_format",
3177 "libtetherutilsjni",
3178 "libvndksupport",
3179 "net-utils-framework-common",
3180 "netd_aidl_interface-V3-java",
3181 "netlink-client",
3182 "networkstack-aidl-interfaces-java",
3183 "tethering-aidl-interfaces-java",
3184 "TetheringApiCurrentLib",
3185 }
3186 //
3187 // Module separator
3188 //
3189 m["com.android.wifi"] = []string{
3190 "PlatformProperties",
3191 "android.hardware.wifi-V1.0-java",
3192 "android.hardware.wifi-V1.0-java-constants",
3193 "android.hardware.wifi-V1.1-java",
3194 "android.hardware.wifi-V1.2-java",
3195 "android.hardware.wifi-V1.3-java",
3196 "android.hardware.wifi-V1.4-java",
3197 "android.hardware.wifi.hostapd-V1.0-java",
3198 "android.hardware.wifi.hostapd-V1.1-java",
3199 "android.hardware.wifi.hostapd-V1.2-java",
3200 "android.hardware.wifi.supplicant-V1.0-java",
3201 "android.hardware.wifi.supplicant-V1.1-java",
3202 "android.hardware.wifi.supplicant-V1.2-java",
3203 "android.hardware.wifi.supplicant-V1.3-java",
3204 "android.hidl.base-V1.0-java",
3205 "android.hidl.manager-V1.0-java",
3206 "android.hidl.manager-V1.1-java",
3207 "android.hidl.manager-V1.2-java",
3208 "bouncycastle-unbundled",
3209 "dnsresolver_aidl_interface-V2-java",
3210 "error_prone_annotations",
3211 "framework-wifi-pre-jarjar",
3212 "framework-wifi-util-lib",
3213 "ipmemorystore-aidl-interfaces-V3-java",
3214 "ipmemorystore-aidl-interfaces-java",
3215 "ksoap2",
3216 "libnanohttpd",
3217 "libwifi-jni",
3218 "net-utils-services-common",
3219 "netd_aidl_interface-V2-java",
3220 "netd_aidl_interface-unstable-java",
3221 "netd_event_listener_interface-java",
3222 "netlink-client",
3223 "networkstack-client",
3224 "services.net",
3225 "wifi-lite-protos",
3226 "wifi-nano-protos",
3227 "wifi-service-pre-jarjar",
3228 "wifi-service-resources",
3229 }
3230 //
3231 // Module separator
3232 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003233 m["com.android.os.statsd"] = []string{
3234 "libstatssocket",
3235 }
3236 //
3237 // Module separator
3238 //
3239 m[android.AvailableToAnyApex] = []string{
3240 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3241 "androidx",
3242 "androidx-constraintlayout_constraintlayout",
3243 "androidx-constraintlayout_constraintlayout-nodeps",
3244 "androidx-constraintlayout_constraintlayout-solver",
3245 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3246 "com.google.android.material_material",
3247 "com.google.android.material_material-nodeps",
3248
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003249 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003250 "libprofile-clang-extras",
3251 "libprofile-clang-extras_ndk",
3252 "libprofile-extras",
3253 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003254 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003255 }
3256 return m
3257}
3258
3259func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003260 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3261 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003262}
3263
Spandan Dasf14e2542021-11-12 00:01:37 +00003264func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3265 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3266 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003267 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003268 With("name", jar).
3269 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3270 Because(jar +
3271 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003272 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003273 " 1. If the offending code is from a statically linked library, consider " +
3274 "removing that dependency and using an alternative already in the " +
3275 "bootclasspath, or perhaps a shared library." +
3276 " 2. Move the offending code into an allowed package.\n" +
3277 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3278 "health implications of bundling that code, particularly if the offending jar " +
3279 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003280
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003281 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003282 }
3283 return rules
3284}
3285
Anton Hanssone1b18362021-12-23 15:05:38 +00003286// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003287// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003288func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003289 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003290 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003291 "android.net.ssl",
3292 "com.android.org.conscrypt",
3293 },
Wei Li40f98732022-05-20 22:08:11 -07003294 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003295 "android.media",
3296 },
3297 }
3298}
3299
Anton Hanssone1b18362021-12-23 15:05:38 +00003300// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003301// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003302func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003303 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003304 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003305 "android.provider",
3306 },
Wei Li40f98732022-05-20 22:08:11 -07003307 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003308 "android.permission",
3309 "android.app.role",
3310 "com.android.permission",
3311 "com.android.role",
3312 },
Wei Li40f98732022-05-20 22:08:11 -07003313 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003314 "android.os.ext",
3315 },
Wei Li40f98732022-05-20 22:08:11 -07003316 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003317 "android.app",
3318 "android.os",
3319 "android.util",
3320 "com.android.internal.statsd",
3321 "com.android.server.stats",
3322 },
Wei Li40f98732022-05-20 22:08:11 -07003323 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003324 "com.android.server.wifi",
3325 "com.android.wifi.x",
3326 "android.hardware.wifi",
3327 "android.net.wifi",
3328 },
Wei Li40f98732022-05-20 22:08:11 -07003329 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003330 "android.net",
3331 },
3332 }
3333}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003334
3335// For Bazel / bp2build
3336
3337type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003338 Manifest bazel.LabelAttribute
3339 Android_manifest bazel.LabelAttribute
3340 File_contexts bazel.LabelAttribute
3341 Key bazel.LabelAttribute
Jingwen Chenbea58092022-09-29 16:56:02 +00003342 Certificate *bazel.Label // used when the certificate prop is a module
3343 Certificate_name *string // used when the certificate prop is a string
Yu Liu4ae55d12022-01-05 17:17:23 -08003344 Min_sdk_version *string
3345 Updatable bazel.BoolAttribute
3346 Installable bazel.BoolAttribute
3347 Binaries bazel.LabelListAttribute
3348 Prebuilts bazel.LabelListAttribute
3349 Native_shared_libs_32 bazel.LabelListAttribute
3350 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003351 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003352 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003353 Logging_parent *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003354}
3355
3356type convertedNativeSharedLibs struct {
3357 Native_shared_libs_32 bazel.LabelListAttribute
3358 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003359}
3360
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003361// ConvertWithBp2build performs bp2build conversion of an apex
3362func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
3363 // We do not convert apex_test modules at this time
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003364 if ctx.ModuleType() != "apex" {
3365 return
3366 }
3367
Wei Li1c66fc72022-05-09 23:59:14 -07003368 attrs, props := convertWithBp2build(a, ctx)
3369 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, &attrs)
3370}
3371
3372func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003373 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003374 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003375
3376 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003377 if a.properties.AndroidManifest != nil {
3378 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003379 }
3380
3381 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003382 if a.properties.File_contexts == nil {
3383 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3384 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3385 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3386 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003387 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003388 } else {
3389 // File_contexts is a file
3390 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003391 }
3392
Albert Martineefabcf2022-03-21 20:11:16 +00003393 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3394 // given it's coming via config, we probably don't want to put it in here.
Liz Kammer46fb7ab2021-12-01 10:09:34 -05003395 var minSdkVersion *string
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003396 if a.properties.Min_sdk_version != nil {
3397 minSdkVersion = a.properties.Min_sdk_version
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003398 }
3399
3400 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003401 if a.overridableProperties.Key != nil {
3402 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003403 }
3404
Jingwen Chenbea58092022-09-29 16:56:02 +00003405 certificateName, certificate := java.ParseCertificateToAttribute(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003406
Yu Liu4ae55d12022-01-05 17:17:23 -08003407 nativeSharedLibs := &convertedNativeSharedLibs{
3408 Native_shared_libs_32: bazel.LabelListAttribute{},
3409 Native_shared_libs_64: bazel.LabelListAttribute{},
3410 }
3411 compileMultilib := "both"
3412 if a.CompileMultilib() != nil {
3413 compileMultilib = *a.CompileMultilib()
3414 }
3415
3416 // properties.Native_shared_libs is treated as "both"
3417 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3418 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3419 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3420 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3421 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003422
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003423 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003424 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3425 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3426
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003427 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003428 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003429
3430 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003431 if a.properties.Updatable != nil {
3432 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003433 }
3434
3435 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003436 if a.properties.Installable != nil {
3437 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003438 }
3439
Wei Lif034cb42022-01-19 15:54:31 -08003440 var compressibleAttribute bazel.BoolAttribute
3441 if a.overridableProperties.Compressible != nil {
3442 compressibleAttribute.Value = a.overridableProperties.Compressible
3443 }
3444
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003445 var packageName *string
3446 if a.overridableProperties.Package_name != "" {
3447 packageName = &a.overridableProperties.Package_name
3448 }
3449
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003450 var loggingParent *string
3451 if a.overridableProperties.Logging_parent != "" {
3452 loggingParent = &a.overridableProperties.Logging_parent
3453 }
3454
Wei Li1c66fc72022-05-09 23:59:14 -07003455 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003456 Manifest: manifestLabelAttribute,
3457 Android_manifest: androidManifestLabelAttribute,
3458 File_contexts: fileContextsLabelAttribute,
3459 Min_sdk_version: minSdkVersion,
3460 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003461 Certificate: certificate,
3462 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003463 Updatable: updatableAttribute,
3464 Installable: installableAttribute,
3465 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3466 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3467 Binaries: binariesLabelListAttribute,
3468 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003469 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003470 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003471 Logging_parent: loggingParent,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003472 }
3473
3474 props := bazel.BazelTargetModuleProperties{
3475 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003476 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003477 }
3478
Wei Li1c66fc72022-05-09 23:59:14 -07003479 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003480}
Yu Liu4ae55d12022-01-05 17:17:23 -08003481
3482// The following conversions are based on this table where the rows are the compile_multilib
3483// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3484// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3485// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3486// should not be compiled.
3487// multib/compile_multilib, 32, 64, both, first
3488// 32, 32/32, none/none, 32/32, none/32
3489// 64, none/none, 64/none, 64/none, 64/none
3490// both, 32/32, 64/none, 32&64/32, 64/32
3491// first, 32/32, 64/none, 64/32, 64/32
3492
3493func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3494 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3495 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3496 switch compileMultilb {
3497 case "both", "32":
3498 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3499 case "first":
3500 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3501 case "64":
3502 // Incompatible, ignore
3503 default:
3504 invalidCompileMultilib(ctx, compileMultilb)
3505 }
3506}
3507
3508func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3509 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3510 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3511 switch compileMultilb {
3512 case "both", "64", "first":
3513 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3514 case "32":
3515 // Incompatible, ignore
3516 default:
3517 invalidCompileMultilib(ctx, compileMultilb)
3518 }
3519}
3520
3521func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3522 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3523 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3524 switch compileMultilb {
3525 case "both":
3526 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3527 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3528 case "first":
3529 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3530 case "32":
3531 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3532 case "64":
3533 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3534 default:
3535 invalidCompileMultilib(ctx, compileMultilb)
3536 }
3537}
3538
3539func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3540 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3541 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3542 switch compileMultilb {
3543 case "both", "first":
3544 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3545 case "32":
3546 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3547 case "64":
3548 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3549 default:
3550 invalidCompileMultilib(ctx, compileMultilb)
3551 }
3552}
3553
3554func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3555 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3556 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3557}
3558
3559func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3560 list := bazel.LabelListAttribute{}
3561 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3562 nativeSharedLibs.Native_shared_libs_32.Append(list)
3563}
3564
3565func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3566 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3567 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3568}
3569
3570func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3571 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3572 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3573}
3574
3575func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3576 labelListAttr *bazel.LabelListAttribute) {
3577 list := bazel.LabelListAttribute{}
3578 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3579 labelListAttr.Append(list)
3580}
3581
3582func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3583 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3584}