blob: 0ed15057568e0e110c6ccaee552022457353090a [file] [log] [blame]
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090015// package apex implements build rules for creating the APEX files which are container for
16// lower-level system components. See https://source.android.com/devices/tech/ota/apex
Jiyong Park48ca7dc2018-10-10 14:01:00 +090017package apex
18
19import (
20 "fmt"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090021 "path/filepath"
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +000022 "regexp"
Jiyong Parkab3ceb32018-10-10 14:05:29 +090023 "sort"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090024 "strings"
25
Yu Liu4c212ce2022-10-14 12:20:20 -070026 "android/soong/bazel/cquery"
27
Jiyong Park48ca7dc2018-10-10 14:01:00 +090028 "github.com/google/blueprint"
Alex Light778127a2019-02-27 14:19:50 -080029 "github.com/google/blueprint/bootstrap"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090030 "github.com/google/blueprint/proptools"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070031
32 "android/soong/android"
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -040033 "android/soong/bazel"
markchien2f59ec92020-09-02 16:23:38 +080034 "android/soong/bpf"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070035 "android/soong/cc"
36 prebuilt_etc "android/soong/etc"
Jiyong Park12a719c2021-01-07 15:31:24 +090037 "android/soong/filesystem"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070038 "android/soong/java"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090039 "android/soong/multitree"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070040 "android/soong/python"
Jiyong Park99644e92020-11-17 22:21:02 +090041 "android/soong/rust"
Jaewoong Jung4b79e982020-06-01 10:45:49 -070042 "android/soong/sh"
Jiyong Park48ca7dc2018-10-10 14:01:00 +090043)
44
Jiyong Park8e6d52f2020-11-19 14:37:47 +090045func init() {
Paul Duffin667893c2021-03-09 22:34:13 +000046 registerApexBuildComponents(android.InitRegistrationContext)
47}
Jiyong Park8e6d52f2020-11-19 14:37:47 +090048
Paul Duffin667893c2021-03-09 22:34:13 +000049func registerApexBuildComponents(ctx android.RegistrationContext) {
50 ctx.RegisterModuleType("apex", BundleFactory)
Yu Liu4c212ce2022-10-14 12:20:20 -070051 ctx.RegisterModuleType("apex_test", TestApexBundleFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000052 ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
53 ctx.RegisterModuleType("apex_defaults", defaultsFactory)
54 ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
Wei Li1c66fc72022-05-09 23:59:14 -070055 ctx.RegisterModuleType("override_apex", OverrideApexFactory)
Paul Duffin667893c2021-03-09 22:34:13 +000056 ctx.RegisterModuleType("apex_set", apexSetFactory)
57
Paul Duffin5dda3e32021-05-05 14:13:27 +010058 ctx.PreArchMutators(registerPreArchMutators)
Paul Duffin667893c2021-03-09 22:34:13 +000059 ctx.PreDepsMutators(RegisterPreDepsMutators)
60 ctx.PostDepsMutators(RegisterPostDepsMutators)
Jiyong Park8e6d52f2020-11-19 14:37:47 +090061}
62
Paul Duffin5dda3e32021-05-05 14:13:27 +010063func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
64 ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
65}
66
Jiyong Park8e6d52f2020-11-19 14:37:47 +090067func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
68 ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
69 ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
70}
71
72func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
Paul Duffin949abc02020-12-08 10:34:30 +000073 ctx.TopDown("apex_info", apexInfoMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090074 ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
75 ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
76 ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
Paul Duffin28bf7ee2021-05-12 16:41:35 +010077 // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
78 // it should create a platform variant.
79 ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090080 ctx.BottomUp("apex", apexMutator).Parallel()
81 ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
82 ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
Spandan Das66773252022-01-15 00:23:18 +000083 // Register after apex_info mutator so that it can use ApexVariationName
84 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090085}
86
87type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090088 // Json manifest file describing meta info of this APEX bundle. Refer to
89 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090090 Manifest *string `android:"path"`
91
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090092 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
93 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090094 AndroidManifest *string `android:"path"`
95
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090096 // Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
97 // device (/apex/<apex_name>). If unspecified, follows the name property.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090098 Apex_name *string
99
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900100 // Determines the file contexts file for setting the security contexts to files in this APEX
101 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
102 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900103 File_contexts *string `android:"path"`
104
Jiyong Park038e8522021-12-13 23:56:35 +0900105 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
106 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
107 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
108 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
109 // capability. If this property is not set, or a file is missing in the file, default config
110 // is used.
111 Canned_fs_config *string `android:"path"`
112
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900113 ApexNativeDependencies
114
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900115 Multilib apexMultilibProperties
116
Sundong Ahn80c04892021-11-23 00:57:19 +0000117 // List of sh binaries that are embedded inside this APEX bundle.
118 Sh_binaries []string
119
Paul Duffin3abc1742021-03-15 19:32:23 +0000120 // List of platform_compat_config files that are embedded inside this APEX bundle.
121 Compat_configs []string
122
Jiyong Park12a719c2021-01-07 15:31:24 +0900123 // List of filesystem images that are embedded inside this APEX bundle.
124 Filesystems []string
125
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900126 // The minimum SDK version that this APEX must support at minimum. This is usually set to
127 // the SDK version that the APEX was first introduced.
128 Min_sdk_version *string
129
130 // Whether this APEX is considered updatable or not. When set to true, this will enforce
131 // additional rules for making sure that the APEX is truly updatable. To be updatable,
132 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000133 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900134 Updatable *bool
135
Jiyong Parkf4020582021-11-29 12:37:10 +0900136 // Marks that this APEX is designed to be updatable in the future, although it's not
137 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
138 // updatable APEXes. Currently, this disables the size optimization, so that the size of
139 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
140 // false.
141 Future_updatable *bool
142
Jiyong Park1bc84122021-06-22 20:23:05 +0900143 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
144 // false`. Default is false.
145 Platform_apis *bool
146
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900147 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
148 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900149 Installable *bool
150
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900151 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
152 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
153 Use_vndk_as_stable *bool
154
Daniel Norman6cfb37af2021-11-16 20:28:29 +0000155 // Whether this is multi-installed APEX should skip installing symbol files.
156 // Multi-installed APEXes share the same apex_name and are installed at the same time.
157 // Default is false.
158 //
159 // Should be set to true for all multi-installed APEXes except the singular
160 // default version within the multi-installed group.
161 // Only the default version can install symbol files in $(PRODUCT_OUT}/apex,
162 // or else conflicting build rules may be created.
163 Multi_install_skip_symbol_files *bool
164
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900165 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
166 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
167 // container. When set to zip, contents are stored in a zip container directly. This type is
168 // mostly for host-side debugging. When set to both, the two types are both built. Default
169 // is 'image'.
170 Payload_type *string
171
Huang Jianan13cac632021-08-02 15:02:17 +0800172 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
173 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900174 Payload_fs_type *string
175
176 // For telling the APEX to ignore special handling for system libraries such as bionic.
177 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900178 Ignore_system_library_special_case *bool
179
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100180 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100181 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100182 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900183
184 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
185 // used in tests.
186 Test_only_unsigned_payload *bool
187
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000188 // Whenever apex should be compressed, regardless of product flag used. Should be only
189 // used in tests.
190 Test_only_force_compression *bool
191
Jooyung Han09c11ad2021-10-27 03:45:31 +0900192 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
193 // with the tool to sign payload contents.
194 Custom_sign_tool *string
195
Dennis Shenaf41bc12022-08-03 16:46:43 +0000196 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
197 // in a special way that include the digest of the lib file under /lib(64)?
198 Dynamic_common_lib_apex *bool
199
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100200 // Canonical name of this APEX bundle. Used to determine the path to the
201 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
202 // apex mutator variations. For override_apex modules, this is the name of the
203 // overridden base module.
204 ApexVariationName string `blueprint:"mutated"`
205
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900206 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900207
208 // List of sanitizer names that this APEX is enabled for
209 SanitizerNames []string `blueprint:"mutated"`
210
211 PreventInstall bool `blueprint:"mutated"`
212
213 HideFromMake bool `blueprint:"mutated"`
214
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900215 // Internal package method for this APEX. When payload_type is image, this can be either
216 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
217 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900218 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900219}
220
221type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900222 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900223 Native_shared_libs []string
224
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900225 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900226 Jni_libs []string
227
Colin Cross70572ed2022-11-02 13:14:20 -0700228 // List of rust dyn libraries that are embedded inside this APEX.
Jiyong Park99644e92020-11-17 22:21:02 +0900229 Rust_dyn_libs []string
230
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900231 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900232 Binaries []string
233
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900234 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900235 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900236
237 // List of filesystem images that are embedded inside this APEX bundle.
238 Filesystems []string
Colin Cross70572ed2022-11-02 13:14:20 -0700239
240 // List of native libraries to exclude from this APEX.
241 Exclude_native_shared_libs []string
242
243 // List of JNI libraries to exclude from this APEX.
244 Exclude_jni_libs []string
245
246 // List of rust dyn libraries to exclude from this APEX.
247 Exclude_rust_dyn_libs []string
248
249 // List of native executables to exclude from this APEX.
250 Exclude_binaries []string
251
252 // List of native tests to exclude from this APEX.
253 Exclude_tests []string
254
255 // List of filesystem images to exclude from this APEX bundle.
256 Exclude_filesystems []string
257}
258
259// Merge combines another ApexNativeDependencies into this one
260func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
261 a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
262 a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
263 a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
264 a.Binaries = append(a.Binaries, b.Binaries...)
265 a.Tests = append(a.Tests, b.Tests...)
266 a.Filesystems = append(a.Filesystems, b.Filesystems...)
267
268 a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
269 a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
270 a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
271 a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
272 a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
273 a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900274}
275
276type apexMultilibProperties struct {
277 // Native dependencies whose compile_multilib is "first"
278 First ApexNativeDependencies
279
280 // Native dependencies whose compile_multilib is "both"
281 Both ApexNativeDependencies
282
283 // Native dependencies whose compile_multilib is "prefer32"
284 Prefer32 ApexNativeDependencies
285
286 // Native dependencies whose compile_multilib is "32"
287 Lib32 ApexNativeDependencies
288
289 // Native dependencies whose compile_multilib is "64"
290 Lib64 ApexNativeDependencies
291}
292
293type apexTargetBundleProperties struct {
294 Target struct {
295 // Multilib properties only for android.
296 Android struct {
297 Multilib apexMultilibProperties
298 }
299
300 // Multilib properties only for host.
301 Host struct {
302 Multilib apexMultilibProperties
303 }
304
305 // Multilib properties only for host linux_bionic.
306 Linux_bionic struct {
307 Multilib apexMultilibProperties
308 }
309
310 // Multilib properties only for host linux_glibc.
311 Linux_glibc struct {
312 Multilib apexMultilibProperties
313 }
314 }
315}
316
Jiyong Park59140302020-12-14 18:44:04 +0900317type apexArchBundleProperties struct {
318 Arch struct {
319 Arm struct {
320 ApexNativeDependencies
321 }
322 Arm64 struct {
323 ApexNativeDependencies
324 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700325 Riscv64 struct {
326 ApexNativeDependencies
327 }
Jiyong Park59140302020-12-14 18:44:04 +0900328 X86 struct {
329 ApexNativeDependencies
330 }
331 X86_64 struct {
332 ApexNativeDependencies
333 }
334 }
335}
336
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900337// These properties can be used in override_apex to override the corresponding properties in the
338// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900339type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900340 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900341 Apps []string
342
Daniel Norman5a3ce132021-08-26 15:44:43 -0700343 // List of prebuilt files that are embedded inside this APEX bundle.
344 Prebuilts []string
345
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900346 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900347 Rros []string
348
markchien7c803b82021-08-26 22:10:06 +0800349 // List of BPF programs inside this APEX bundle.
350 Bpfs []string
351
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900352 // List of bootclasspath fragments that are embedded inside this APEX bundle.
353 Bootclasspath_fragments []string
354
355 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
356 Systemserverclasspath_fragments []string
357
358 // List of java libraries that are embedded inside this APEX bundle.
359 Java_libs []string
360
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900361 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
362 // Soong). This does not completely prevent installation of the overridden binaries, but if
363 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
364 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900365 Overrides []string
366
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900367 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900368 Logging_parent string
369
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900370 // Apex Container package name. Override value for attribute package:name in
371 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900372 Package_name string
373
374 // A txt file containing list of files that are allowed to be included in this APEX.
375 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700376
377 // Name of the apex_key module that provides the private key to sign this APEX bundle.
378 Key *string
379
380 // Specifies the certificate and the private key to sign the zip container of this APEX. If
381 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
382 // as the certificate and the private key, respectively. If this is ":module", then the
383 // certificate and the private key are provided from the android_app_certificate module
384 // named "module".
385 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400386
387 // Whether this APEX can be compressed or not. Setting this property to false means this
388 // APEX will never be compressed. When set to true, APEX will be compressed if other
389 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
390 // Default: false.
391 Compressible *bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900392}
393
394type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900395 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900396 android.ModuleBase
397 android.DefaultableModuleBase
398 android.OverridableModuleBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400399 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900400 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900401
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900402 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900403 properties apexBundleProperties
404 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900405 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900406 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900407 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900408
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900409 ///////////////////////////////////////////////////////////////////////////////////////////
410 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900411
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900412 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800413 publicKeyFile android.Path
414 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900415
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900416 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800417 containerCertificateFile android.Path
418 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900419
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900420 // Flags for special variants of APEX
421 testApex bool
422 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900423
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900424 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
425 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900426 primaryApexType bool
427
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900428 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900429 suffix string
430
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900431 // File system type of apex_payload.img
432 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900433
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900434 // Whether to create symlink to the system file instead of having a file inside the apex or
435 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900436 linkToSystemLib bool
437
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900438 // List of files to be included in this APEX. This is filled in the first part of
439 // GenerateAndroidBuildActions.
440 filesInfo []apexFile
441
Jingwen Chen29743c82023-01-25 17:49:46 +0000442 // List of other module names that should be installed when this APEX gets installed (LOCAL_REQUIRED_MODULES).
443 makeModulesToInstall []string
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900444
445 ///////////////////////////////////////////////////////////////////////////////////////////
446 // Outputs (final and intermediates)
447
448 // Processed apex manifest in JSONson format (for Q)
449 manifestJsonOut android.WritablePath
450
451 // Processed apex manifest in PB format (for R+)
452 manifestPbOut android.WritablePath
453
454 // Processed file_contexts files
455 fileContexts android.WritablePath
456
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900457 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900458 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900459 outputFile android.WritablePath
460
Jooyung Hana6d36672022-02-24 13:58:07 +0900461 // The built uncompressed .apex file.
462 outputApexFile android.WritablePath
463
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900464 // The built APEX file in app bundle format. This file is not directly installed to the
465 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
466 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
467 // system) to be merged into a single app bundle file that Play accepts. See
468 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
469 bundleModuleFile android.WritablePath
470
Colin Cross6340ea52021-11-04 12:01:18 -0700471 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900472 installDir android.InstallPath
473
Colin Cross6340ea52021-11-04 12:01:18 -0700474 // Path where this APEX was installed.
475 installedFile android.InstallPath
476
477 // Installed locations of symlinks for backward compatibility.
478 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900479
480 // Text file having the list of individual files that are included in this APEX. Used for
481 // debugging purpose.
482 installedFilesFile android.WritablePath
483
484 // List of module names that this APEX is including (to be shown via *-deps-info target).
485 // Used for debugging purpose.
486 android.ApexBundleDepsInfo
487
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900488 // Optional list of lint report zip files for apexes that contain java or app modules
489 lintReports android.Paths
490
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900491 prebuiltFileToDelete string
sophiezc80a2b32020-11-12 16:39:19 +0000492
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000493 isCompressed bool
494
sophiezc80a2b32020-11-12 16:39:19 +0000495 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700496 nativeApisUsedByModuleFile android.ModuleOutPath
497 nativeApisBackedByModuleFile android.ModuleOutPath
498 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800499
500 // Collect the module directory for IDE info in java/jdeps.go.
501 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900502}
503
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900504// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900505type apexFileClass int
506
Jooyung Han72bd2f82019-10-23 16:46:38 +0900507const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900508 app apexFileClass = iota
509 appSet
510 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900511 goBinary
512 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900513 nativeExecutable
514 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900515 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900516 pyBinary
517 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900518)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900519
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900520// apexFile represents a file in an APEX bundle. This is created during the first half of
521// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
522// of the function, this is used to create commands that copies the files into a staging directory,
523// where they are packaged into the APEX file. This struct is also used for creating Make modules
524// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900525type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900526 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000527 builtFile android.Path
528 installDir string
529 customStem string
530 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900531
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900532 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
533 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
534 // suffix>]
535 androidMkModuleName string // becomes LOCAL_MODULE
536 class apexFileClass // becomes LOCAL_MODULE_CLASS
537 moduleDir string // becomes LOCAL_PATH
538 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
539 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
540 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
541 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900542
543 jacocoReportClassesFile android.Path // only for javalibs and apps
544 lintDepSets java.LintDepSets // only for javalibs and apps
545 certificate java.Certificate // only for apps
546 overriddenPackageName string // only for apps
547
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900548 transitiveDep bool
549 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900550
Jiyong Park57621b22021-01-20 20:33:11 +0900551 multilib string
552
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900553 // TODO(jiyong): remove this
554 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900555}
556
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900557// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900558func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
559 ret := apexFile{
560 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900561 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900562 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900563 class: class,
564 module: module,
565 }
566 if module != nil {
567 ret.moduleDir = ctx.OtherModuleDir(module)
568 ret.requiredModuleNames = module.RequiredModuleNames()
569 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
570 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900571 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900572 }
573 return ret
574}
575
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900576func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900577 return af.builtFile != nil && af.builtFile.String() != ""
578}
579
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900580// apexRelativePath returns the relative path of the given path from the install directory of this
581// apexFile.
582// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900583func (af *apexFile) apexRelativePath(path string) string {
584 return filepath.Join(af.installDir, path)
585}
586
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900587// path returns path of this apex file relative to the APEX root
588func (af *apexFile) path() string {
589 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900590}
591
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900592// stem returns the base filename of this apex file
593func (af *apexFile) stem() string {
594 if af.customStem != "" {
595 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900596 }
597 return af.builtFile.Base()
598}
599
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900600// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
601func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900602 var ret []string
603 for _, symlink := range af.symlinks {
604 ret = append(ret, af.apexRelativePath(symlink))
605 }
606 return ret
607}
608
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900609// availableToPlatform tests whether this apexFile is from a module that can be installed to the
610// platform.
611func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900612 if af.module == nil {
613 return false
614 }
615 if am, ok := af.module.(android.ApexModule); ok {
616 return am.AvailableFor(android.AvailableToPlatform)
617 }
618 return false
619}
620
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900621////////////////////////////////////////////////////////////////////////////////////////////////////
622// Mutators
623//
624// Brief description about mutators for APEX. The following three mutators are the most important
625// ones.
626//
627// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
628// to the (direct) dependencies of this APEX bundle.
629//
Paul Duffin949abc02020-12-08 10:34:30 +0000630// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900631// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
632// modules are marked as being included in the APEX via BuildForApex().
633//
Paul Duffin949abc02020-12-08 10:34:30 +0000634// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
635// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900636
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900637type dependencyTag struct {
638 blueprint.BaseDependencyTag
639 name string
640
641 // Determines if the dependent will be part of the APEX payload. Can be false for the
642 // dependencies to the signing key module, etc.
643 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000644
645 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
646 // replacement. This is needed because some prebuilt modules do not provide all the information
647 // needed by the apex.
648 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000649
650 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
651 // also be added as exported members of that SDK.
652 memberType android.SdkMemberType
653}
654
655func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
656 return d.memberType
657}
658
659func (d *dependencyTag) ExportMember() bool {
660 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900661}
662
Paul Duffin520917a2022-05-13 13:01:59 +0000663func (d *dependencyTag) String() string {
664 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
665}
666
667func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000668 return !d.sourceOnly
669}
670
671var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000672var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000673
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900674var (
Paul Duffin520917a2022-05-13 13:01:59 +0000675 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
676 bpfTag = &dependencyTag{name: "bpf", payload: true}
677 certificateTag = &dependencyTag{name: "certificate"}
678 executableTag = &dependencyTag{name: "executable", payload: true}
679 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000680 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
681 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000682 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000683 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
684 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
685 keyTag = &dependencyTag{name: "key"}
686 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
687 rroTag = &dependencyTag{name: "rro", payload: true}
688 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
689 testForTag = &dependencyTag{name: "test for"}
690 testTag = &dependencyTag{name: "test", payload: true}
691 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900692)
693
694// TODO(jiyong): shorten this function signature
695func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900696 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900697 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900698 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900699
700 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900701 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900702 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
703 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900704 }
705
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900706 // Use *FarVariation* to be able to depend on modules having conflicting variations with
707 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
708 // 'arm' or 'arm64' for native shared libs.
Colin Cross70572ed2022-11-02 13:14:20 -0700709 ctx.AddFarVariationDependencies(binVariations, executableTag,
710 android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
711 ctx.AddFarVariationDependencies(binVariations, testTag,
712 android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
713 ctx.AddFarVariationDependencies(libVariations, jniLibTag,
714 android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
715 ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
716 android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
717 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
718 android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
719 ctx.AddFarVariationDependencies(target.Variations(), fsTag,
720 android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900721}
722
723func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900724 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900725 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
726 } else {
727 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
728 if ctx.Os().Bionic() {
729 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
730 } else {
731 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
732 }
733 }
734}
735
Jooyung Hand045ebc2022-12-06 15:23:57 +0900736// getImageVariationPair returns a pair for the image variation name as its
737// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
738// suffix indicates the vndk version when it's vendor or product.
739// getImageVariation can simply join the result of this function to get the
740// image variation name.
741func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900742 if a.vndkApex {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900743 return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900744 }
745
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900746 var prefix string
747 var vndkVersion string
748 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000749 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900750 prefix = cc.VendorVariationPrefix
751 vndkVersion = deviceConfig.VndkVersion()
752 } else if a.ProductSpecific() {
753 prefix = cc.ProductVariationPrefix
754 vndkVersion = deviceConfig.ProductVndkVersion()
755 }
756 }
757 if vndkVersion == "current" {
758 vndkVersion = deviceConfig.PlatformVndkVersion()
759 }
760 if vndkVersion != "" {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900761 return prefix, vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900762 }
763
Jooyung Hand045ebc2022-12-06 15:23:57 +0900764 return android.CoreVariation, "" // The usual case
765}
766
767// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
768// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
769func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
770 prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
771 return prefix + vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900772}
773
774func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900775 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
776 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
777 // each target os/architectures, appropriate dependencies are selected by their
778 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900779 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900780 imageVariation := a.getImageVariation(ctx)
781
782 a.combineProperties(ctx)
783
784 has32BitTarget := false
785 for _, target := range targets {
786 if target.Arch.ArchType.Multilib == "lib32" {
787 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000788 }
789 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900790 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900791 // Don't include artifacts for the host cross targets because there is no way for us
792 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900793 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900794 continue
795 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000796
Colin Cross70572ed2022-11-02 13:14:20 -0700797 var deps ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000798
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900799 // Add native modules targeting both ABIs. When multilib.* is omitted for
800 // native_shared_libs/jni_libs/tests, it implies multilib.both
Colin Cross70572ed2022-11-02 13:14:20 -0700801 deps.Merge(a.properties.Multilib.Both)
802 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900803 Native_shared_libs: a.properties.Native_shared_libs,
804 Tests: a.properties.Tests,
805 Jni_libs: a.properties.Jni_libs,
806 Binaries: nil,
807 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900808
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900809 // Add native modules targeting the first ABI When multilib.* is omitted for
810 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900811 isPrimaryAbi := i == 0
812 if isPrimaryAbi {
Colin Cross70572ed2022-11-02 13:14:20 -0700813 deps.Merge(a.properties.Multilib.First)
814 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900815 Native_shared_libs: nil,
816 Tests: nil,
817 Jni_libs: nil,
818 Binaries: a.properties.Binaries,
819 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900820 }
821
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900822 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900823 switch target.Arch.ArchType.Multilib {
824 case "lib32":
Colin Cross70572ed2022-11-02 13:14:20 -0700825 deps.Merge(a.properties.Multilib.Lib32)
826 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900827 case "lib64":
Colin Cross70572ed2022-11-02 13:14:20 -0700828 deps.Merge(a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900829 if !has32BitTarget {
Colin Cross70572ed2022-11-02 13:14:20 -0700830 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900831 }
832 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900833
Jiyong Park59140302020-12-14 18:44:04 +0900834 // Add native modules targeting a specific arch variant
835 switch target.Arch.ArchType {
836 case android.Arm:
Colin Cross70572ed2022-11-02 13:14:20 -0700837 deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900838 case android.Arm64:
Colin Cross70572ed2022-11-02 13:14:20 -0700839 deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700840 case android.Riscv64:
Colin Cross70572ed2022-11-02 13:14:20 -0700841 deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900842 case android.X86:
Colin Cross70572ed2022-11-02 13:14:20 -0700843 deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900844 case android.X86_64:
Colin Cross70572ed2022-11-02 13:14:20 -0700845 deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900846 default:
847 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
848 }
849
Colin Cross70572ed2022-11-02 13:14:20 -0700850 addDependenciesForNativeModules(ctx, deps, target, imageVariation)
Sundong Ahn80c04892021-11-23 00:57:19 +0000851 ctx.AddFarVariationDependencies([]blueprint.Variation{
852 {Mutator: "os", Variation: target.OsVariation()},
853 {Mutator: "arch", Variation: target.ArchVariation()},
854 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900855 }
856
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900857 // Common-arch dependencies come next
858 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900859 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000860 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100861}
862
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900863// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900864func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
865 if a.overridableProperties.Allowed_files != nil {
866 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100867 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900868
869 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
870 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800871 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900872 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900873 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
874 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
875 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700876 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
877 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
878 // regardless of the TARGET_PREFER_* setting. See b/144532908
879 arches := ctx.DeviceConfig().Arches()
880 if len(arches) != 0 {
881 archForPrebuiltEtc := arches[0]
882 for _, arch := range arches {
883 // Prefer 64-bit arch if there is any
884 if arch.ArchType.Multilib == "lib64" {
885 archForPrebuiltEtc = arch
886 break
887 }
888 }
889 ctx.AddFarVariationDependencies([]blueprint.Variation{
890 {Mutator: "os", Variation: ctx.Os().String()},
891 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
892 }, prebuiltTag, prebuilts...)
893 }
894 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700895
896 // Dependencies for signing
897 if String(a.overridableProperties.Key) == "" {
898 ctx.PropertyErrorf("key", "missing")
899 return
900 }
901 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
902
903 cert := android.SrcIsModule(a.getCertString(ctx))
904 if cert != "" {
905 ctx.AddDependency(ctx.Module(), certificateTag, cert)
906 // empty cert is not an error. Cert and private keys will be directly found under
907 // PRODUCT_DEFAULT_DEV_CERTIFICATE
908 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100909}
910
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900911type ApexBundleInfo struct {
912 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100913}
914
Paul Duffin949abc02020-12-08 10:34:30 +0000915var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900916
Paul Duffina7d6a892020-12-07 17:39:59 +0000917var _ ApexInfoMutator = (*apexBundle)(nil)
918
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100919func (a *apexBundle) ApexVariationName() string {
920 return a.properties.ApexVariationName
921}
922
Paul Duffina7d6a892020-12-07 17:39:59 +0000923// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900924// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
925// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
926// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
927// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000928//
929// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
930// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
931// The apexMutator uses that list to create module variants for the apexes to which it belongs.
932// The relationship between module variants and apexes is not one-to-one as variants will be
933// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000934func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900935
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900936 // The VNDK APEX is special. For the APEX, the membership is described in a very different
937 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
938 // libraries are self-identified by their vndk.enabled properties. There is no need to run
939 // this mutator for the APEX as nothing will be collected. So, let's return fast.
940 if a.vndkApex {
941 return
942 }
943
944 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
945 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
946 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
947 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
948 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900949 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
950 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900951 if proptools.Bool(a.properties.Use_vndk_as_stable) {
952 if !useVndk {
953 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
954 }
955 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
956 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
957 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
958 }
959 })
960 if mctx.Failed() {
961 return
962 }
Jooyung Handf78e212020-07-22 15:54:47 +0900963 }
964
Colin Cross56a83212020-09-15 18:30:11 -0700965 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900966 am, ok := child.(android.ApexModule)
967 if !ok || !am.CanHaveApexVariants() {
968 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900969 }
Paul Duffin573989d2021-03-17 13:25:29 +0000970 depTag := mctx.OtherModuleDependencyTag(child)
971
972 // Check to see if the tag always requires that the child module has an apex variant for every
973 // apex variant of the parent module. If it does not then it is still possible for something
974 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
975 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
976 return true
977 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000978 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900979 return false
980 }
Jooyung Handf78e212020-07-22 15:54:47 +0900981 if excludeVndkLibs {
982 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
983 return false
984 }
985 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900986 // By default, all the transitive dependencies are collected, unless filtered out
987 // above.
Colin Cross56a83212020-09-15 18:30:11 -0700988 return true
989 }
990
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900991 // Records whether a certain module is included in this apexBundle via direct dependency or
992 // inndirect dependency.
993 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -0700994 mctx.WalkDeps(func(child, parent android.Module) bool {
995 if !continueApexDepsWalk(child, parent) {
996 return false
997 }
Jooyung Han698dd9f2020-07-22 15:17:19 +0900998 // If the parent is apexBundle, this child is directly depended.
999 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001000 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -07001001 contents[depName] = contents[depName].Add(directDep)
1002 return true
1003 })
1004
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001005 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +09001006 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -07001007 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
1008 Contents: apexContents,
1009 })
1010
Jooyung Haned124c32021-01-26 11:43:46 +09001011 minSdkVersion := a.minSdkVersion(mctx)
1012 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
1013 if minSdkVersion.IsNone() {
1014 minSdkVersion = android.FutureApiLevel
1015 }
1016
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001017 // This is the main part of this mutator. Mark the collected dependencies that they need to
1018 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +09001019
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001020 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
1021 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -07001022 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001023 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +09001024 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -07001025 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +09001026 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001027 InApexVariants: []string{apexVariationName},
1028 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -07001029 ApexContents: []*android.ApexContents{apexContents},
1030 }
Colin Cross56a83212020-09-15 18:30:11 -07001031 mctx.WalkDeps(func(child, parent android.Module) bool {
1032 if !continueApexDepsWalk(child, parent) {
1033 return false
1034 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001035 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +09001036 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +09001037 })
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001038}
1039
Paul Duffina7d6a892020-12-07 17:39:59 +00001040type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001041 // ApexVariationName returns the name of the APEX variation to use in the apex
1042 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
1043 ApexVariationName() string
1044
Paul Duffina7d6a892020-12-07 17:39:59 +00001045 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1046 // depended upon by an apex and which require an apex specific variant.
1047 ApexInfoMutator(android.TopDownMutatorContext)
1048}
1049
1050// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1051// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001052// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001053func apexInfoMutator(mctx android.TopDownMutatorContext) {
1054 if !mctx.Module().Enabled() {
1055 return
1056 }
1057
1058 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1059 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001060 }
Spandan Das42e89502022-05-06 22:12:55 +00001061 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001062}
1063
Spandan Das66773252022-01-15 00:23:18 +00001064// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1065// This check is enforced for updatable modules
1066func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1067 if !mctx.Module().Enabled() {
1068 return
1069 }
Spandan Das08c911f2022-01-21 22:07:26 +00001070 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001071 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001072 // b/208656169 Do not propagate strict updatability linting to libcore/
1073 // These libs are available on the classpath during compilation
1074 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1075 // Only skip libraries defined in libcore root, not subdirectories
1076 if mctx.OtherModuleDir(child) == "libcore" {
1077 // Do not traverse transitive deps of libcore/ libs
1078 return false
1079 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001080 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1081 return false
1082 }
Spandan Das66773252022-01-15 00:23:18 +00001083 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1084 lintable.SetStrictUpdatabilityLinting(true)
1085 }
1086 // visit transitive deps
1087 return true
1088 })
1089 }
1090}
1091
Spandan Das42e89502022-05-06 22:12:55 +00001092// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1093func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1094 if !mctx.Module().Enabled() {
1095 return
1096 }
1097 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1098 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1099 mctx.VisitDirectDeps(func(module android.Module) {
1100 // ignore android_test_app
1101 if app, ok := module.(*java.AndroidApp); ok {
1102 app.SetUpdatable(true)
1103 }
1104 })
1105 }
1106}
1107
Spandan Das08c911f2022-01-21 22:07:26 +00001108// TODO: b/215736885 Whittle the denylist
1109// Transitive deps of certain mainline modules baseline NewApi errors
1110// Skip these mainline modules for now
1111var (
1112 skipStrictUpdatabilityLintAllowlist = []string{
1113 "com.android.art",
1114 "com.android.art.debug",
1115 "com.android.conscrypt",
1116 "com.android.media",
1117 // test apexes
1118 "test_com.android.art",
1119 "test_com.android.conscrypt",
1120 "test_com.android.media",
1121 "test_jitzygote_com.android.art",
1122 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001123
1124 // TODO: b/215736885 Remove this list
1125 skipLintJavalibAllowlist = []string{
1126 "conscrypt.module.platform.api.stubs",
1127 "conscrypt.module.public.api.stubs",
1128 "conscrypt.module.public.api.stubs.system",
1129 "conscrypt.module.public.api.stubs.module_lib",
1130 "framework-media.stubs",
1131 "framework-media.stubs.system",
1132 "framework-media.stubs.module_lib",
1133 }
Spandan Das08c911f2022-01-21 22:07:26 +00001134)
1135
1136func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1137 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1138}
1139
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001140// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1141// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1142// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001143func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1144 if !mctx.Module().Enabled() {
1145 return
1146 }
1147 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001148 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1149 }
1150}
1151
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001152// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1153// the apex in order to retrieve its contents later.
1154// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001155func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1156 if !mctx.Module().Enabled() {
1157 return
1158 }
Colin Cross56a83212020-09-15 18:30:11 -07001159 if am, ok := mctx.Module().(android.ApexModule); ok {
1160 if testFor := am.TestFor(); len(testFor) > 0 {
1161 mctx.AddFarVariationDependencies([]blueprint.Variation{
1162 {Mutator: "os", Variation: am.Target().OsVariation()},
1163 {"arch", "common"},
1164 }, testForTag, testFor...)
1165 }
1166 }
1167}
1168
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001169// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001170func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1171 if !mctx.Module().Enabled() {
1172 return
1173 }
Colin Cross56a83212020-09-15 18:30:11 -07001174 if _, ok := mctx.Module().(android.ApexModule); ok {
1175 var contents []*android.ApexContents
1176 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1177 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1178 contents = append(contents, abInfo.Contents)
1179 }
1180 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1181 ApexContents: contents,
1182 })
Colin Crossaede88c2020-08-11 12:17:01 -07001183 }
1184}
1185
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001186// markPlatformAvailability marks whether or not a module can be available to platform. A module
1187// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1188// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1189// be) available to platform
1190// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001191func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1192 // Host and recovery are not considered as platform
1193 if mctx.Host() || mctx.Module().InstallInRecovery() {
1194 return
1195 }
1196
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001197 am, ok := mctx.Module().(android.ApexModule)
1198 if !ok {
1199 return
1200 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001201
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001202 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001203
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001204 // If any of the dep is not available to platform, this module is also considered as being
1205 // not available to platform even if it has "//apex_available:platform"
1206 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001207 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001208 // if the dependency crosses apex boundary, don't consider it
1209 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001210 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001211 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1212 availableToPlatform = false
1213 // TODO(b/154889534) trigger an error when 'am' has
1214 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001215 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001216 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001217
Paul Duffinb5769c12021-05-12 16:16:51 +01001218 // Exception 1: check to see if the module always requires it.
1219 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001220 availableToPlatform = true
1221 }
1222
1223 // Exception 2: bootstrap bionic libraries are also always available to platform
1224 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1225 availableToPlatform = true
1226 }
1227
1228 if !availableToPlatform {
1229 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001230 }
1231}
1232
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001233// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001234// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001235func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001236 if !mctx.Module().Enabled() {
1237 return
1238 }
Colin Cross56a83212020-09-15 18:30:11 -07001239
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001240 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001241 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001242 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001243 return
1244 }
1245
1246 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001247 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1248 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001249 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001250 if strings.HasPrefix(apexBundleName, "com.android.art") {
1251 // Create an alias from the platform variant. This is done to make
1252 // test_for dependencies work for modules that are split by the APEX
1253 // mutator, since test_for dependencies always go to the platform variant.
1254 // This doesn't happen for normal APEXes that are disjunct, so only do
1255 // this for the overlapping ART APEXes.
1256 // TODO(b/183882457): Remove this if the test_for functionality is
1257 // refactored to depend on the proper APEX variants instead of platform.
1258 mctx.CreateAliasVariation("", apexBundleName)
1259 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001260 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1261 apexBundleName := o.GetOverriddenModuleName()
1262 if apexBundleName == "" {
1263 mctx.ModuleErrorf("base property is not set")
1264 return
1265 }
1266 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001267 if strings.HasPrefix(apexBundleName, "com.android.art") {
1268 // TODO(b/183882457): See note for CreateAliasVariation above.
1269 mctx.CreateAliasVariation("", apexBundleName)
1270 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001271 }
1272}
Sundong Ahne9b55722019-09-06 17:37:42 +09001273
Paul Duffin6717d882021-06-15 19:09:41 +01001274// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1275// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001276func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001277 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001278 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001279 return !a.vndkApex
1280 }
1281
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001282 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001283}
1284
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001285// See android.UpdateDirectlyInAnyApex
1286// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001287func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1288 if !mctx.Module().Enabled() {
1289 return
1290 }
1291 if am, ok := mctx.Module().(android.ApexModule); ok {
1292 android.UpdateDirectlyInAnyApex(mctx, am)
1293 }
1294}
1295
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001296// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001297type apexPackaging int
1298
1299const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001300 // imageApex is a packaging method where contents are included in a filesystem image which
1301 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001302 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001303
1304 // zipApex is a packaging method where contents are directly included in the zip container.
1305 // This is used for host-side testing - because the contents are easily accessible by
1306 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001307 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001308
1309 // flattendApex is a packaging method where contents are not included in the APEX file, but
1310 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1311 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001312 flattenedApex
1313)
1314
1315const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001316 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001317 imageApexSuffix = ".apex"
1318 imageCapexSuffix = ".capex"
1319 zipApexSuffix = ".zipapex"
1320 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001321
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001322 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001323 imageApexType = "image"
1324 zipApexType = "zip"
1325 flattenedApexType = "flattened"
1326
Dan Willemsen47e1a752021-10-16 18:36:13 -07001327 ext4FsType = "ext4"
1328 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001329 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001330)
1331
1332// The suffix for the output "file", not the module
1333func (a apexPackaging) suffix() string {
1334 switch a {
1335 case imageApex:
1336 return imageApexSuffix
1337 case zipApex:
1338 return zipApexSuffix
1339 default:
1340 panic(fmt.Errorf("unknown APEX type %d", a))
1341 }
1342}
1343
1344func (a apexPackaging) name() string {
1345 switch a {
1346 case imageApex:
1347 return imageApexType
1348 case zipApex:
1349 return zipApexType
1350 default:
1351 panic(fmt.Errorf("unknown APEX type %d", a))
1352 }
1353}
1354
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001355// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1356// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001357func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001358 if !mctx.Module().Enabled() {
1359 return
1360 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001361 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001362 var variants []string
1363 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1364 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001365 // This is the normal case. Note that both image and flattend APEXes are
1366 // created. The image type is installed to the system partition, while the
1367 // flattened APEX is (optionally) installed to the system_ext partition.
1368 // This is mostly for GSI which has to support wide range of devices. If GSI
1369 // is installed on a newer (APEX-capable) device, the image APEX in the
1370 // system will be used. However, if the same GSI is installed on an old
1371 // device which can't support image APEX, the flattened APEX in the
1372 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001373 variants = append(variants, imageApexType, flattenedApexType)
1374 case "zip":
1375 variants = append(variants, zipApexType)
1376 case "both":
1377 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1378 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001379 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001380 return
1381 }
1382
1383 modules := mctx.CreateLocalVariations(variants...)
1384
1385 for i, v := range variants {
1386 switch v {
1387 case imageApexType:
1388 modules[i].(*apexBundle).properties.ApexType = imageApex
1389 case zipApexType:
1390 modules[i].(*apexBundle).properties.ApexType = zipApex
1391 case flattenedApexType:
1392 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001393 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001394 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001395 modules[i].(*apexBundle).MakeAsSystemExt()
1396 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001397 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001398 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001399 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001400 // payload_type is forcibly overridden to "image"
1401 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001402 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001403 }
1404}
1405
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001406var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001407
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001408// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001409func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001410 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001411 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001412 return true
1413}
1414
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001415var _ android.OutputFileProducer = (*apexBundle)(nil)
1416
1417// Implements android.OutputFileProducer
1418func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1419 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001420 case "", android.DefaultDistTag:
1421 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001422 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001423 case imageApexSuffix:
1424 // uncompressed one
1425 if a.outputApexFile != nil {
1426 return android.Paths{a.outputApexFile}, nil
1427 }
1428 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001429 default:
1430 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1431 }
1432}
1433
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001434var _ multitree.Exportable = (*apexBundle)(nil)
1435
1436func (a *apexBundle) Exportable() bool {
1437 if a.properties.ApexType == flattenedApex {
1438 return false
1439 }
1440 return true
1441}
1442
1443func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1444 ret := make(map[string]android.Paths)
1445 ret["apex"] = android.Paths{a.outputFile}
1446 return ret
1447}
1448
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001449var _ cc.Coverage = (*apexBundle)(nil)
1450
1451// Implements cc.Coverage
1452func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1453 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1454}
1455
1456// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001457func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001458 a.properties.PreventInstall = true
1459}
1460
1461// Implements cc.Coverage
1462func (a *apexBundle) HideFromMake() {
1463 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001464 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1465 // TODO(ccross): untangle these
1466 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001467}
1468
1469// Implements cc.Coverage
1470func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1471 a.properties.IsCoverageVariant = coverage
1472}
1473
1474// Implements cc.Coverage
1475func (a *apexBundle) EnableCoverageIfNeeded() {}
1476
1477var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1478
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001479// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001480func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001481 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001482}
1483
Jiyong Parkf4020582021-11-29 12:37:10 +09001484func (a *apexBundle) FutureUpdatable() bool {
1485 return proptools.BoolDefault(a.properties.Future_updatable, false)
1486}
1487
Jiyong Park1bc84122021-06-22 20:23:05 +09001488func (a *apexBundle) UsePlatformApis() bool {
1489 return proptools.BoolDefault(a.properties.Platform_apis, false)
1490}
1491
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001492// getCertString returns the name of the cert that should be used to sign this APEX. This is
1493// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001494func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001495 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001496 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1497 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1498 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001499 if a.vndkApex {
1500 moduleName = vndkApexName
1501 }
1502 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001503 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001504 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001505 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001506 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001507}
1508
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001509// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001510func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001511 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001512}
1513
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001514// See the generate_hashtree property
1515func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001516 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001517}
1518
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001519// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001520func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1521 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1522}
1523
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001524// See the test_only_force_compression property
1525func (a *apexBundle) testOnlyShouldForceCompression() bool {
1526 return proptools.Bool(a.properties.Test_only_force_compression)
1527}
1528
Dennis Shenaf41bc12022-08-03 16:46:43 +00001529// See the dynamic_common_lib_apex property
1530func (a *apexBundle) dynamic_common_lib_apex() bool {
1531 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1532}
1533
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001534// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1535// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1536// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001537
Jiyong Parkf97782b2019-02-13 20:28:58 +09001538func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1539 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1540 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1541 }
1542}
1543
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001544func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001545 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1546 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001547 }
1548
1549 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001550 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001551 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001552 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001553 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001554 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001555 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001556 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001557 }
1558 }
1559 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001560}
1561
Jooyung Han8ce8db92020-05-15 19:05:05 +09001562func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001563 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1564 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001565 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001566 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001567 for _, target := range ctx.MultiTargets() {
1568 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001569 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001570 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001571 Tests: nil,
1572 Jni_libs: nil,
1573 Binaries: nil,
1574 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001575 break
1576 }
1577 }
1578 }
1579}
1580
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001581// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1582// returned apexFile saves information about the Soong module that will be used for creating the
1583// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001584func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001585 // Decide the APEX-local directory by the multilib of the library In the future, we may
1586 // query this to the module.
1587 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001588 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001589 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001590 case "lib32":
1591 dirInApex = "lib"
1592 case "lib64":
1593 dirInApex = "lib64"
1594 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001595 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001596 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001597 }
Jooyung Han35155c42020-02-06 17:33:20 +09001598 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001599 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001600 // Special case for Bionic libs and other libs installed with them. This is to
1601 // prevent those libs from being included in the search path
1602 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1603 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1604 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1605 // will be loaded into the default linker namespace (aka "platform" namespace). If
1606 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1607 // be loaded again into the runtime linker namespace, which will result in double
1608 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001609 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001610 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001611
Colin Cross1d487152022-10-03 19:14:46 -07001612 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001613 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1614 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001615}
1616
Jiyong Park1833cef2019-12-13 13:28:36 +09001617func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001618 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001619 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001620 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001621 }
Jooyung Han35155c42020-02-06 17:33:20 +09001622 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001623 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001624 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1625 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001626 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001627 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001628 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001629}
1630
Jiyong Park99644e92020-11-17 22:21:02 +09001631func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1632 dirInApex := "bin"
1633 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1634 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1635 }
Colin Cross1d487152022-10-03 19:14:46 -07001636 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001637 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1638 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1639 return af
1640}
1641
1642func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1643 // Decide the APEX-local directory by the multilib of the library
1644 // In the future, we may query this to the module.
1645 var dirInApex string
1646 switch rustm.Arch().ArchType.Multilib {
1647 case "lib32":
1648 dirInApex = "lib"
1649 case "lib64":
1650 dirInApex = "lib64"
1651 }
1652 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1653 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1654 }
Colin Cross1d487152022-10-03 19:14:46 -07001655 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001656 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1657 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1658}
1659
Jiyong Park1833cef2019-12-13 13:28:36 +09001660func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001661 dirInApex := "bin"
1662 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001663 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001664}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001665
Jiyong Park1833cef2019-12-13 13:28:36 +09001666func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001667 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001668 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001669 // NB: Since go binaries are static we don't need the module for anything here, which is
1670 // good since the go tool is a blueprint.Module not an android.Module like we would
1671 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001672 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001673}
1674
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001675func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001676 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001677 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1678 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1679 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001680 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001681 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001682 af.symlinks = sh.Symlinks()
1683 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001684}
1685
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001686func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001687 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001688 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001689 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001690}
1691
atrost6e126252020-01-27 17:01:16 +00001692func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1693 dirInApex := filepath.Join("etc", config.SubDir())
1694 fileToCopy := config.CompatConfig()
1695 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1696}
1697
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001698// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1699// way.
1700type javaModule interface {
1701 android.Module
1702 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001703 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001704 JacocoReportClassesFile() android.Path
1705 LintDepSets() java.LintDepSets
1706 Stem() string
1707}
1708
1709var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001710var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001711var _ javaModule = (*java.SdkLibrary)(nil)
1712var _ javaModule = (*java.DexImport)(nil)
1713var _ javaModule = (*java.SdkLibraryImport)(nil)
1714
Paul Duffin190fdef2021-04-26 10:33:59 +01001715// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001716func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001717 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001718}
1719
1720// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1721func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001722 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001723 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001724 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1725 af.lintDepSets = module.LintDepSets()
1726 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001727 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1728 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1729 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1730 }
1731 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001732 return af
1733}
1734
1735// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1736// the same way.
1737type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001738 android.Module
1739 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001740 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001741 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001742 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001743 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001744 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001745 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001746}
1747
1748var _ androidApp = (*java.AndroidApp)(nil)
1749var _ androidApp = (*java.AndroidAppImport)(nil)
1750
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001751func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1752 buildId := ctx.Config().BuildId()
1753
1754 // The build ID is used as a suffix for a filename, so ensure that
1755 // the set of characters being used are sanitized.
1756 // - any word character: [a-zA-Z0-9_]
1757 // - dots: .
1758 // - dashes: -
1759 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1760 if !validRegex.MatchString(buildId) {
1761 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1762 }
1763 return buildId
1764}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001765
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001766func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001767 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001768 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001769 appDir = "priv-app"
1770 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001771
1772 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1773 // so that PackageManager correctly invalidates the existing installed apk
1774 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001775 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001776 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001777
Yo Chiange8128052020-07-23 20:09:18 +08001778 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001779 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001780 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001781 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001782
1783 if app, ok := aapp.(interface {
1784 OverriddenManifestPackageName() string
1785 }); ok {
1786 af.overriddenPackageName = app.OverriddenManifestPackageName()
1787 }
Jiyong Park618922e2020-01-08 13:35:43 +09001788 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001789}
1790
Jiyong Park69aeba92020-04-24 21:16:36 +09001791func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1792 rroDir := "overlay"
1793 dirInApex := filepath.Join(rroDir, rro.Theme())
1794 fileToCopy := rro.OutputFile()
1795 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1796 af.certificate = rro.Certificate()
1797
1798 if a, ok := rro.(interface {
1799 OverriddenManifestPackageName() string
1800 }); ok {
1801 af.overriddenPackageName = a.OverriddenManifestPackageName()
1802 }
1803 return af
1804}
1805
Ken Chenfad7f9d2021-11-10 22:02:57 +08001806func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1807 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001808 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1809}
1810
Jiyong Park12a719c2021-01-07 15:31:24 +09001811func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1812 dirInApex := filepath.Join("etc", "fs")
1813 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1814}
1815
Paul Duffin064b70c2020-11-02 17:32:38 +00001816// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001817// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1818// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1819// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001820func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001821 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001822 am, ok := child.(android.ApexModule)
1823 if !ok || !am.CanHaveApexVariants() {
1824 return false
1825 }
1826
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001827 // Filter-out unwanted depedendencies
1828 depTag := ctx.OtherModuleDependencyTag(child)
1829 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1830 return false
1831 }
Paul Duffin520917a2022-05-13 13:01:59 +00001832 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001833 return false
1834 }
1835
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001836 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001837 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001838
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001839 // Visit actually
1840 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001841 })
1842}
1843
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001844// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1845type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001846
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001847const (
1848 ext4 fsType = iota
1849 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001850 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001851)
Artur Satayev849f8442020-04-28 14:57:42 +01001852
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001853func (f fsType) string() string {
1854 switch f {
1855 case ext4:
1856 return ext4FsType
1857 case f2fs:
1858 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001859 case erofs:
1860 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001861 default:
1862 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001863 }
1864}
1865
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001866var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1867
1868func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1869 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1870}
1871
1872func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1873 bazelCtx := ctx.Config().BazelContext
1874 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1875}
1876
Jingwen Chen889f2f22022-12-16 08:16:01 +00001877// GetBazelLabel returns the bazel label of this apexBundle, or the label of the
1878// override_apex module overriding this apexBundle. An apexBundle can be
1879// overridden by different override_apex modules (e.g. Google or Go variants),
1880// which is handled by the overrides mutators.
1881func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string {
1882 if _, ok := ctx.Module().(android.OverridableModule); ok {
1883 return android.MaybeBp2buildLabelOfOverridingModule(ctx)
1884 }
1885 return a.BazelModuleBase.GetBazelLabel(ctx, a)
1886}
1887
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001888func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1889 if !a.commonBuildActions(ctx) {
1890 return
1891 }
1892
1893 a.setApexTypeAndSuffix(ctx)
1894 a.setPayloadFsType(ctx)
1895 a.setSystemLibLink(ctx)
1896
1897 if a.properties.ApexType != zipApex {
1898 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1899 }
1900
1901 bazelCtx := ctx.Config().BazelContext
1902 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1903 if err != nil {
1904 ctx.ModuleErrorf(err.Error())
1905 return
1906 }
1907 a.installDir = android.PathForModuleInstall(ctx, "apex")
Jingwen Chen94098e82023-01-10 14:50:42 +00001908
1909 // Set the output file to .apex or .capex depending on the compression configuration.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001910 a.setCompression(ctx)
Jingwen Chen94098e82023-01-10 14:50:42 +00001911 if a.isCompressed {
1912 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedCompressedOutput)
1913 } else {
1914 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1915 }
1916 a.outputFile = a.outputApexFile
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001917
Liz Kammer0e255ef2022-11-04 16:07:04 -04001918 // TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
1919 // interface if these were set in a provider rather than the module itself
Wei Li32dcdf92022-10-26 22:30:48 -07001920 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1921 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1922 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1923 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Liz Kammer0e255ef2022-11-04 16:07:04 -04001924
Jingwen Chen29743c82023-01-25 17:49:46 +00001925 // Ensure ApexMkInfo.install_to_system make module names are installed as
1926 // part of a bundled build.
1927 a.makeModulesToInstall = append(a.makeModulesToInstall, outputs.MakeModulesToInstall...)
Vinh Tranb6803a52022-12-14 11:34:54 -05001928
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001929 apexType := a.properties.ApexType
1930 switch apexType {
1931 case imageApex:
Liz Kammer303978d2022-11-04 16:12:43 -04001932 a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001933 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
Wei Licc73a052022-11-07 14:25:34 -08001934 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001935 // TODO(b/239084755): Generate the java api using.xml file from Bazel.
Jingwen Chen1ec77852022-11-07 14:36:12 +00001936 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
Wei Li78c07de2022-11-08 16:01:05 -08001937 a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001938 installSuffix := imageApexSuffix
1939 if a.isCompressed {
1940 installSuffix = imageCapexSuffix
1941 }
1942 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1943 a.compatSymlinks.Paths()...)
1944 default:
1945 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1946 }
1947
1948 /*
1949 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1950 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1951 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1952 To find out what Soong build puts there, run:
1953 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1954 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1955 return a.depVisitor(&vctx, ctx, child, parent)
1956 })
1957 vctx.normalizeFileInfo()
1958 */
1959
1960}
1961
1962func (a *apexBundle) setCompression(ctx android.ModuleContext) {
1963 if a.properties.ApexType != imageApex {
1964 a.isCompressed = false
1965 } else if a.testOnlyShouldForceCompression() {
1966 a.isCompressed = true
1967 } else {
1968 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1969 }
1970}
1971
1972func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1973 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
1974 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1975 // the same library in the system partition, thus effectively sharing the same libraries
1976 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1977 // in the APEX.
1978 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1979
1980 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
1981 // So we can't link them to /system/lib libs which are core variants.
1982 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1983 a.linkToSystemLib = false
1984 }
1985
1986 forced := ctx.Config().ForceApexSymlinkOptimization()
1987 updatable := a.Updatable() || a.FutureUpdatable()
1988
1989 // We don't need the optimization for updatable APEXes, as it might give false signal
1990 // to the system health when the APEXes are still bundled (b/149805758).
1991 if !forced && updatable && a.properties.ApexType == imageApex {
1992 a.linkToSystemLib = false
1993 }
1994
1995 // We also don't want the optimization for host APEXes, because it doesn't make sense.
1996 if ctx.Host() {
1997 a.linkToSystemLib = false
1998 }
1999}
2000
2001func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
2002 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
2003 case ext4FsType:
2004 a.payloadFsType = ext4
2005 case f2fsFsType:
2006 a.payloadFsType = f2fs
2007 case erofsFsType:
2008 a.payloadFsType = erofs
2009 default:
2010 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
2011 }
2012}
2013
2014func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
2015 // Set suffix and primaryApexType depending on the ApexType
2016 buildFlattenedAsDefault := ctx.Config().FlattenApex()
2017 switch a.properties.ApexType {
2018 case imageApex:
2019 if buildFlattenedAsDefault {
2020 a.suffix = imageApexSuffix
2021 } else {
2022 a.suffix = ""
2023 a.primaryApexType = true
2024
2025 if ctx.Config().InstallExtraFlattenedApexes() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002026 a.makeModulesToInstall = append(a.makeModulesToInstall, a.Name()+flattenedSuffix)
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002027 }
2028 }
2029 case zipApex:
2030 if proptools.String(a.properties.Payload_type) == "zip" {
2031 a.suffix = ""
2032 a.primaryApexType = true
2033 } else {
2034 a.suffix = zipApexSuffix
2035 }
2036 case flattenedApex:
2037 if buildFlattenedAsDefault {
2038 a.suffix = ""
2039 a.primaryApexType = true
2040 } else {
2041 a.suffix = flattenedSuffix
2042 }
2043 }
2044}
2045
2046func (a apexBundle) isCompressable() bool {
2047 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
2048}
2049
2050func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
2051 a.checkApexAvailability(ctx)
2052 a.checkUpdatable(ctx)
2053 a.CheckMinSdkVersion(ctx)
2054 a.checkStaticLinkingToStubLibraries(ctx)
2055 a.checkStaticExecutables(ctx)
2056 if len(a.properties.Tests) > 0 && !a.testApex {
2057 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
2058 return false
2059 }
2060 return true
2061}
2062
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002063type visitorContext struct {
2064 // all the files that will be included in this APEX
2065 filesInfo []apexFile
2066
2067 // native lib dependencies
2068 provideNativeLibs []string
2069 requireNativeLibs []string
2070
2071 handleSpecialLibs bool
Jooyung Han862c0d62022-12-21 10:15:37 +09002072
2073 // if true, raise error on duplicate apexFile
2074 checkDuplicate bool
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002075}
2076
Jooyung Han862c0d62022-12-21 10:15:37 +09002077func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002078 encountered := make(map[string]apexFile)
2079 for _, f := range vctx.filesInfo {
2080 dest := filepath.Join(f.installDir, f.builtFile.Base())
2081 if e, ok := encountered[dest]; !ok {
2082 encountered[dest] = f
2083 } else {
Jooyung Han862c0d62022-12-21 10:15:37 +09002084 if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
2085 mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
2086 dest, e.builtFile, f.builtFile)
2087 return
2088 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002089 // If a module is directly included and also transitively depended on
2090 // consider it as directly included.
2091 e.transitiveDep = e.transitiveDep && f.transitiveDep
2092 encountered[dest] = e
2093 }
2094 }
2095 vctx.filesInfo = vctx.filesInfo[:0]
2096 for _, v := range encountered {
2097 vctx.filesInfo = append(vctx.filesInfo, v)
2098 }
2099 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2100 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2101 // changes.
2102 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2103 })
2104}
2105
2106func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2107 depTag := ctx.OtherModuleDependencyTag(child)
2108 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2109 return false
2110 }
2111 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2112 return false
2113 }
2114 depName := ctx.OtherModuleName(child)
2115 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2116 switch depTag {
2117 case sharedLibTag, jniLibTag:
2118 isJniLib := depTag == jniLibTag
2119 switch ch := child.(type) {
2120 case *cc.Module:
2121 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2122 fi.isJniLib = isJniLib
2123 vctx.filesInfo = append(vctx.filesInfo, fi)
2124 // Collect the list of stub-providing libs except:
2125 // - VNDK libs are only for vendors
2126 // - bootstrap bionic libs are treated as provided by system
2127 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2128 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2129 }
2130 return true // track transitive dependencies
2131 case *rust.Module:
2132 fi := apexFileForRustLibrary(ctx, ch)
2133 fi.isJniLib = isJniLib
2134 vctx.filesInfo = append(vctx.filesInfo, fi)
2135 return true // track transitive dependencies
2136 default:
2137 propertyName := "native_shared_libs"
2138 if isJniLib {
2139 propertyName = "jni_libs"
2140 }
2141 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2142 }
2143 case executableTag:
2144 switch ch := child.(type) {
2145 case *cc.Module:
2146 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2147 return true // track transitive dependencies
2148 case *python.Module:
2149 if ch.HostToolPath().Valid() {
2150 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2151 }
2152 case bootstrap.GoBinaryTool:
2153 if a.Host() {
2154 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2155 }
2156 case *rust.Module:
2157 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2158 return true // track transitive dependencies
2159 default:
2160 ctx.PropertyErrorf("binaries",
2161 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2162 }
2163 case shBinaryTag:
2164 if csh, ok := child.(*sh.ShBinary); ok {
2165 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2166 } else {
2167 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2168 }
2169 case bcpfTag:
2170 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2171 if !ok {
2172 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2173 return false
2174 }
2175
2176 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2177 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002178 a.makeModulesToInstall = append(a.makeModulesToInstall, makeModuleName)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002179 }
2180 return true
2181 case sscpfTag:
2182 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2183 ctx.PropertyErrorf("systemserverclasspath_fragments",
2184 "%q is not a systemserverclasspath_fragment module", depName)
2185 return false
2186 }
2187 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2188 vctx.filesInfo = append(vctx.filesInfo, *af)
2189 }
2190 return true
2191 case javaLibTag:
2192 switch child.(type) {
2193 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2194 af := apexFileForJavaModule(ctx, child.(javaModule))
2195 if !af.ok() {
2196 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2197 return false
2198 }
2199 vctx.filesInfo = append(vctx.filesInfo, af)
2200 return true // track transitive dependencies
2201 default:
2202 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2203 }
2204 case androidAppTag:
2205 switch ap := child.(type) {
2206 case *java.AndroidApp:
2207 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2208 return true // track transitive dependencies
2209 case *java.AndroidAppImport:
2210 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2211 case *java.AndroidTestHelperApp:
2212 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2213 case *java.AndroidAppSet:
2214 appDir := "app"
2215 if ap.Privileged() {
2216 appDir = "priv-app"
2217 }
2218 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2219 // suffixed so that PackageManager correctly invalidates the
2220 // existing installed apk in favour of the new APK-in-APEX.
2221 // See bugs for more information.
2222 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2223 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2224 af.certificate = java.PresignedCertificate
2225 vctx.filesInfo = append(vctx.filesInfo, af)
2226 default:
2227 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2228 }
2229 case rroTag:
2230 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2231 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2232 } else {
2233 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2234 }
2235 case bpfTag:
2236 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2237 filesToCopy, _ := bpfProgram.OutputFiles("")
2238 apex_sub_dir := bpfProgram.SubDir()
2239 for _, bpfFile := range filesToCopy {
2240 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2241 }
2242 } else {
2243 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2244 }
2245 case fsTag:
2246 if fs, ok := child.(filesystem.Filesystem); ok {
2247 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2248 } else {
2249 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2250 }
2251 case prebuiltTag:
2252 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2253 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2254 } else {
2255 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2256 }
2257 case compatConfigTag:
2258 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2259 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2260 } else {
2261 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2262 }
2263 case testTag:
2264 if ccTest, ok := child.(*cc.Module); ok {
2265 if ccTest.IsTestPerSrcAllTestsVariation() {
2266 // Multiple-output test module (where `test_per_src: true`).
2267 //
2268 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2269 // We do not add this variation to `filesInfo`, as it has no output;
2270 // however, we do add the other variations of this module as indirect
2271 // dependencies (see below).
2272 } else {
2273 // Single-output test module (where `test_per_src: false`).
2274 af := apexFileForExecutable(ctx, ccTest)
2275 af.class = nativeTest
2276 vctx.filesInfo = append(vctx.filesInfo, af)
2277 }
2278 return true // track transitive dependencies
2279 } else {
2280 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2281 }
2282 case keyTag:
2283 if key, ok := child.(*apexKey); ok {
2284 a.privateKeyFile = key.privateKeyFile
2285 a.publicKeyFile = key.publicKeyFile
2286 } else {
2287 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2288 }
2289 case certificateTag:
2290 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2291 a.containerCertificateFile = dep.Certificate.Pem
2292 a.containerPrivateKeyFile = dep.Certificate.Key
2293 } else {
2294 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2295 }
2296 case android.PrebuiltDepTag:
2297 // If the prebuilt is force disabled, remember to delete the prebuilt file
2298 // that might have been installed in the previous builds
2299 if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2300 a.prebuiltFileToDelete = prebuilt.InstallFilename()
2301 }
2302 }
2303 return false
2304 }
2305
2306 if a.vndkApex {
2307 return false
2308 }
2309
2310 // indirect dependencies
2311 am, ok := child.(android.ApexModule)
2312 if !ok {
2313 return false
2314 }
2315 // We cannot use a switch statement on `depTag` here as the checked
2316 // tags used below are private (e.g. `cc.sharedDepTag`).
2317 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2318 if ch, ok := child.(*cc.Module); ok {
2319 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2320 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2321 return false
2322 }
2323 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2324 af.transitiveDep = true
2325
2326 // Always track transitive dependencies for host.
2327 if a.Host() {
2328 vctx.filesInfo = append(vctx.filesInfo, af)
2329 return true
2330 }
2331
2332 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2333 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2334 // If the dependency is a stubs lib, don't include it in this APEX,
2335 // but make sure that the lib is installed on the device.
2336 // In case no APEX is having the lib, the lib is installed to the system
2337 // partition.
2338 //
2339 // Always include if we are a host-apex however since those won't have any
2340 // system libraries.
Alan Stokes73feba32022-11-14 12:21:24 +00002341 if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002342 // we need a module name for Make
2343 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
Jingwen Chen29743c82023-01-25 17:49:46 +00002344 if !android.InList(name, a.makeModulesToInstall) {
2345 a.makeModulesToInstall = append(a.makeModulesToInstall, name)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002346 }
2347 }
2348 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2349 // Don't track further
2350 return false
2351 }
2352
2353 // If the dep is not considered to be in the same
2354 // apex, don't add it to filesInfo so that it is not
2355 // included in this APEX.
2356 // TODO(jiyong): move this to at the top of the
2357 // else-if clause for the indirect dependencies.
2358 // Currently, that's impossible because we would
2359 // like to record requiredNativeLibs even when
2360 // DepIsInSameAPex is false. We also shouldn't do
2361 // this for host.
2362 //
2363 // TODO(jiyong): explain why the same module is passed in twice.
2364 // Switching the first am to parent breaks lots of tests.
2365 if !android.IsDepInSameApex(ctx, am, am) {
2366 return false
2367 }
2368
2369 vctx.filesInfo = append(vctx.filesInfo, af)
2370 return true // track transitive dependencies
2371 } else if rm, ok := child.(*rust.Module); ok {
2372 af := apexFileForRustLibrary(ctx, rm)
2373 af.transitiveDep = true
2374 vctx.filesInfo = append(vctx.filesInfo, af)
2375 return true // track transitive dependencies
2376 }
2377 } else if cc.IsTestPerSrcDepTag(depTag) {
2378 if ch, ok := child.(*cc.Module); ok {
2379 af := apexFileForExecutable(ctx, ch)
2380 // Handle modules created as `test_per_src` variations of a single test module:
2381 // use the name of the generated test binary (`fileToCopy`) instead of the name
2382 // of the original test module (`depName`, shared by all `test_per_src`
2383 // variations of that module).
2384 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2385 // these are not considered transitive dep
2386 af.transitiveDep = false
2387 vctx.filesInfo = append(vctx.filesInfo, af)
2388 return true // track transitive dependencies
2389 }
2390 } else if cc.IsHeaderDepTag(depTag) {
2391 // nothing
2392 } else if java.IsJniDepTag(depTag) {
2393 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2394 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2395 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2396 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2397 }
2398 } else if rust.IsDylibDepTag(depTag) {
2399 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2400 af := apexFileForRustLibrary(ctx, rustm)
2401 af.transitiveDep = true
2402 vctx.filesInfo = append(vctx.filesInfo, af)
2403 return true // track transitive dependencies
2404 }
2405 } else if rust.IsRlibDepTag(depTag) {
2406 // Rlib is statically linked, but it might have shared lib
2407 // dependencies. Track them.
2408 return true
2409 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2410 // Add the contents of the bootclasspath fragment to the apex.
2411 switch child.(type) {
2412 case *java.Library, *java.SdkLibrary:
2413 javaModule := child.(javaModule)
2414 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2415 if !af.ok() {
2416 ctx.PropertyErrorf("bootclasspath_fragments",
2417 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2418 return false
2419 }
2420 vctx.filesInfo = append(vctx.filesInfo, af)
2421 return true // track transitive dependencies
2422 default:
2423 ctx.PropertyErrorf("bootclasspath_fragments",
2424 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2425 }
2426 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2427 // Add the contents of the systemserverclasspath fragment to the apex.
2428 switch child.(type) {
2429 case *java.Library, *java.SdkLibrary:
2430 af := apexFileForJavaModule(ctx, child.(javaModule))
2431 vctx.filesInfo = append(vctx.filesInfo, af)
2432 return true // track transitive dependencies
2433 default:
2434 ctx.PropertyErrorf("systemserverclasspath_fragments",
2435 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2436 }
2437 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2438 // nothing
2439 } else if depTag == android.DarwinUniversalVariantTag {
2440 // nothing
2441 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2442 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2443 }
2444 return false
2445}
2446
Jooyung Han862c0d62022-12-21 10:15:37 +09002447func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
2448 // TODO(b/263308293) remove this
2449 if a.properties.IsCoverageVariant {
2450 return false
2451 }
2452 // TODO(b/263308515) remove this
2453 if a.testApex {
2454 return false
2455 }
2456 // TODO(b/263309864) remove this
2457 if a.Host() {
2458 return false
2459 }
2460 if a.Device() && ctx.DeviceConfig().DeviceArch() == "" {
2461 return false
2462 }
2463 return true
2464}
2465
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002466// Creates build rules for an APEX. It consists of the following major steps:
2467//
2468// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2469// 2) traverse the dependency tree to collect apexFile structs from them.
2470// 3) some fields in apexBundle struct are configured
2471// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002472func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002473 ////////////////////////////////////////////////////////////////////////////////////////////
2474 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002475 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002476 return
2477 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002478 ////////////////////////////////////////////////////////////////////////////////////////////
2479 // 2) traverse the dependency tree to collect apexFile structs from them.
2480
braleeb0c1f0c2021-06-07 22:49:13 +08002481 // Collect the module directory for IDE info in java/jdeps.go.
2482 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2483
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002484 // TODO(jiyong): do this using WalkPayloadDeps
2485 // TODO(jiyong): make this clean!!!
Jooyung Han862c0d62022-12-21 10:15:37 +09002486 vctx := visitorContext{
2487 handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case),
2488 checkDuplicate: a.shouldCheckDuplicate(ctx),
2489 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002490 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
Jooyung Han862c0d62022-12-21 10:15:37 +09002491 vctx.normalizeFileInfo(ctx)
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002492 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002493 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002494 return
2495 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002496
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002497 ////////////////////////////////////////////////////////////////////////////////////////////
2498 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002499 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002500 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002501
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002502 a.setApexTypeAndSuffix(ctx)
2503 a.setPayloadFsType(ctx)
2504 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002505 if a.properties.ApexType != zipApex {
2506 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2507 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002508
2509 ////////////////////////////////////////////////////////////////////////////////////////////
2510 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002511 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002512 if a.properties.ApexType == flattenedApex {
2513 a.buildFlattenedApex(ctx)
2514 } else {
2515 a.buildUnflattenedApex(ctx)
2516 }
Jiyong Park956305c2020-01-09 12:32:06 +09002517 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002518 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002519
2520 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2521 if a.installable() {
2522 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2523 // along with other ordinary files. (Note that this is done by apexer for
2524 // non-flattened APEXes)
2525 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2526
2527 // Place the public key as apex_pubkey. This is also done by apexer for
2528 // non-flattened APEXes case.
2529 // TODO(jiyong): Why do we need this CP rule?
2530 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2531 ctx.Build(pctx, android.BuildParams{
2532 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002533 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002534 Output: copiedPubkey,
2535 })
2536 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2537 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002538}
2539
Paul Duffincc33ec82021-04-25 23:14:55 +01002540// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2541// the bootclasspath_fragment contributes to the apex.
2542func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2543 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2544 var filesToAdd []apexFile
2545
2546 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002547 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2548 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2549 dirInApex := filepath.Join("javalib", arch.String())
2550 for _, f := range files {
2551 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2552 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2553 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2554 filesToAdd = append(filesToAdd, af)
2555 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002556 }
2557 }
2558
satayev3db35472021-05-06 23:59:58 +01002559 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002560 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2561 filesToAdd = append(filesToAdd, *af)
2562 }
satayev3db35472021-05-06 23:59:58 +01002563
Ulya Trafimovichf5c548d2022-11-16 14:52:41 +00002564 pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2565 if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002566 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2567 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2568
2569 if pathOnHost != nil {
2570 // We need to copy the profile to a temporary path with the right filename because the apexer
2571 // will take the filename as is.
2572 ctx.Build(pctx, android.BuildParams{
2573 Rule: android.Cp,
2574 Input: pathOnHost,
2575 Output: tempPath,
2576 })
2577 } else {
2578 // At this point, the boot image profile cannot be generated. It is probably because the boot
2579 // image profile source file does not exist on the branch, or it is not available for the
2580 // current build target.
2581 // However, we cannot enforce the boot image profile to be generated because some build
2582 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2583 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2584 // only if the APEX is being built.
2585 ctx.Build(pctx, android.BuildParams{
2586 Rule: android.ErrorRule,
2587 Output: tempPath,
2588 Args: map[string]string{
2589 "error": "Boot image profile cannot be generated",
2590 },
2591 })
2592 }
2593
2594 androidMkModuleName := filepath.Base(pathInApex)
2595 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2596 filesToAdd = append(filesToAdd, af)
2597 }
2598
Paul Duffincc33ec82021-04-25 23:14:55 +01002599 return filesToAdd
2600}
2601
satayevb98371c2021-06-15 16:49:50 +01002602// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2603// the module contributes to the apex; or nil if the proto config was not generated.
2604func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2605 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2606 if !info.ClasspathFragmentProtoGenerated {
2607 return nil
2608 }
2609 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2610 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2611 return &af
satayev14e49132021-05-17 21:03:07 +01002612}
2613
Paul Duffincc33ec82021-04-25 23:14:55 +01002614// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2615// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002616func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2617 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2618
2619 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2620 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002621 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2622 if err != nil {
2623 ctx.ModuleErrorf("%s", err)
2624 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002625
2626 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2627 // bootclasspath_fragment.
2628 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2629 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002630}
2631
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002632///////////////////////////////////////////////////////////////////////////////////////////////////
2633// Factory functions
2634//
2635
2636func newApexBundle() *apexBundle {
2637 module := &apexBundle{}
2638
2639 module.AddProperties(&module.properties)
2640 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002641 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002642 module.AddProperties(&module.overridableProperties)
2643
2644 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2645 android.InitDefaultableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002646 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002647 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002648 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002649 return module
2650}
2651
Paul Duffineb8051d2021-10-18 17:49:39 +01002652func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002653 bundle := newApexBundle()
2654 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002655 return bundle
2656}
2657
2658// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2659// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002660func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002661 bundle := newApexBundle()
2662 bundle.testApex = true
2663 return bundle
2664}
2665
2666// apex packages other modules into an APEX file which is a packaging format for system-level
2667// components like binaries, shared libraries, etc.
2668func BundleFactory() android.Module {
2669 return newApexBundle()
2670}
2671
2672type Defaults struct {
2673 android.ModuleBase
2674 android.DefaultsModuleBase
2675}
2676
2677// apex_defaults provides defaultable properties to other apex modules.
2678func defaultsFactory() android.Module {
2679 return DefaultsFactory()
2680}
2681
2682func DefaultsFactory(props ...interface{}) android.Module {
2683 module := &Defaults{}
2684
2685 module.AddProperties(props...)
2686 module.AddProperties(
2687 &apexBundleProperties{},
2688 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002689 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002690 &overridableProperties{},
2691 )
2692
2693 android.InitDefaultsModule(module)
2694 return module
2695}
2696
2697type OverrideApex struct {
2698 android.ModuleBase
2699 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002700 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002701}
2702
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002703func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002704 // All the overrides happen in the base module.
2705}
2706
2707// override_apex is used to create an apex module based on another apex module by overriding some of
2708// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002709func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002710 m := &OverrideApex{}
2711
2712 m.AddProperties(&overridableProperties{})
2713
2714 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2715 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002716 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002717 return m
2718}
2719
Wei Li1c66fc72022-05-09 23:59:14 -07002720func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2721 if ctx.ModuleType() != "override_apex" {
2722 return
2723 }
2724
2725 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2726 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2727 if !baseApexExists {
2728 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2729 }
2730
2731 a, baseModuleIsApex := baseModule.(*apexBundle)
2732 if !baseModuleIsApex {
2733 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2734 }
2735 attrs, props := convertWithBp2build(a, ctx)
2736
Jingwen Chenc4c34e12022-11-29 12:07:45 +00002737 // We just want the name, not module reference.
2738 baseApexName := strings.TrimPrefix(baseApexModuleName, ":")
2739 attrs.Base_apex_name = &baseApexName
2740
Wei Li1c66fc72022-05-09 23:59:14 -07002741 for _, p := range o.GetProperties() {
2742 overridableProperties, ok := p.(*overridableProperties)
2743 if !ok {
2744 continue
2745 }
Wei Li40f98732022-05-20 22:08:11 -07002746
2747 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2748 // After it is converted in convertWithBp2build(baseApex, ctx),
2749 // the attrs.Manifest.Value.Label is the file path relative to the directory
2750 // of base apex. So the following code converts it to a label that looks like
2751 // <package of base apex>:<path of manifest file> if base apex and override
2752 // apex are not in the same package.
2753 baseApexPackage := ctx.OtherModuleDir(a)
2754 overrideApexPackage := ctx.ModuleDir()
2755 if baseApexPackage != overrideApexPackage {
2756 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2757 }
2758
Wei Li1c66fc72022-05-09 23:59:14 -07002759 // Key
2760 if overridableProperties.Key != nil {
2761 attrs.Key = bazel.LabelAttribute{}
2762 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2763 }
2764
2765 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002766 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002767 // If overridableProperties.Certificate is nil, clear this out as
2768 // well with zeroed structs, so the override_apex does not use the
2769 // base apex's certificate.
2770 attrs.Certificate = bazel.LabelAttribute{}
2771 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002772 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002773 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002774 }
2775
2776 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002777 if overridableProperties.Prebuilts != nil {
2778 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2779 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2780 }
Wei Li1c66fc72022-05-09 23:59:14 -07002781
2782 // Compressible
2783 if overridableProperties.Compressible != nil {
2784 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2785 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002786
2787 // Package name
2788 //
2789 // e.g. com.android.adbd's package name is com.android.adbd, but
2790 // com.google.android.adbd overrides the package name to com.google.android.adbd
2791 //
2792 // TODO: this can be overridden from the product configuration, see
2793 // getOverrideManifestPackageName and
2794 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2795 //
2796 // Instead of generating the BUILD files differently based on the product config
2797 // at the point of conversion, this should be handled by the BUILD file loading
2798 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2799 if overridableProperties.Package_name != "" {
2800 attrs.Package_name = &overridableProperties.Package_name
2801 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002802
2803 // Logging parent
2804 if overridableProperties.Logging_parent != "" {
2805 attrs.Logging_parent = &overridableProperties.Logging_parent
2806 }
Wei Li1c66fc72022-05-09 23:59:14 -07002807 }
2808
2809 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2810}
2811
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002812///////////////////////////////////////////////////////////////////////////////////////////////////
2813// Vality check routines
2814//
2815// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2816// certain conditions are not met.
2817//
2818// TODO(jiyong): move these checks to a separate go file.
2819
satayevad991492021-12-03 18:58:32 +00002820var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2821
Spandan Dasa5f39a12022-08-05 02:35:52 +00002822// 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 +09002823// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002824func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002825 if a.testApex || a.vndkApex {
2826 return
2827 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002828 // apexBundle::minSdkVersion reports its own errors.
2829 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002830 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002831}
2832
Albert Martineefabcf2022-03-21 20:11:16 +00002833// Returns apex's min_sdk_version string value, honoring overrides
2834func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2835 // Only override the minSdkVersion value on Apexes which already specify
2836 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2837 // min_sdk_version value is lower than the one to override with.
Colin Cross56534df2022-10-04 09:58:58 -07002838 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
2839 if minApiLevel.IsNone() {
2840 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002841 }
2842
Colin Cross56534df2022-10-04 09:58:58 -07002843 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2844 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2845 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2846 minApiLevel = overrideApiLevel
2847 }
2848
2849 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002850}
2851
2852// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002853func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2854 return android.SdkSpec{
2855 Kind: android.SdkNone,
2856 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002857 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002858 }
2859}
2860
Albert Martineefabcf2022-03-21 20:11:16 +00002861// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002862func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002863 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2864}
2865
2866// Construct ApiLevel object from min_sdk_version string value
2867func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2868 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002869 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002870 }
Albert Martineefabcf2022-03-21 20:11:16 +00002871 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002872 if err != nil {
2873 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2874 return android.NoneApiLevel
2875 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002876 return apiLevel
2877}
2878
2879// Ensures that a lib providing stub isn't statically linked
2880func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2881 // Practically, we only care about regular APEXes on the device.
2882 if ctx.Host() || a.testApex || a.vndkApex {
2883 return
2884 }
2885
2886 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2887
2888 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2889 if ccm, ok := to.(*cc.Module); ok {
2890 apexName := ctx.ModuleName()
2891 fromName := ctx.OtherModuleName(from)
2892 toName := ctx.OtherModuleName(to)
2893
2894 // If `to` is not actually in the same APEX as `from` then it does not need
2895 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002896 //
2897 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002898 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2899 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2900 return false
2901 }
2902
2903 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2904 // exception to this rule. It can't make the static dependencies dynamic
2905 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002906 // Same rule should be applied to linkerconfig, because it should be executed
2907 // only with static linked libraries before linker is available with ld.config.txt
2908 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002909 return false
2910 }
2911
2912 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2913 if isStubLibraryFromOtherApex && !externalDep {
2914 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2915 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2916 }
2917
2918 }
2919 return true
2920 })
2921}
2922
satayevb98371c2021-06-15 16:49:50 +01002923// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002924func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2925 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002926 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002927 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2928 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002929 if a.UsePlatformApis() {
2930 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2931 }
Daniel Norman69109112021-12-02 12:52:42 -08002932 if a.SocSpecific() || a.DeviceSpecific() {
2933 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2934 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002935 if a.FutureUpdatable() {
2936 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2937 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002938 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002939 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002940 }
2941}
2942
satayevb98371c2021-06-15 16:49:50 +01002943// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2944func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2945 ctx.VisitDirectDeps(func(module android.Module) {
2946 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2947 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2948 if !info.ClasspathFragmentProtoGenerated {
2949 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2950 }
2951 }
2952 })
2953}
2954
2955// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002956func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002957 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2958 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002959 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2960 tag := ctx.OtherModuleDependencyTag(module)
2961 switch tag {
2962 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002963 if m, ok := module.(interface {
2964 CheckStableSdkVersion(ctx android.BaseModuleContext) error
2965 }); ok {
2966 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01002967 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2968 }
2969 }
2970 }
2971 })
2972}
2973
satayevb98371c2021-06-15 16:49:50 +01002974// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002975func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2976 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
2977 if ctx.Host() || a.testApex || a.vndkApex {
2978 return
2979 }
2980
2981 // Because APEXes targeting other than system/system_ext partitions can't set
2982 // apex_available, we skip checks for these APEXes
2983 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2984 return
2985 }
2986
2987 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
2988 // Requiring them and their transitive depencies with apex_available is not right
2989 // because they just add noise.
2990 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2991 return
2992 }
2993
2994 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2995 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2996 if externalDep {
2997 return false
2998 }
2999
3000 apexName := ctx.ModuleName()
3001 fromName := ctx.OtherModuleName(from)
3002 toName := ctx.OtherModuleName(to)
3003
3004 // If `to` is not actually in the same APEX as `from` then it does not need
3005 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00003006 //
3007 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003008 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
3009 // As soon as the dependency graph crosses the APEX boundary, don't go
3010 // further.
3011 return false
3012 }
3013
3014 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
3015 return true
3016 }
Jiyong Park767dbd92021-03-04 13:03:10 +09003017 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
3018 "\n\nDependency path:%s\n\n"+
3019 "Consider adding %q to 'apex_available' property of %q",
3020 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003021 // Visit this module's dependencies to check and report any issues with their availability.
3022 return true
3023 })
3024}
3025
Jiyong Park192600a2021-08-03 07:52:17 +00003026// checkStaticExecutable ensures that executables in an APEX are not static.
3027func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09003028 // No need to run this for host APEXes
3029 if ctx.Host() {
3030 return
3031 }
3032
Jiyong Park192600a2021-08-03 07:52:17 +00003033 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3034 if ctx.OtherModuleDependencyTag(module) != executableTag {
3035 return
3036 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09003037
3038 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00003039 apex := a.ApexVariationName()
3040 exec := ctx.OtherModuleName(module)
3041 if isStaticExecutableAllowed(apex, exec) {
3042 return
3043 }
3044 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
3045 }
3046 })
3047}
3048
3049// A small list of exceptions where static executables are allowed in APEXes.
3050func isStaticExecutableAllowed(apex string, exec string) bool {
3051 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003052 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00003053 "linker",
3054 "linkerconfig",
3055 },
3056 }
3057 execNames, ok := m[apex]
3058 return ok && android.InList(exec, execNames)
3059}
3060
braleeb0c1f0c2021-06-07 22:49:13 +08003061// Collect information for opening IDE project files in java/jdeps.go.
3062func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09003063 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
3064 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
3065 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08003066 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
3067}
3068
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003069var (
3070 apexAvailBaseline = makeApexAvailableBaseline()
3071 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
3072)
3073
Colin Cross440e0d02020-06-11 11:32:11 -07003074func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003075 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003076 moduleName = normalizeModuleName(moduleName)
3077
Colin Cross440e0d02020-06-11 11:32:11 -07003078 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003079 return true
3080 }
3081
3082 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07003083 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003084 return true
3085 }
3086
3087 return false
3088}
3089
3090func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09003091 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
3092 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00003093 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09003094 if strings.HasPrefix(moduleName, "libclang_rt.") {
3095 // This module has many arch variants that depend on the product being built.
3096 // We don't want to list them all
3097 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003098 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003099 if strings.HasPrefix(moduleName, "androidx.") {
3100 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3101 moduleName = "androidx"
3102 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003103 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003104}
3105
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003106// Transform the map of apex -> modules to module -> apexes.
3107func invertApexBaseline(m map[string][]string) map[string][]string {
3108 r := make(map[string][]string)
3109 for apex, modules := range m {
3110 for _, module := range modules {
3111 r[module] = append(r[module], apex)
3112 }
3113 }
3114 return r
3115}
3116
3117// Retrieve the baseline of apexes to which the supplied module belongs.
3118func BaselineApexAvailable(moduleName string) []string {
3119 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3120}
3121
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003122// This is a map from apex to modules, which overrides the apex_available setting for that
3123// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003124// TODO(b/147364041): remove this
3125func makeApexAvailableBaseline() map[string][]string {
3126 // The "Module separator"s below are employed to minimize merge conflicts.
3127 m := make(map[string][]string)
3128 //
3129 // Module separator
3130 //
3131 m["com.android.appsearch"] = []string{
3132 "icing-java-proto-lite",
3133 "libprotobuf-java-lite",
3134 }
3135 //
3136 // Module separator
3137 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003138 m["com.android.btservices"] = []string{
William Escande89bca3f2022-06-28 18:03:30 -07003139 // empty
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003140 }
3141 //
3142 // Module separator
3143 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003144 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3145 //
3146 // Module separator
3147 //
3148 m["com.android.extservices"] = []string{
3149 "error_prone_annotations",
3150 "ExtServices-core",
3151 "ExtServices",
3152 "libtextclassifier-java",
3153 "libz_current",
3154 "textclassifier-statsd",
3155 "TextClassifierNotificationLibNoManifest",
3156 "TextClassifierServiceLibNoManifest",
3157 }
3158 //
3159 // Module separator
3160 //
3161 m["com.android.neuralnetworks"] = []string{
3162 "android.hardware.neuralnetworks@1.0",
3163 "android.hardware.neuralnetworks@1.1",
3164 "android.hardware.neuralnetworks@1.2",
3165 "android.hardware.neuralnetworks@1.3",
3166 "android.hidl.allocator@1.0",
3167 "android.hidl.memory.token@1.0",
3168 "android.hidl.memory@1.0",
3169 "android.hidl.safe_union@1.0",
3170 "libarect",
3171 "libbuildversion",
3172 "libmath",
3173 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003174 }
3175 //
3176 // Module separator
3177 //
3178 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003179 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003180 }
3181 //
3182 // Module separator
3183 //
3184 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003185 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003186 }
3187 //
3188 // Module separator
3189 //
3190 m["com.android.mediaprovider"] = []string{
3191 "MediaProvider",
3192 "MediaProviderGoogle",
3193 "fmtlib_ndk",
3194 "libbase_ndk",
3195 "libfuse",
3196 "libfuse_jni",
3197 }
3198 //
3199 // Module separator
3200 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003201 m["com.android.runtime"] = []string{
3202 "bionic_libc_platform_headers",
3203 "libarm-optimized-routines-math",
3204 "libc_aeabi",
3205 "libc_bionic",
3206 "libc_bionic_ndk",
3207 "libc_bootstrap",
3208 "libc_common",
3209 "libc_common_shared",
3210 "libc_common_static",
3211 "libc_dns",
3212 "libc_dynamic_dispatch",
3213 "libc_fortify",
3214 "libc_freebsd",
3215 "libc_freebsd_large_stack",
3216 "libc_gdtoa",
3217 "libc_init_dynamic",
3218 "libc_init_static",
3219 "libc_jemalloc_wrapper",
3220 "libc_netbsd",
3221 "libc_nomalloc",
3222 "libc_nopthread",
3223 "libc_openbsd",
3224 "libc_openbsd_large_stack",
3225 "libc_openbsd_ndk",
3226 "libc_pthread",
3227 "libc_static_dispatch",
3228 "libc_syscalls",
3229 "libc_tzcode",
3230 "libc_unwind_static",
3231 "libdebuggerd",
3232 "libdebuggerd_common_headers",
3233 "libdebuggerd_handler_core",
3234 "libdebuggerd_handler_fallback",
3235 "libdl_static",
3236 "libjemalloc5",
3237 "liblinker_main",
3238 "liblinker_malloc",
3239 "liblz4",
3240 "liblzma",
3241 "libprocinfo",
3242 "libpropertyinfoparser",
3243 "libscudo",
3244 "libstdc++",
3245 "libsystemproperties",
3246 "libtombstoned_client_static",
3247 "libunwindstack",
3248 "libz",
3249 "libziparchive",
3250 }
3251 //
3252 // Module separator
3253 //
3254 m["com.android.tethering"] = []string{
3255 "android.hardware.tetheroffload.config-V1.0-java",
3256 "android.hardware.tetheroffload.control-V1.0-java",
3257 "android.hidl.base-V1.0-java",
3258 "libcgrouprc",
3259 "libcgrouprc_format",
3260 "libtetherutilsjni",
3261 "libvndksupport",
3262 "net-utils-framework-common",
3263 "netd_aidl_interface-V3-java",
3264 "netlink-client",
3265 "networkstack-aidl-interfaces-java",
3266 "tethering-aidl-interfaces-java",
3267 "TetheringApiCurrentLib",
3268 }
3269 //
3270 // Module separator
3271 //
3272 m["com.android.wifi"] = []string{
3273 "PlatformProperties",
3274 "android.hardware.wifi-V1.0-java",
3275 "android.hardware.wifi-V1.0-java-constants",
3276 "android.hardware.wifi-V1.1-java",
3277 "android.hardware.wifi-V1.2-java",
3278 "android.hardware.wifi-V1.3-java",
3279 "android.hardware.wifi-V1.4-java",
3280 "android.hardware.wifi.hostapd-V1.0-java",
3281 "android.hardware.wifi.hostapd-V1.1-java",
3282 "android.hardware.wifi.hostapd-V1.2-java",
3283 "android.hardware.wifi.supplicant-V1.0-java",
3284 "android.hardware.wifi.supplicant-V1.1-java",
3285 "android.hardware.wifi.supplicant-V1.2-java",
3286 "android.hardware.wifi.supplicant-V1.3-java",
3287 "android.hidl.base-V1.0-java",
3288 "android.hidl.manager-V1.0-java",
3289 "android.hidl.manager-V1.1-java",
3290 "android.hidl.manager-V1.2-java",
3291 "bouncycastle-unbundled",
3292 "dnsresolver_aidl_interface-V2-java",
3293 "error_prone_annotations",
3294 "framework-wifi-pre-jarjar",
3295 "framework-wifi-util-lib",
3296 "ipmemorystore-aidl-interfaces-V3-java",
3297 "ipmemorystore-aidl-interfaces-java",
3298 "ksoap2",
3299 "libnanohttpd",
3300 "libwifi-jni",
3301 "net-utils-services-common",
3302 "netd_aidl_interface-V2-java",
3303 "netd_aidl_interface-unstable-java",
3304 "netd_event_listener_interface-java",
3305 "netlink-client",
3306 "networkstack-client",
3307 "services.net",
3308 "wifi-lite-protos",
3309 "wifi-nano-protos",
3310 "wifi-service-pre-jarjar",
3311 "wifi-service-resources",
3312 }
3313 //
3314 // Module separator
3315 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003316 m["com.android.os.statsd"] = []string{
3317 "libstatssocket",
3318 }
3319 //
3320 // Module separator
3321 //
3322 m[android.AvailableToAnyApex] = []string{
3323 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3324 "androidx",
3325 "androidx-constraintlayout_constraintlayout",
3326 "androidx-constraintlayout_constraintlayout-nodeps",
3327 "androidx-constraintlayout_constraintlayout-solver",
3328 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3329 "com.google.android.material_material",
3330 "com.google.android.material_material-nodeps",
3331
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003332 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003333 "libprofile-clang-extras",
3334 "libprofile-clang-extras_ndk",
3335 "libprofile-extras",
3336 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003337 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003338 }
3339 return m
3340}
3341
3342func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003343 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3344 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003345}
3346
Spandan Dasf14e2542021-11-12 00:01:37 +00003347func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3348 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3349 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003350 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003351 With("name", jar).
3352 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3353 Because(jar +
3354 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003355 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003356 " 1. If the offending code is from a statically linked library, consider " +
3357 "removing that dependency and using an alternative already in the " +
3358 "bootclasspath, or perhaps a shared library." +
3359 " 2. Move the offending code into an allowed package.\n" +
3360 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3361 "health implications of bundling that code, particularly if the offending jar " +
3362 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003363
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003364 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003365 }
3366 return rules
3367}
3368
Anton Hanssone1b18362021-12-23 15:05:38 +00003369// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003370// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003371func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003372 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003373 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003374 "android.net.ssl",
3375 "com.android.org.conscrypt",
3376 },
Wei Li40f98732022-05-20 22:08:11 -07003377 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003378 "android.media",
3379 },
3380 }
3381}
3382
Anton Hanssone1b18362021-12-23 15:05:38 +00003383// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003384// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003385func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003386 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003387 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003388 "android.provider",
3389 },
Wei Li40f98732022-05-20 22:08:11 -07003390 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003391 "android.permission",
3392 "android.app.role",
3393 "com.android.permission",
3394 "com.android.role",
3395 },
Wei Li40f98732022-05-20 22:08:11 -07003396 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003397 "android.os.ext",
3398 },
Wei Li40f98732022-05-20 22:08:11 -07003399 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003400 "android.app",
3401 "android.os",
3402 "android.util",
3403 "com.android.internal.statsd",
3404 "com.android.server.stats",
3405 },
Wei Li40f98732022-05-20 22:08:11 -07003406 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003407 "com.android.server.wifi",
3408 "com.android.wifi.x",
3409 "android.hardware.wifi",
3410 "android.net.wifi",
3411 },
Wei Li40f98732022-05-20 22:08:11 -07003412 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003413 "android.net",
3414 },
3415 }
3416}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003417
3418// For Bazel / bp2build
3419
3420type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003421 Manifest bazel.LabelAttribute
3422 Android_manifest bazel.LabelAttribute
3423 File_contexts bazel.LabelAttribute
3424 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003425 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3426 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Liz Kammerb83b7b02022-12-21 14:53:41 -05003427 Min_sdk_version bazel.StringAttribute
Yu Liu4ae55d12022-01-05 17:17:23 -08003428 Updatable bazel.BoolAttribute
3429 Installable bazel.BoolAttribute
3430 Binaries bazel.LabelListAttribute
3431 Prebuilts bazel.LabelListAttribute
3432 Native_shared_libs_32 bazel.LabelListAttribute
3433 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003434 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003435 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003436 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003437 Tests bazel.LabelListAttribute
Jingwen Chenc4c34e12022-11-29 12:07:45 +00003438 Base_apex_name *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003439}
3440
3441type convertedNativeSharedLibs struct {
3442 Native_shared_libs_32 bazel.LabelListAttribute
3443 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003444}
3445
Liz Kammerb83b7b02022-12-21 14:53:41 -05003446const (
3447 minSdkVersionPropName = "Min_sdk_version"
3448)
3449
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003450// ConvertWithBp2build performs bp2build conversion of an apex
3451func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003452 // We only convert apex and apex_test modules at this time
3453 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003454 return
3455 }
3456
Wei Li1c66fc72022-05-09 23:59:14 -07003457 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003458 commonAttrs := android.CommonAttributes{
3459 Name: a.Name(),
3460 }
3461 if a.testApex {
3462 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3463 }
3464 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003465}
3466
3467func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003468 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003469 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003470
3471 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003472 if a.properties.AndroidManifest != nil {
3473 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003474 }
3475
3476 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003477 if a.properties.File_contexts == nil {
3478 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3479 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3480 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3481 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003482 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003483 } else {
3484 // File_contexts is a file
3485 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003486 }
3487
Liz Kammerb83b7b02022-12-21 14:53:41 -05003488 productVariableProps := android.ProductVariableProperties(ctx)
Albert Martineefabcf2022-03-21 20:11:16 +00003489 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3490 // given it's coming via config, we probably don't want to put it in here.
Liz Kammerb83b7b02022-12-21 14:53:41 -05003491 var minSdkVersion bazel.StringAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003492 if a.properties.Min_sdk_version != nil {
Liz Kammerb83b7b02022-12-21 14:53:41 -05003493 minSdkVersion.SetValue(*a.properties.Min_sdk_version)
3494 }
3495 if props, ok := productVariableProps[minSdkVersionPropName]; ok {
3496 for c, p := range props {
3497 if val, ok := p.(*string); ok {
3498 minSdkVersion.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val)
3499 }
3500 }
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003501 }
3502
3503 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003504 if a.overridableProperties.Key != nil {
3505 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003506 }
3507
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003508 // Certificate
3509 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003510
Yu Liu4ae55d12022-01-05 17:17:23 -08003511 nativeSharedLibs := &convertedNativeSharedLibs{
3512 Native_shared_libs_32: bazel.LabelListAttribute{},
3513 Native_shared_libs_64: bazel.LabelListAttribute{},
3514 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003515
3516 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3517 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3518 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3519 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3520 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003521 if a.CompileMultilib() != nil {
3522 compileMultilib = *a.CompileMultilib()
3523 }
3524
3525 // properties.Native_shared_libs is treated as "both"
3526 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3527 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3528 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3529 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3530 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003531
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003532 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003533 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3534 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3535
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003536 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003537 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003538
Yu Liu4c212ce2022-10-14 12:20:20 -07003539 var testsAttrs bazel.LabelListAttribute
3540 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3541 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3542 testsAttrs = bazel.MakeLabelListAttribute(tests)
3543 }
3544
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003545 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003546 if a.properties.Updatable != nil {
3547 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003548 }
3549
3550 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003551 if a.properties.Installable != nil {
3552 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003553 }
3554
Wei Lif034cb42022-01-19 15:54:31 -08003555 var compressibleAttribute bazel.BoolAttribute
3556 if a.overridableProperties.Compressible != nil {
3557 compressibleAttribute.Value = a.overridableProperties.Compressible
3558 }
3559
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003560 var packageName *string
3561 if a.overridableProperties.Package_name != "" {
3562 packageName = &a.overridableProperties.Package_name
3563 }
3564
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003565 var loggingParent *string
3566 if a.overridableProperties.Logging_parent != "" {
3567 loggingParent = &a.overridableProperties.Logging_parent
3568 }
3569
Wei Li1c66fc72022-05-09 23:59:14 -07003570 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003571 Manifest: manifestLabelAttribute,
3572 Android_manifest: androidManifestLabelAttribute,
3573 File_contexts: fileContextsLabelAttribute,
3574 Min_sdk_version: minSdkVersion,
3575 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003576 Certificate: certificate,
3577 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003578 Updatable: updatableAttribute,
3579 Installable: installableAttribute,
3580 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3581 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3582 Binaries: binariesLabelListAttribute,
3583 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003584 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003585 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003586 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003587 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003588 }
3589
3590 props := bazel.BazelTargetModuleProperties{
3591 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003592 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003593 }
3594
Wei Li1c66fc72022-05-09 23:59:14 -07003595 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003596}
Yu Liu4ae55d12022-01-05 17:17:23 -08003597
3598// The following conversions are based on this table where the rows are the compile_multilib
3599// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3600// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3601// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3602// should not be compiled.
3603// multib/compile_multilib, 32, 64, both, first
3604// 32, 32/32, none/none, 32/32, none/32
3605// 64, none/none, 64/none, 64/none, 64/none
3606// both, 32/32, 64/none, 32&64/32, 64/32
3607// first, 32/32, 64/none, 64/32, 64/32
3608
3609func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3610 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3611 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3612 switch compileMultilb {
3613 case "both", "32":
3614 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3615 case "first":
3616 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3617 case "64":
3618 // Incompatible, ignore
3619 default:
3620 invalidCompileMultilib(ctx, compileMultilb)
3621 }
3622}
3623
3624func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3625 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3626 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3627 switch compileMultilb {
3628 case "both", "64", "first":
3629 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3630 case "32":
3631 // Incompatible, ignore
3632 default:
3633 invalidCompileMultilib(ctx, compileMultilb)
3634 }
3635}
3636
3637func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3638 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3639 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3640 switch compileMultilb {
3641 case "both":
3642 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3643 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3644 case "first":
3645 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3646 case "32":
3647 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3648 case "64":
3649 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3650 default:
3651 invalidCompileMultilib(ctx, compileMultilb)
3652 }
3653}
3654
3655func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3656 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3657 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3658 switch compileMultilb {
3659 case "both", "first":
3660 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3661 case "32":
3662 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3663 case "64":
3664 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3665 default:
3666 invalidCompileMultilib(ctx, compileMultilb)
3667 }
3668}
3669
3670func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3671 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3672 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3673}
3674
3675func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3676 list := bazel.LabelListAttribute{}
3677 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3678 nativeSharedLibs.Native_shared_libs_32.Append(list)
3679}
3680
3681func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3682 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3683 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3684}
3685
3686func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3687 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3688 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3689}
3690
3691func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3692 labelListAttr *bazel.LabelListAttribute) {
3693 list := bazel.LabelListAttribute{}
3694 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3695 labelListAttr.Append(list)
3696}
3697
3698func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3699 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3700}