blob: 3cdcd79850dd347d31604432656530691d6185ad [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()
Dennis Shene2ed70c2023-01-11 14:15:43 +000083 ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
Spandan Das66773252022-01-15 00:23:18 +000084 // Register after apex_info mutator so that it can use ApexVariationName
85 ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
Jiyong Park8e6d52f2020-11-19 14:37:47 +090086}
87
88type apexBundleProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090089 // Json manifest file describing meta info of this APEX bundle. Refer to
90 // system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
Jiyong Park8e6d52f2020-11-19 14:37:47 +090091 Manifest *string `android:"path"`
92
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090093 // AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
94 // a default one is automatically generated.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090095 AndroidManifest *string `android:"path"`
96
Marco Loaizad1209a82023-02-08 10:14:01 +000097 // Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
98 // device (/apex/<apex_name>). If unspecified, follows the name property.
99 Apex_name *string
100
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900101 // Determines the file contexts file for setting the security contexts to files in this APEX
102 // bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
103 // /system/sepolicy/apex/<module_name>_file_contexts.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900104 File_contexts *string `android:"path"`
105
Jiyong Park038e8522021-12-13 23:56:35 +0900106 // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
107 // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
108 // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
109 // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
110 // capability. If this property is not set, or a file is missing in the file, default config
111 // is used.
112 Canned_fs_config *string `android:"path"`
113
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900114 ApexNativeDependencies
115
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900116 Multilib apexMultilibProperties
117
Sundong Ahn80c04892021-11-23 00:57:19 +0000118 // List of sh binaries that are embedded inside this APEX bundle.
119 Sh_binaries []string
120
Paul Duffin3abc1742021-03-15 19:32:23 +0000121 // List of platform_compat_config files that are embedded inside this APEX bundle.
122 Compat_configs []string
123
Jiyong Park12a719c2021-01-07 15:31:24 +0900124 // List of filesystem images that are embedded inside this APEX bundle.
125 Filesystems []string
126
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900127 // Whether this APEX is considered updatable or not. When set to true, this will enforce
128 // additional rules for making sure that the APEX is truly updatable. To be updatable,
129 // min_sdk_version should be set as well. This will also disable the size optimizations like
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000130 // symlinking to the system libs. Default is true.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900131 Updatable *bool
132
Jiyong Parkf4020582021-11-29 12:37:10 +0900133 // Marks that this APEX is designed to be updatable in the future, although it's not
134 // updatable yet. This is used to mimic some of the build behaviors that are applied only to
135 // updatable APEXes. Currently, this disables the size optimization, so that the size of
136 // APEX will not increase when the APEX is actually marked as truly updatable. Default is
137 // false.
138 Future_updatable *bool
139
Jiyong Park1bc84122021-06-22 20:23:05 +0900140 // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
141 // false`. Default is false.
142 Platform_apis *bool
143
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900144 // Whether this APEX is installable to one of the partitions like system, vendor, etc.
145 // Default: true.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900146 Installable *bool
147
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900148 // If set true, VNDK libs are considered as stable libs and are not included in this APEX.
149 // Should be only used in non-system apexes (e.g. vendor: true). Default is false.
150 Use_vndk_as_stable *bool
151
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900152 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
153 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
154 // container. When set to zip, contents are stored in a zip container directly. This type is
155 // mostly for host-side debugging. When set to both, the two types are both built. Default
156 // is 'image'.
157 Payload_type *string
158
Huang Jianan13cac632021-08-02 15:02:17 +0800159 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
160 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900161 Payload_fs_type *string
162
163 // For telling the APEX to ignore special handling for system libraries such as bionic.
164 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900165 Ignore_system_library_special_case *bool
166
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100167 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100168 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100169 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900170
171 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
172 // used in tests.
173 Test_only_unsigned_payload *bool
174
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000175 // Whenever apex should be compressed, regardless of product flag used. Should be only
176 // used in tests.
177 Test_only_force_compression *bool
178
Jooyung Han09c11ad2021-10-27 03:45:31 +0900179 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
180 // with the tool to sign payload contents.
181 Custom_sign_tool *string
182
Dennis Shenaf41bc12022-08-03 16:46:43 +0000183 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
184 // in a special way that include the digest of the lib file under /lib(64)?
185 Dynamic_common_lib_apex *bool
186
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100187 // Canonical name of this APEX bundle. Used to determine the path to the
188 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
189 // apex mutator variations. For override_apex modules, this is the name of the
190 // overridden base module.
191 ApexVariationName string `blueprint:"mutated"`
192
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900193 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900194
195 // List of sanitizer names that this APEX is enabled for
196 SanitizerNames []string `blueprint:"mutated"`
197
198 PreventInstall bool `blueprint:"mutated"`
199
200 HideFromMake bool `blueprint:"mutated"`
201
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900202 // Internal package method for this APEX. When payload_type is image, this can be either
203 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
204 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900205 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900206}
207
208type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900209 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900210 Native_shared_libs []string
211
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900212 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900213 Jni_libs []string
214
Colin Cross70572ed2022-11-02 13:14:20 -0700215 // List of rust dyn libraries that are embedded inside this APEX.
Jiyong Park99644e92020-11-17 22:21:02 +0900216 Rust_dyn_libs []string
217
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900218 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900219 Binaries []string
220
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900221 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900222 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900223
224 // List of filesystem images that are embedded inside this APEX bundle.
225 Filesystems []string
Colin Cross70572ed2022-11-02 13:14:20 -0700226
227 // List of native libraries to exclude from this APEX.
228 Exclude_native_shared_libs []string
229
230 // List of JNI libraries to exclude from this APEX.
231 Exclude_jni_libs []string
232
233 // List of rust dyn libraries to exclude from this APEX.
234 Exclude_rust_dyn_libs []string
235
236 // List of native executables to exclude from this APEX.
237 Exclude_binaries []string
238
239 // List of native tests to exclude from this APEX.
240 Exclude_tests []string
241
242 // List of filesystem images to exclude from this APEX bundle.
243 Exclude_filesystems []string
244}
245
246// Merge combines another ApexNativeDependencies into this one
247func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
248 a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
249 a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
250 a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
251 a.Binaries = append(a.Binaries, b.Binaries...)
252 a.Tests = append(a.Tests, b.Tests...)
253 a.Filesystems = append(a.Filesystems, b.Filesystems...)
254
255 a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
256 a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
257 a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
258 a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
259 a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
260 a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900261}
262
263type apexMultilibProperties struct {
264 // Native dependencies whose compile_multilib is "first"
265 First ApexNativeDependencies
266
267 // Native dependencies whose compile_multilib is "both"
268 Both ApexNativeDependencies
269
270 // Native dependencies whose compile_multilib is "prefer32"
271 Prefer32 ApexNativeDependencies
272
273 // Native dependencies whose compile_multilib is "32"
274 Lib32 ApexNativeDependencies
275
276 // Native dependencies whose compile_multilib is "64"
277 Lib64 ApexNativeDependencies
278}
279
280type apexTargetBundleProperties struct {
281 Target struct {
282 // Multilib properties only for android.
283 Android struct {
284 Multilib apexMultilibProperties
285 }
286
287 // Multilib properties only for host.
288 Host struct {
289 Multilib apexMultilibProperties
290 }
291
292 // Multilib properties only for host linux_bionic.
293 Linux_bionic struct {
294 Multilib apexMultilibProperties
295 }
296
297 // Multilib properties only for host linux_glibc.
298 Linux_glibc struct {
299 Multilib apexMultilibProperties
300 }
301 }
302}
303
Jiyong Park59140302020-12-14 18:44:04 +0900304type apexArchBundleProperties struct {
305 Arch struct {
306 Arm struct {
307 ApexNativeDependencies
308 }
309 Arm64 struct {
310 ApexNativeDependencies
311 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700312 Riscv64 struct {
313 ApexNativeDependencies
314 }
Jiyong Park59140302020-12-14 18:44:04 +0900315 X86 struct {
316 ApexNativeDependencies
317 }
318 X86_64 struct {
319 ApexNativeDependencies
320 }
321 }
322}
323
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900324// These properties can be used in override_apex to override the corresponding properties in the
325// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900326type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900327 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900328 Apps []string
329
Daniel Norman5a3ce132021-08-26 15:44:43 -0700330 // List of prebuilt files that are embedded inside this APEX bundle.
331 Prebuilts []string
332
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900333 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900334 Rros []string
335
markchien7c803b82021-08-26 22:10:06 +0800336 // List of BPF programs inside this APEX bundle.
337 Bpfs []string
338
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900339 // List of bootclasspath fragments that are embedded inside this APEX bundle.
340 Bootclasspath_fragments []string
341
342 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
343 Systemserverclasspath_fragments []string
344
345 // List of java libraries that are embedded inside this APEX bundle.
346 Java_libs []string
347
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900348 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
349 // Soong). This does not completely prevent installation of the overridden binaries, but if
350 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
351 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900352 Overrides []string
353
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900354 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900355 Logging_parent string
356
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900357 // Apex Container package name. Override value for attribute package:name in
358 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900359 Package_name string
360
361 // A txt file containing list of files that are allowed to be included in this APEX.
362 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700363
364 // Name of the apex_key module that provides the private key to sign this APEX bundle.
365 Key *string
366
367 // Specifies the certificate and the private key to sign the zip container of this APEX. If
368 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
369 // as the certificate and the private key, respectively. If this is ":module", then the
370 // certificate and the private key are provided from the android_app_certificate module
371 // named "module".
372 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400373
374 // Whether this APEX can be compressed or not. Setting this property to false means this
375 // APEX will never be compressed. When set to true, APEX will be compressed if other
376 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
377 // Default: false.
378 Compressible *bool
Dennis Shene2ed70c2023-01-11 14:15:43 +0000379
380 // Trim against a specific Dynamic Common Lib APEX
381 Trim_against *string
zhidou133c55b2023-01-31 19:34:10 +0000382
383 // The minimum SDK version that this APEX must support at minimum. This is usually set to
384 // the SDK version that the APEX was first introduced.
385 Min_sdk_version *string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900386}
387
388type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900389 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900390 android.ModuleBase
391 android.DefaultableModuleBase
392 android.OverridableModuleBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400393 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900394 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900395
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900396 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900397 properties apexBundleProperties
398 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900399 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900400 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900401 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900402
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900403 ///////////////////////////////////////////////////////////////////////////////////////////
404 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900405
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900406 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800407 publicKeyFile android.Path
408 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900409
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900410 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800411 containerCertificateFile android.Path
412 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900413
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900414 // Flags for special variants of APEX
415 testApex bool
416 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900417
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900418 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
419 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900420 primaryApexType bool
421
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900422 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900423 suffix string
424
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900425 // File system type of apex_payload.img
426 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900427
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900428 // Whether to create symlink to the system file instead of having a file inside the apex or
429 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900430 linkToSystemLib bool
431
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900432 // List of files to be included in this APEX. This is filled in the first part of
433 // GenerateAndroidBuildActions.
434 filesInfo []apexFile
435
Jingwen Chen29743c82023-01-25 17:49:46 +0000436 // List of other module names that should be installed when this APEX gets installed (LOCAL_REQUIRED_MODULES).
437 makeModulesToInstall []string
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900438
439 ///////////////////////////////////////////////////////////////////////////////////////////
440 // Outputs (final and intermediates)
441
442 // Processed apex manifest in JSONson format (for Q)
443 manifestJsonOut android.WritablePath
444
445 // Processed apex manifest in PB format (for R+)
446 manifestPbOut android.WritablePath
447
448 // Processed file_contexts files
449 fileContexts android.WritablePath
450
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900451 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900452 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900453 outputFile android.WritablePath
454
Jooyung Hana6d36672022-02-24 13:58:07 +0900455 // The built uncompressed .apex file.
456 outputApexFile android.WritablePath
457
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900458 // The built APEX file in app bundle format. This file is not directly installed to the
459 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
460 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
461 // system) to be merged into a single app bundle file that Play accepts. See
462 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
463 bundleModuleFile android.WritablePath
464
Colin Cross6340ea52021-11-04 12:01:18 -0700465 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900466 installDir android.InstallPath
467
Colin Cross6340ea52021-11-04 12:01:18 -0700468 // Path where this APEX was installed.
469 installedFile android.InstallPath
470
471 // Installed locations of symlinks for backward compatibility.
472 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900473
474 // Text file having the list of individual files that are included in this APEX. Used for
475 // debugging purpose.
476 installedFilesFile android.WritablePath
477
478 // List of module names that this APEX is including (to be shown via *-deps-info target).
479 // Used for debugging purpose.
480 android.ApexBundleDepsInfo
481
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900482 // Optional list of lint report zip files for apexes that contain java or app modules
483 lintReports android.Paths
484
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000485 isCompressed bool
486
sophiezc80a2b32020-11-12 16:39:19 +0000487 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700488 nativeApisUsedByModuleFile android.ModuleOutPath
489 nativeApisBackedByModuleFile android.ModuleOutPath
490 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800491
492 // Collect the module directory for IDE info in java/jdeps.go.
493 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900494}
495
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900496// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900497type apexFileClass int
498
Jooyung Han72bd2f82019-10-23 16:46:38 +0900499const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900500 app apexFileClass = iota
501 appSet
502 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900503 goBinary
504 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900505 nativeExecutable
506 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900507 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900508 pyBinary
509 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900510)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900511
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900512// apexFile represents a file in an APEX bundle. This is created during the first half of
513// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
514// of the function, this is used to create commands that copies the files into a staging directory,
515// where they are packaged into the APEX file. This struct is also used for creating Make modules
516// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900517type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900518 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000519 builtFile android.Path
520 installDir string
521 customStem string
522 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900523
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900524 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
525 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
526 // suffix>]
527 androidMkModuleName string // becomes LOCAL_MODULE
528 class apexFileClass // becomes LOCAL_MODULE_CLASS
529 moduleDir string // becomes LOCAL_PATH
530 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
531 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
532 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
533 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900534
535 jacocoReportClassesFile android.Path // only for javalibs and apps
536 lintDepSets java.LintDepSets // only for javalibs and apps
537 certificate java.Certificate // only for apps
538 overriddenPackageName string // only for apps
539
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900540 transitiveDep bool
541 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900542
Jiyong Park57621b22021-01-20 20:33:11 +0900543 multilib string
544
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900545 // TODO(jiyong): remove this
546 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900547}
548
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900549// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900550func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
551 ret := apexFile{
552 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900553 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900554 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900555 class: class,
556 module: module,
557 }
558 if module != nil {
559 ret.moduleDir = ctx.OtherModuleDir(module)
560 ret.requiredModuleNames = module.RequiredModuleNames()
561 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
562 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900563 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900564 }
565 return ret
566}
567
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900568func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900569 return af.builtFile != nil && af.builtFile.String() != ""
570}
571
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900572// apexRelativePath returns the relative path of the given path from the install directory of this
573// apexFile.
574// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900575func (af *apexFile) apexRelativePath(path string) string {
576 return filepath.Join(af.installDir, path)
577}
578
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900579// path returns path of this apex file relative to the APEX root
580func (af *apexFile) path() string {
581 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900582}
583
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900584// stem returns the base filename of this apex file
585func (af *apexFile) stem() string {
586 if af.customStem != "" {
587 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900588 }
589 return af.builtFile.Base()
590}
591
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900592// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
593func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900594 var ret []string
595 for _, symlink := range af.symlinks {
596 ret = append(ret, af.apexRelativePath(symlink))
597 }
598 return ret
599}
600
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900601// availableToPlatform tests whether this apexFile is from a module that can be installed to the
602// platform.
603func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900604 if af.module == nil {
605 return false
606 }
607 if am, ok := af.module.(android.ApexModule); ok {
608 return am.AvailableFor(android.AvailableToPlatform)
609 }
610 return false
611}
612
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900613////////////////////////////////////////////////////////////////////////////////////////////////////
614// Mutators
615//
616// Brief description about mutators for APEX. The following three mutators are the most important
617// ones.
618//
619// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
620// to the (direct) dependencies of this APEX bundle.
621//
Paul Duffin949abc02020-12-08 10:34:30 +0000622// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900623// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
624// modules are marked as being included in the APEX via BuildForApex().
625//
Paul Duffin949abc02020-12-08 10:34:30 +0000626// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
627// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900628
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900629type dependencyTag struct {
630 blueprint.BaseDependencyTag
631 name string
632
633 // Determines if the dependent will be part of the APEX payload. Can be false for the
634 // dependencies to the signing key module, etc.
635 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000636
637 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
638 // replacement. This is needed because some prebuilt modules do not provide all the information
639 // needed by the apex.
640 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000641
642 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
643 // also be added as exported members of that SDK.
644 memberType android.SdkMemberType
645}
646
647func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
648 return d.memberType
649}
650
651func (d *dependencyTag) ExportMember() bool {
652 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900653}
654
Paul Duffin520917a2022-05-13 13:01:59 +0000655func (d *dependencyTag) String() string {
656 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
657}
658
659func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000660 return !d.sourceOnly
661}
662
663var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000664var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000665
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900666var (
Paul Duffin520917a2022-05-13 13:01:59 +0000667 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
668 bpfTag = &dependencyTag{name: "bpf", payload: true}
669 certificateTag = &dependencyTag{name: "certificate"}
Dennis Shene2ed70c2023-01-11 14:15:43 +0000670 dclaTag = &dependencyTag{name: "dcla"}
Paul Duffin520917a2022-05-13 13:01:59 +0000671 executableTag = &dependencyTag{name: "executable", payload: true}
672 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000673 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
674 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000675 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000676 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
677 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
678 keyTag = &dependencyTag{name: "key"}
679 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
680 rroTag = &dependencyTag{name: "rro", payload: true}
681 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
682 testForTag = &dependencyTag{name: "test for"}
683 testTag = &dependencyTag{name: "test", payload: true}
684 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900685)
686
687// TODO(jiyong): shorten this function signature
688func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900689 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900690 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900691 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900692
693 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900694 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900695 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
696 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900697 }
698
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900699 // Use *FarVariation* to be able to depend on modules having conflicting variations with
700 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
701 // 'arm' or 'arm64' for native shared libs.
Colin Cross70572ed2022-11-02 13:14:20 -0700702 ctx.AddFarVariationDependencies(binVariations, executableTag,
703 android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
704 ctx.AddFarVariationDependencies(binVariations, testTag,
705 android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
706 ctx.AddFarVariationDependencies(libVariations, jniLibTag,
707 android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
708 ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
709 android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
710 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
711 android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
712 ctx.AddFarVariationDependencies(target.Variations(), fsTag,
713 android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900714}
715
716func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900717 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900718 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
719 } else {
720 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
721 if ctx.Os().Bionic() {
722 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
723 } else {
724 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
725 }
726 }
727}
728
Jooyung Hand045ebc2022-12-06 15:23:57 +0900729// getImageVariationPair returns a pair for the image variation name as its
730// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
731// suffix indicates the vndk version when it's vendor or product.
732// getImageVariation can simply join the result of this function to get the
733// image variation name.
734func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900735 if a.vndkApex {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900736 return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900737 }
738
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900739 var prefix string
740 var vndkVersion string
741 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000742 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900743 prefix = cc.VendorVariationPrefix
744 vndkVersion = deviceConfig.VndkVersion()
745 } else if a.ProductSpecific() {
746 prefix = cc.ProductVariationPrefix
747 vndkVersion = deviceConfig.ProductVndkVersion()
748 }
749 }
750 if vndkVersion == "current" {
751 vndkVersion = deviceConfig.PlatformVndkVersion()
752 }
753 if vndkVersion != "" {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900754 return prefix, vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900755 }
756
Jooyung Hand045ebc2022-12-06 15:23:57 +0900757 return android.CoreVariation, "" // The usual case
758}
759
760// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
761// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
762func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
763 prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
764 return prefix + vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900765}
766
767func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900768 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
769 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
770 // each target os/architectures, appropriate dependencies are selected by their
771 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900772 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900773 imageVariation := a.getImageVariation(ctx)
774
775 a.combineProperties(ctx)
776
777 has32BitTarget := false
778 for _, target := range targets {
779 if target.Arch.ArchType.Multilib == "lib32" {
780 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000781 }
782 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900783 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900784 // Don't include artifacts for the host cross targets because there is no way for us
785 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900786 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900787 continue
788 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000789
Colin Cross70572ed2022-11-02 13:14:20 -0700790 var deps ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000791
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900792 // Add native modules targeting both ABIs. When multilib.* is omitted for
793 // native_shared_libs/jni_libs/tests, it implies multilib.both
Colin Cross70572ed2022-11-02 13:14:20 -0700794 deps.Merge(a.properties.Multilib.Both)
795 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900796 Native_shared_libs: a.properties.Native_shared_libs,
797 Tests: a.properties.Tests,
798 Jni_libs: a.properties.Jni_libs,
799 Binaries: nil,
800 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900801
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900802 // Add native modules targeting the first ABI When multilib.* is omitted for
803 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900804 isPrimaryAbi := i == 0
805 if isPrimaryAbi {
Colin Cross70572ed2022-11-02 13:14:20 -0700806 deps.Merge(a.properties.Multilib.First)
807 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900808 Native_shared_libs: nil,
809 Tests: nil,
810 Jni_libs: nil,
811 Binaries: a.properties.Binaries,
812 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900813 }
814
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900815 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900816 switch target.Arch.ArchType.Multilib {
817 case "lib32":
Colin Cross70572ed2022-11-02 13:14:20 -0700818 deps.Merge(a.properties.Multilib.Lib32)
819 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900820 case "lib64":
Colin Cross70572ed2022-11-02 13:14:20 -0700821 deps.Merge(a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900822 if !has32BitTarget {
Colin Cross70572ed2022-11-02 13:14:20 -0700823 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900824 }
825 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900826
Jiyong Park59140302020-12-14 18:44:04 +0900827 // Add native modules targeting a specific arch variant
828 switch target.Arch.ArchType {
829 case android.Arm:
Colin Cross70572ed2022-11-02 13:14:20 -0700830 deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900831 case android.Arm64:
Colin Cross70572ed2022-11-02 13:14:20 -0700832 deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700833 case android.Riscv64:
Colin Cross70572ed2022-11-02 13:14:20 -0700834 deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900835 case android.X86:
Colin Cross70572ed2022-11-02 13:14:20 -0700836 deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900837 case android.X86_64:
Colin Cross70572ed2022-11-02 13:14:20 -0700838 deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900839 default:
840 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
841 }
842
Colin Cross70572ed2022-11-02 13:14:20 -0700843 addDependenciesForNativeModules(ctx, deps, target, imageVariation)
Sundong Ahn80c04892021-11-23 00:57:19 +0000844 ctx.AddFarVariationDependencies([]blueprint.Variation{
845 {Mutator: "os", Variation: target.OsVariation()},
846 {Mutator: "arch", Variation: target.ArchVariation()},
847 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900848 }
849
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900850 // Common-arch dependencies come next
851 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900852 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000853 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100854}
855
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900856// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900857func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
858 if a.overridableProperties.Allowed_files != nil {
859 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100860 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900861
862 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
863 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800864 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900865 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900866 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
867 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
868 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700869 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
870 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
871 // regardless of the TARGET_PREFER_* setting. See b/144532908
872 arches := ctx.DeviceConfig().Arches()
873 if len(arches) != 0 {
874 archForPrebuiltEtc := arches[0]
875 for _, arch := range arches {
876 // Prefer 64-bit arch if there is any
877 if arch.ArchType.Multilib == "lib64" {
878 archForPrebuiltEtc = arch
879 break
880 }
881 }
882 ctx.AddFarVariationDependencies([]blueprint.Variation{
883 {Mutator: "os", Variation: ctx.Os().String()},
884 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
885 }, prebuiltTag, prebuilts...)
886 }
887 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700888
889 // Dependencies for signing
890 if String(a.overridableProperties.Key) == "" {
891 ctx.PropertyErrorf("key", "missing")
892 return
893 }
894 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
895
896 cert := android.SrcIsModule(a.getCertString(ctx))
897 if cert != "" {
898 ctx.AddDependency(ctx.Module(), certificateTag, cert)
899 // empty cert is not an error. Cert and private keys will be directly found under
900 // PRODUCT_DEFAULT_DEV_CERTIFICATE
901 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100902}
903
Dennis Shene2ed70c2023-01-11 14:15:43 +0000904func apexDCLADepsMutator(mctx android.BottomUpMutatorContext) {
905 if !mctx.Config().ApexTrimEnabled() {
906 return
907 }
908 if a, ok := mctx.Module().(*apexBundle); ok && a.overridableProperties.Trim_against != nil {
909 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
910 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(a.overridableProperties.Trim_against))
911 } else if o, ok := mctx.Module().(*OverrideApex); ok {
912 for _, p := range o.GetProperties() {
913 properties, ok := p.(*overridableProperties)
914 if !ok {
915 continue
916 }
917 if properties.Trim_against != nil {
918 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
919 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(properties.Trim_against))
920 }
921 }
922 }
923}
924
925type DCLAInfo struct {
926 ProvidedLibs []string
927}
928
929var DCLAInfoProvider = blueprint.NewMutatorProvider(DCLAInfo{}, "apex_info")
930
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900931type ApexBundleInfo struct {
932 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100933}
934
Paul Duffin949abc02020-12-08 10:34:30 +0000935var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900936
Paul Duffina7d6a892020-12-07 17:39:59 +0000937var _ ApexInfoMutator = (*apexBundle)(nil)
938
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100939func (a *apexBundle) ApexVariationName() string {
940 return a.properties.ApexVariationName
941}
942
Paul Duffina7d6a892020-12-07 17:39:59 +0000943// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900944// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
945// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
946// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
947// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000948//
949// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
950// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
951// The apexMutator uses that list to create module variants for the apexes to which it belongs.
952// The relationship between module variants and apexes is not one-to-one as variants will be
953// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000954func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900955
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900956 // The VNDK APEX is special. For the APEX, the membership is described in a very different
957 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
958 // libraries are self-identified by their vndk.enabled properties. There is no need to run
959 // this mutator for the APEX as nothing will be collected. So, let's return fast.
960 if a.vndkApex {
961 return
962 }
963
964 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
965 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
966 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
967 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
968 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900969 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
970 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900971 if proptools.Bool(a.properties.Use_vndk_as_stable) {
972 if !useVndk {
973 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
974 }
975 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
976 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
977 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
978 }
979 })
980 if mctx.Failed() {
981 return
982 }
Jooyung Handf78e212020-07-22 15:54:47 +0900983 }
984
Colin Cross56a83212020-09-15 18:30:11 -0700985 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900986 am, ok := child.(android.ApexModule)
987 if !ok || !am.CanHaveApexVariants() {
988 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900989 }
Paul Duffin573989d2021-03-17 13:25:29 +0000990 depTag := mctx.OtherModuleDependencyTag(child)
991
992 // Check to see if the tag always requires that the child module has an apex variant for every
993 // apex variant of the parent module. If it does not then it is still possible for something
994 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
995 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
996 return true
997 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +0000998 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900999 return false
1000 }
Jooyung Handf78e212020-07-22 15:54:47 +09001001 if excludeVndkLibs {
1002 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
1003 return false
1004 }
1005 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001006 // By default, all the transitive dependencies are collected, unless filtered out
1007 // above.
Colin Cross56a83212020-09-15 18:30:11 -07001008 return true
1009 }
1010
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001011 // Records whether a certain module is included in this apexBundle via direct dependency or
1012 // inndirect dependency.
1013 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -07001014 mctx.WalkDeps(func(child, parent android.Module) bool {
1015 if !continueApexDepsWalk(child, parent) {
1016 return false
1017 }
Jooyung Han698dd9f2020-07-22 15:17:19 +09001018 // If the parent is apexBundle, this child is directly depended.
1019 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001020 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -07001021 contents[depName] = contents[depName].Add(directDep)
1022 return true
1023 })
1024
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001025 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +09001026 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -07001027 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
1028 Contents: apexContents,
1029 })
1030
Jooyung Haned124c32021-01-26 11:43:46 +09001031 minSdkVersion := a.minSdkVersion(mctx)
1032 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
1033 if minSdkVersion.IsNone() {
1034 minSdkVersion = android.FutureApiLevel
1035 }
1036
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001037 // This is the main part of this mutator. Mark the collected dependencies that they need to
1038 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +09001039
Marco Loaizad1209a82023-02-08 10:14:01 +00001040 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001041 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -07001042 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001043 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +09001044 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -07001045 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +09001046 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001047 InApexVariants: []string{apexVariationName},
1048 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -07001049 ApexContents: []*android.ApexContents{apexContents},
1050 }
Colin Cross56a83212020-09-15 18:30:11 -07001051 mctx.WalkDeps(func(child, parent android.Module) bool {
1052 if !continueApexDepsWalk(child, parent) {
1053 return false
1054 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001055 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +09001056 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +09001057 })
Dennis Shene2ed70c2023-01-11 14:15:43 +00001058
1059 if a.dynamic_common_lib_apex() {
1060 mctx.SetProvider(DCLAInfoProvider, DCLAInfo{
1061 ProvidedLibs: a.properties.Native_shared_libs,
1062 })
1063 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001064}
1065
Paul Duffina7d6a892020-12-07 17:39:59 +00001066type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001067 // ApexVariationName returns the name of the APEX variation to use in the apex
1068 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
1069 ApexVariationName() string
1070
Paul Duffina7d6a892020-12-07 17:39:59 +00001071 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1072 // depended upon by an apex and which require an apex specific variant.
1073 ApexInfoMutator(android.TopDownMutatorContext)
1074}
1075
1076// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1077// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001078// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001079func apexInfoMutator(mctx android.TopDownMutatorContext) {
1080 if !mctx.Module().Enabled() {
1081 return
1082 }
1083
1084 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1085 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001086 }
Spandan Das42e89502022-05-06 22:12:55 +00001087 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001088}
1089
Spandan Das66773252022-01-15 00:23:18 +00001090// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1091// This check is enforced for updatable modules
1092func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1093 if !mctx.Module().Enabled() {
1094 return
1095 }
Spandan Das08c911f2022-01-21 22:07:26 +00001096 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001097 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001098 // b/208656169 Do not propagate strict updatability linting to libcore/
1099 // These libs are available on the classpath during compilation
1100 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1101 // Only skip libraries defined in libcore root, not subdirectories
1102 if mctx.OtherModuleDir(child) == "libcore" {
1103 // Do not traverse transitive deps of libcore/ libs
1104 return false
1105 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001106 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1107 return false
1108 }
Spandan Das66773252022-01-15 00:23:18 +00001109 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1110 lintable.SetStrictUpdatabilityLinting(true)
1111 }
1112 // visit transitive deps
1113 return true
1114 })
1115 }
1116}
1117
Spandan Das42e89502022-05-06 22:12:55 +00001118// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1119func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1120 if !mctx.Module().Enabled() {
1121 return
1122 }
1123 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1124 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1125 mctx.VisitDirectDeps(func(module android.Module) {
1126 // ignore android_test_app
1127 if app, ok := module.(*java.AndroidApp); ok {
1128 app.SetUpdatable(true)
1129 }
1130 })
1131 }
1132}
1133
Spandan Das08c911f2022-01-21 22:07:26 +00001134// TODO: b/215736885 Whittle the denylist
1135// Transitive deps of certain mainline modules baseline NewApi errors
1136// Skip these mainline modules for now
1137var (
1138 skipStrictUpdatabilityLintAllowlist = []string{
1139 "com.android.art",
1140 "com.android.art.debug",
1141 "com.android.conscrypt",
1142 "com.android.media",
1143 // test apexes
1144 "test_com.android.art",
1145 "test_com.android.conscrypt",
1146 "test_com.android.media",
1147 "test_jitzygote_com.android.art",
1148 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001149
1150 // TODO: b/215736885 Remove this list
1151 skipLintJavalibAllowlist = []string{
1152 "conscrypt.module.platform.api.stubs",
1153 "conscrypt.module.public.api.stubs",
1154 "conscrypt.module.public.api.stubs.system",
1155 "conscrypt.module.public.api.stubs.module_lib",
1156 "framework-media.stubs",
1157 "framework-media.stubs.system",
1158 "framework-media.stubs.module_lib",
1159 }
Spandan Das08c911f2022-01-21 22:07:26 +00001160)
1161
1162func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1163 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1164}
1165
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001166// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1167// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1168// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001169func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1170 if !mctx.Module().Enabled() {
1171 return
1172 }
1173 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001174 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1175 }
1176}
1177
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001178// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1179// the apex in order to retrieve its contents later.
1180// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001181func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1182 if !mctx.Module().Enabled() {
1183 return
1184 }
Colin Cross56a83212020-09-15 18:30:11 -07001185 if am, ok := mctx.Module().(android.ApexModule); ok {
1186 if testFor := am.TestFor(); len(testFor) > 0 {
1187 mctx.AddFarVariationDependencies([]blueprint.Variation{
1188 {Mutator: "os", Variation: am.Target().OsVariation()},
1189 {"arch", "common"},
1190 }, testForTag, testFor...)
1191 }
1192 }
1193}
1194
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001195// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001196func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1197 if !mctx.Module().Enabled() {
1198 return
1199 }
Colin Cross56a83212020-09-15 18:30:11 -07001200 if _, ok := mctx.Module().(android.ApexModule); ok {
1201 var contents []*android.ApexContents
1202 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1203 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1204 contents = append(contents, abInfo.Contents)
1205 }
1206 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1207 ApexContents: contents,
1208 })
Colin Crossaede88c2020-08-11 12:17:01 -07001209 }
1210}
1211
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001212// markPlatformAvailability marks whether or not a module can be available to platform. A module
1213// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1214// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1215// be) available to platform
1216// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001217func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1218 // Host and recovery are not considered as platform
1219 if mctx.Host() || mctx.Module().InstallInRecovery() {
1220 return
1221 }
1222
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001223 am, ok := mctx.Module().(android.ApexModule)
1224 if !ok {
1225 return
1226 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001227
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001228 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001229
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001230 // If any of the dep is not available to platform, this module is also considered as being
1231 // not available to platform even if it has "//apex_available:platform"
1232 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001233 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001234 // if the dependency crosses apex boundary, don't consider it
1235 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001236 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001237 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1238 availableToPlatform = false
1239 // TODO(b/154889534) trigger an error when 'am' has
1240 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001241 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001242 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001243
Paul Duffinb5769c12021-05-12 16:16:51 +01001244 // Exception 1: check to see if the module always requires it.
1245 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001246 availableToPlatform = true
1247 }
1248
1249 // Exception 2: bootstrap bionic libraries are also always available to platform
1250 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1251 availableToPlatform = true
1252 }
1253
1254 if !availableToPlatform {
1255 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001256 }
1257}
1258
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001259// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001260// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001261func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001262 if !mctx.Module().Enabled() {
1263 return
1264 }
Colin Cross56a83212020-09-15 18:30:11 -07001265
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001266 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001267 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001268 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001269 return
1270 }
1271
1272 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001273 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1274 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001275 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001276 if strings.HasPrefix(apexBundleName, "com.android.art") {
1277 // Create an alias from the platform variant. This is done to make
1278 // test_for dependencies work for modules that are split by the APEX
1279 // mutator, since test_for dependencies always go to the platform variant.
1280 // This doesn't happen for normal APEXes that are disjunct, so only do
1281 // this for the overlapping ART APEXes.
1282 // TODO(b/183882457): Remove this if the test_for functionality is
1283 // refactored to depend on the proper APEX variants instead of platform.
1284 mctx.CreateAliasVariation("", apexBundleName)
1285 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001286 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1287 apexBundleName := o.GetOverriddenModuleName()
1288 if apexBundleName == "" {
1289 mctx.ModuleErrorf("base property is not set")
1290 return
1291 }
1292 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001293 if strings.HasPrefix(apexBundleName, "com.android.art") {
1294 // TODO(b/183882457): See note for CreateAliasVariation above.
1295 mctx.CreateAliasVariation("", apexBundleName)
1296 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001297 }
1298}
Sundong Ahne9b55722019-09-06 17:37:42 +09001299
Paul Duffin6717d882021-06-15 19:09:41 +01001300// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1301// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001302func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001303 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001304 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001305 return !a.vndkApex
1306 }
1307
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001308 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001309}
1310
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001311// See android.UpdateDirectlyInAnyApex
1312// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001313func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1314 if !mctx.Module().Enabled() {
1315 return
1316 }
1317 if am, ok := mctx.Module().(android.ApexModule); ok {
1318 android.UpdateDirectlyInAnyApex(mctx, am)
1319 }
1320}
1321
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001322// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001323type apexPackaging int
1324
1325const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001326 // imageApex is a packaging method where contents are included in a filesystem image which
1327 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001328 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001329
1330 // zipApex is a packaging method where contents are directly included in the zip container.
1331 // This is used for host-side testing - because the contents are easily accessible by
1332 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001333 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001334
1335 // flattendApex is a packaging method where contents are not included in the APEX file, but
1336 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1337 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001338 flattenedApex
1339)
1340
1341const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001342 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001343 imageApexSuffix = ".apex"
1344 imageCapexSuffix = ".capex"
1345 zipApexSuffix = ".zipapex"
1346 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001347
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001348 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001349 imageApexType = "image"
1350 zipApexType = "zip"
1351 flattenedApexType = "flattened"
1352
Dan Willemsen47e1a752021-10-16 18:36:13 -07001353 ext4FsType = "ext4"
1354 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001355 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001356)
1357
1358// The suffix for the output "file", not the module
1359func (a apexPackaging) suffix() string {
1360 switch a {
1361 case imageApex:
1362 return imageApexSuffix
1363 case zipApex:
1364 return zipApexSuffix
1365 default:
1366 panic(fmt.Errorf("unknown APEX type %d", a))
1367 }
1368}
1369
1370func (a apexPackaging) name() string {
1371 switch a {
1372 case imageApex:
1373 return imageApexType
1374 case zipApex:
1375 return zipApexType
1376 default:
1377 panic(fmt.Errorf("unknown APEX type %d", a))
1378 }
1379}
1380
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001381// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1382// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001383func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001384 if !mctx.Module().Enabled() {
1385 return
1386 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001387 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001388 var variants []string
1389 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1390 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001391 // This is the normal case. Note that both image and flattend APEXes are
1392 // created. The image type is installed to the system partition, while the
1393 // flattened APEX is (optionally) installed to the system_ext partition.
1394 // This is mostly for GSI which has to support wide range of devices. If GSI
1395 // is installed on a newer (APEX-capable) device, the image APEX in the
1396 // system will be used. However, if the same GSI is installed on an old
1397 // device which can't support image APEX, the flattened APEX in the
1398 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001399 variants = append(variants, imageApexType, flattenedApexType)
1400 case "zip":
1401 variants = append(variants, zipApexType)
1402 case "both":
1403 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1404 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001405 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001406 return
1407 }
1408
1409 modules := mctx.CreateLocalVariations(variants...)
1410
1411 for i, v := range variants {
1412 switch v {
1413 case imageApexType:
1414 modules[i].(*apexBundle).properties.ApexType = imageApex
1415 case zipApexType:
1416 modules[i].(*apexBundle).properties.ApexType = zipApex
1417 case flattenedApexType:
1418 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001419 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001420 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001421 modules[i].(*apexBundle).MakeAsSystemExt()
1422 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001423 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001424 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001425 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001426 // payload_type is forcibly overridden to "image"
1427 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001428 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001429 }
1430}
1431
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001432var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001433
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001434// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001435func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001436 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001437 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001438 return true
1439}
1440
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001441var _ android.OutputFileProducer = (*apexBundle)(nil)
1442
1443// Implements android.OutputFileProducer
1444func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1445 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001446 case "", android.DefaultDistTag:
1447 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001448 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001449 case imageApexSuffix:
1450 // uncompressed one
1451 if a.outputApexFile != nil {
1452 return android.Paths{a.outputApexFile}, nil
1453 }
1454 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001455 default:
1456 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1457 }
1458}
1459
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001460var _ multitree.Exportable = (*apexBundle)(nil)
1461
1462func (a *apexBundle) Exportable() bool {
1463 if a.properties.ApexType == flattenedApex {
1464 return false
1465 }
1466 return true
1467}
1468
1469func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1470 ret := make(map[string]android.Paths)
1471 ret["apex"] = android.Paths{a.outputFile}
1472 return ret
1473}
1474
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001475var _ cc.Coverage = (*apexBundle)(nil)
1476
1477// Implements cc.Coverage
1478func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1479 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1480}
1481
1482// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001483func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001484 a.properties.PreventInstall = true
1485}
1486
1487// Implements cc.Coverage
1488func (a *apexBundle) HideFromMake() {
1489 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001490 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1491 // TODO(ccross): untangle these
1492 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001493}
1494
1495// Implements cc.Coverage
1496func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1497 a.properties.IsCoverageVariant = coverage
1498}
1499
1500// Implements cc.Coverage
1501func (a *apexBundle) EnableCoverageIfNeeded() {}
1502
1503var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1504
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001505// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001506func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001507 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001508}
1509
Jiyong Parkf4020582021-11-29 12:37:10 +09001510func (a *apexBundle) FutureUpdatable() bool {
1511 return proptools.BoolDefault(a.properties.Future_updatable, false)
1512}
1513
Jiyong Park1bc84122021-06-22 20:23:05 +09001514func (a *apexBundle) UsePlatformApis() bool {
1515 return proptools.BoolDefault(a.properties.Platform_apis, false)
1516}
1517
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001518// getCertString returns the name of the cert that should be used to sign this APEX. This is
1519// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001520func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001521 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001522 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1523 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1524 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001525 if a.vndkApex {
1526 moduleName = vndkApexName
1527 }
1528 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001529 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001530 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001531 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001532 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001533}
1534
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001535// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001536func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001537 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001538}
1539
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001540// See the generate_hashtree property
1541func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001542 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001543}
1544
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001545// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001546func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1547 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1548}
1549
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001550// See the test_only_force_compression property
1551func (a *apexBundle) testOnlyShouldForceCompression() bool {
1552 return proptools.Bool(a.properties.Test_only_force_compression)
1553}
1554
Dennis Shenaf41bc12022-08-03 16:46:43 +00001555// See the dynamic_common_lib_apex property
1556func (a *apexBundle) dynamic_common_lib_apex() bool {
1557 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1558}
1559
Dennis Shene2ed70c2023-01-11 14:15:43 +00001560// See the list of libs to trim
1561func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string {
1562 dclaModules := ctx.GetDirectDepsWithTag(dclaTag)
1563 if len(dclaModules) > 1 {
1564 panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules)))
1565 }
1566 if len(dclaModules) > 0 {
1567 DCLAInfo := ctx.OtherModuleProvider(dclaModules[0], DCLAInfoProvider).(DCLAInfo)
1568 return DCLAInfo.ProvidedLibs
1569 }
1570 return []string{}
1571}
1572
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001573// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1574// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1575// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001576
Jiyong Parkf97782b2019-02-13 20:28:58 +09001577func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1578 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1579 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1580 }
1581}
1582
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001583func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001584 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1585 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001586 }
1587
1588 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001589 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001590 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001591 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001592 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001593 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001594 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001595 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001596 }
1597 }
1598 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001599}
1600
Jooyung Han8ce8db92020-05-15 19:05:05 +09001601func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001602 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1603 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001604 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001605 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001606 for _, target := range ctx.MultiTargets() {
1607 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001608 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001609 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001610 Tests: nil,
1611 Jni_libs: nil,
1612 Binaries: nil,
1613 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001614 break
1615 }
1616 }
1617 }
1618}
1619
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001620// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1621// returned apexFile saves information about the Soong module that will be used for creating the
1622// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001623func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001624 // Decide the APEX-local directory by the multilib of the library In the future, we may
1625 // query this to the module.
1626 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001627 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001628 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001629 case "lib32":
1630 dirInApex = "lib"
1631 case "lib64":
1632 dirInApex = "lib64"
1633 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001634 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001635 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001636 }
Jooyung Han35155c42020-02-06 17:33:20 +09001637 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001638 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001639 // Special case for Bionic libs and other libs installed with them. This is to
1640 // prevent those libs from being included in the search path
1641 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1642 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1643 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1644 // will be loaded into the default linker namespace (aka "platform" namespace). If
1645 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1646 // be loaded again into the runtime linker namespace, which will result in double
1647 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001648 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001649 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001650
Colin Cross1d487152022-10-03 19:14:46 -07001651 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001652 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1653 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001654}
1655
Jiyong Park1833cef2019-12-13 13:28:36 +09001656func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001657 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001658 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001659 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001660 }
Jooyung Han35155c42020-02-06 17:33:20 +09001661 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001662 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001663 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1664 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001665 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001666 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001667 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001668}
1669
Jiyong Park99644e92020-11-17 22:21:02 +09001670func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1671 dirInApex := "bin"
1672 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1673 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1674 }
Colin Cross1d487152022-10-03 19:14:46 -07001675 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001676 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1677 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1678 return af
1679}
1680
1681func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1682 // Decide the APEX-local directory by the multilib of the library
1683 // In the future, we may query this to the module.
1684 var dirInApex string
1685 switch rustm.Arch().ArchType.Multilib {
1686 case "lib32":
1687 dirInApex = "lib"
1688 case "lib64":
1689 dirInApex = "lib64"
1690 }
1691 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1692 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1693 }
Colin Cross1d487152022-10-03 19:14:46 -07001694 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001695 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1696 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1697}
1698
Cole Faust4d247e62023-01-23 10:14:58 -08001699func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.PythonBinaryModule) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001700 dirInApex := "bin"
1701 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001702 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001703}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001704
Jiyong Park1833cef2019-12-13 13:28:36 +09001705func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001706 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001707 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001708 // NB: Since go binaries are static we don't need the module for anything here, which is
1709 // good since the go tool is a blueprint.Module not an android.Module like we would
1710 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001711 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001712}
1713
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001714func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001715 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001716 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1717 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1718 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001719 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001720 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001721 af.symlinks = sh.Symlinks()
1722 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001723}
1724
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001725func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001726 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001727 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001728 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001729}
1730
atrost6e126252020-01-27 17:01:16 +00001731func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1732 dirInApex := filepath.Join("etc", config.SubDir())
1733 fileToCopy := config.CompatConfig()
1734 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1735}
1736
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001737// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1738// way.
1739type javaModule interface {
1740 android.Module
1741 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001742 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001743 JacocoReportClassesFile() android.Path
1744 LintDepSets() java.LintDepSets
1745 Stem() string
1746}
1747
1748var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001749var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001750var _ javaModule = (*java.SdkLibrary)(nil)
1751var _ javaModule = (*java.DexImport)(nil)
1752var _ javaModule = (*java.SdkLibraryImport)(nil)
1753
Paul Duffin190fdef2021-04-26 10:33:59 +01001754// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001755func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001756 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001757}
1758
1759// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1760func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001761 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001762 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001763 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1764 af.lintDepSets = module.LintDepSets()
1765 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001766 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1767 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1768 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1769 }
1770 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001771 return af
1772}
1773
1774// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1775// the same way.
1776type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001777 android.Module
1778 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001779 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001780 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001781 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001782 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001783 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001784 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001785}
1786
1787var _ androidApp = (*java.AndroidApp)(nil)
1788var _ androidApp = (*java.AndroidAppImport)(nil)
1789
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001790func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1791 buildId := ctx.Config().BuildId()
1792
1793 // The build ID is used as a suffix for a filename, so ensure that
1794 // the set of characters being used are sanitized.
1795 // - any word character: [a-zA-Z0-9_]
1796 // - dots: .
1797 // - dashes: -
1798 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1799 if !validRegex.MatchString(buildId) {
1800 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1801 }
1802 return buildId
1803}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001804
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001805func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001806 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001807 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001808 appDir = "priv-app"
1809 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001810
1811 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1812 // so that PackageManager correctly invalidates the existing installed apk
1813 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001814 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001815 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001816
Yo Chiange8128052020-07-23 20:09:18 +08001817 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001818 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001819 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001820 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001821
1822 if app, ok := aapp.(interface {
1823 OverriddenManifestPackageName() string
1824 }); ok {
1825 af.overriddenPackageName = app.OverriddenManifestPackageName()
1826 }
Jiyong Park618922e2020-01-08 13:35:43 +09001827 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001828}
1829
Jiyong Park69aeba92020-04-24 21:16:36 +09001830func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1831 rroDir := "overlay"
1832 dirInApex := filepath.Join(rroDir, rro.Theme())
1833 fileToCopy := rro.OutputFile()
1834 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1835 af.certificate = rro.Certificate()
1836
1837 if a, ok := rro.(interface {
1838 OverriddenManifestPackageName() string
1839 }); ok {
1840 af.overriddenPackageName = a.OverriddenManifestPackageName()
1841 }
1842 return af
1843}
1844
Ken Chenfad7f9d2021-11-10 22:02:57 +08001845func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1846 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001847 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1848}
1849
Jiyong Park12a719c2021-01-07 15:31:24 +09001850func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1851 dirInApex := filepath.Join("etc", "fs")
1852 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1853}
1854
Paul Duffin064b70c2020-11-02 17:32:38 +00001855// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001856// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1857// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1858// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001859func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001860 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001861 am, ok := child.(android.ApexModule)
1862 if !ok || !am.CanHaveApexVariants() {
1863 return false
1864 }
1865
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001866 // Filter-out unwanted depedendencies
1867 depTag := ctx.OtherModuleDependencyTag(child)
1868 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1869 return false
1870 }
Paul Duffin520917a2022-05-13 13:01:59 +00001871 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001872 return false
1873 }
1874
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001875 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001876 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001877
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001878 // Visit actually
1879 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001880 })
1881}
1882
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001883// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1884type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001885
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001886const (
1887 ext4 fsType = iota
1888 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001889 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001890)
Artur Satayev849f8442020-04-28 14:57:42 +01001891
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001892func (f fsType) string() string {
1893 switch f {
1894 case ext4:
1895 return ext4FsType
1896 case f2fs:
1897 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001898 case erofs:
1899 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001900 default:
1901 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001902 }
1903}
1904
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001905var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1906
1907func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1908 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1909}
1910
1911func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1912 bazelCtx := ctx.Config().BazelContext
1913 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1914}
1915
Jingwen Chen889f2f22022-12-16 08:16:01 +00001916// GetBazelLabel returns the bazel label of this apexBundle, or the label of the
1917// override_apex module overriding this apexBundle. An apexBundle can be
1918// overridden by different override_apex modules (e.g. Google or Go variants),
1919// which is handled by the overrides mutators.
1920func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string {
1921 if _, ok := ctx.Module().(android.OverridableModule); ok {
1922 return android.MaybeBp2buildLabelOfOverridingModule(ctx)
1923 }
1924 return a.BazelModuleBase.GetBazelLabel(ctx, a)
1925}
1926
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001927func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1928 if !a.commonBuildActions(ctx) {
1929 return
1930 }
1931
1932 a.setApexTypeAndSuffix(ctx)
1933 a.setPayloadFsType(ctx)
1934 a.setSystemLibLink(ctx)
1935
1936 if a.properties.ApexType != zipApex {
1937 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1938 }
1939
1940 bazelCtx := ctx.Config().BazelContext
1941 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1942 if err != nil {
1943 ctx.ModuleErrorf(err.Error())
1944 return
1945 }
1946 a.installDir = android.PathForModuleInstall(ctx, "apex")
Jingwen Chen94098e82023-01-10 14:50:42 +00001947
1948 // Set the output file to .apex or .capex depending on the compression configuration.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001949 a.setCompression(ctx)
Jingwen Chen94098e82023-01-10 14:50:42 +00001950 if a.isCompressed {
1951 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedCompressedOutput)
1952 } else {
1953 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1954 }
1955 a.outputFile = a.outputApexFile
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001956
Liz Kammer0e255ef2022-11-04 16:07:04 -04001957 // TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
1958 // interface if these were set in a provider rather than the module itself
Wei Li32dcdf92022-10-26 22:30:48 -07001959 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1960 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1961 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1962 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Liz Kammer0e255ef2022-11-04 16:07:04 -04001963
Jingwen Chen29743c82023-01-25 17:49:46 +00001964 // Ensure ApexMkInfo.install_to_system make module names are installed as
1965 // part of a bundled build.
1966 a.makeModulesToInstall = append(a.makeModulesToInstall, outputs.MakeModulesToInstall...)
Vinh Tranb6803a52022-12-14 11:34:54 -05001967
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001968 apexType := a.properties.ApexType
1969 switch apexType {
1970 case imageApex:
Liz Kammer303978d2022-11-04 16:12:43 -04001971 a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001972 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
Wei Licc73a052022-11-07 14:25:34 -08001973 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001974 // TODO(b/239084755): Generate the java api using.xml file from Bazel.
Jingwen Chen1ec77852022-11-07 14:36:12 +00001975 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
Wei Li78c07de2022-11-08 16:01:05 -08001976 a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001977 installSuffix := imageApexSuffix
1978 if a.isCompressed {
1979 installSuffix = imageCapexSuffix
1980 }
1981 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1982 a.compatSymlinks.Paths()...)
1983 default:
1984 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1985 }
1986
1987 /*
1988 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1989 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
1990 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
1991 To find out what Soong build puts there, run:
1992 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
1993 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1994 return a.depVisitor(&vctx, ctx, child, parent)
1995 })
1996 vctx.normalizeFileInfo()
1997 */
1998
1999}
2000
2001func (a *apexBundle) setCompression(ctx android.ModuleContext) {
2002 if a.properties.ApexType != imageApex {
2003 a.isCompressed = false
2004 } else if a.testOnlyShouldForceCompression() {
2005 a.isCompressed = true
2006 } else {
2007 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
2008 }
2009}
2010
2011func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
2012 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
2013 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
2014 // the same library in the system partition, thus effectively sharing the same libraries
2015 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
2016 // in the APEX.
2017 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
2018
2019 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
2020 // So we can't link them to /system/lib libs which are core variants.
2021 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2022 a.linkToSystemLib = false
2023 }
2024
2025 forced := ctx.Config().ForceApexSymlinkOptimization()
2026 updatable := a.Updatable() || a.FutureUpdatable()
2027
2028 // We don't need the optimization for updatable APEXes, as it might give false signal
2029 // to the system health when the APEXes are still bundled (b/149805758).
2030 if !forced && updatable && a.properties.ApexType == imageApex {
2031 a.linkToSystemLib = false
2032 }
2033
2034 // We also don't want the optimization for host APEXes, because it doesn't make sense.
2035 if ctx.Host() {
2036 a.linkToSystemLib = false
2037 }
2038}
2039
2040func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
2041 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
2042 case ext4FsType:
2043 a.payloadFsType = ext4
2044 case f2fsFsType:
2045 a.payloadFsType = f2fs
2046 case erofsFsType:
2047 a.payloadFsType = erofs
2048 default:
2049 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
2050 }
2051}
2052
2053func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
2054 // Set suffix and primaryApexType depending on the ApexType
2055 buildFlattenedAsDefault := ctx.Config().FlattenApex()
2056 switch a.properties.ApexType {
2057 case imageApex:
2058 if buildFlattenedAsDefault {
2059 a.suffix = imageApexSuffix
2060 } else {
2061 a.suffix = ""
2062 a.primaryApexType = true
2063
2064 if ctx.Config().InstallExtraFlattenedApexes() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002065 a.makeModulesToInstall = append(a.makeModulesToInstall, a.Name()+flattenedSuffix)
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002066 }
2067 }
2068 case zipApex:
2069 if proptools.String(a.properties.Payload_type) == "zip" {
2070 a.suffix = ""
2071 a.primaryApexType = true
2072 } else {
2073 a.suffix = zipApexSuffix
2074 }
2075 case flattenedApex:
2076 if buildFlattenedAsDefault {
2077 a.suffix = ""
2078 a.primaryApexType = true
2079 } else {
2080 a.suffix = flattenedSuffix
2081 }
2082 }
2083}
2084
2085func (a apexBundle) isCompressable() bool {
2086 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
2087}
2088
2089func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
2090 a.checkApexAvailability(ctx)
2091 a.checkUpdatable(ctx)
2092 a.CheckMinSdkVersion(ctx)
2093 a.checkStaticLinkingToStubLibraries(ctx)
2094 a.checkStaticExecutables(ctx)
2095 if len(a.properties.Tests) > 0 && !a.testApex {
2096 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
2097 return false
2098 }
2099 return true
2100}
2101
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002102type visitorContext struct {
2103 // all the files that will be included in this APEX
2104 filesInfo []apexFile
2105
2106 // native lib dependencies
2107 provideNativeLibs []string
2108 requireNativeLibs []string
2109
2110 handleSpecialLibs bool
Jooyung Han862c0d62022-12-21 10:15:37 +09002111
2112 // if true, raise error on duplicate apexFile
2113 checkDuplicate bool
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002114}
2115
Jooyung Han862c0d62022-12-21 10:15:37 +09002116func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002117 encountered := make(map[string]apexFile)
2118 for _, f := range vctx.filesInfo {
2119 dest := filepath.Join(f.installDir, f.builtFile.Base())
2120 if e, ok := encountered[dest]; !ok {
2121 encountered[dest] = f
2122 } else {
Jooyung Han862c0d62022-12-21 10:15:37 +09002123 if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
2124 mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
2125 dest, e.builtFile, f.builtFile)
2126 return
2127 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002128 // If a module is directly included and also transitively depended on
2129 // consider it as directly included.
2130 e.transitiveDep = e.transitiveDep && f.transitiveDep
2131 encountered[dest] = e
2132 }
2133 }
2134 vctx.filesInfo = vctx.filesInfo[:0]
2135 for _, v := range encountered {
2136 vctx.filesInfo = append(vctx.filesInfo, v)
2137 }
2138 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2139 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2140 // changes.
2141 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2142 })
2143}
2144
2145func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2146 depTag := ctx.OtherModuleDependencyTag(child)
2147 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2148 return false
2149 }
2150 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2151 return false
2152 }
2153 depName := ctx.OtherModuleName(child)
2154 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2155 switch depTag {
2156 case sharedLibTag, jniLibTag:
2157 isJniLib := depTag == jniLibTag
2158 switch ch := child.(type) {
2159 case *cc.Module:
2160 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2161 fi.isJniLib = isJniLib
2162 vctx.filesInfo = append(vctx.filesInfo, fi)
2163 // Collect the list of stub-providing libs except:
2164 // - VNDK libs are only for vendors
2165 // - bootstrap bionic libs are treated as provided by system
2166 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2167 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2168 }
2169 return true // track transitive dependencies
2170 case *rust.Module:
2171 fi := apexFileForRustLibrary(ctx, ch)
2172 fi.isJniLib = isJniLib
2173 vctx.filesInfo = append(vctx.filesInfo, fi)
2174 return true // track transitive dependencies
2175 default:
2176 propertyName := "native_shared_libs"
2177 if isJniLib {
2178 propertyName = "jni_libs"
2179 }
2180 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2181 }
2182 case executableTag:
2183 switch ch := child.(type) {
2184 case *cc.Module:
2185 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2186 return true // track transitive dependencies
Cole Faust4d247e62023-01-23 10:14:58 -08002187 case *python.PythonBinaryModule:
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002188 if ch.HostToolPath().Valid() {
2189 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2190 }
2191 case bootstrap.GoBinaryTool:
2192 if a.Host() {
2193 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2194 }
2195 case *rust.Module:
2196 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2197 return true // track transitive dependencies
2198 default:
2199 ctx.PropertyErrorf("binaries",
2200 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2201 }
2202 case shBinaryTag:
2203 if csh, ok := child.(*sh.ShBinary); ok {
2204 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2205 } else {
2206 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2207 }
2208 case bcpfTag:
2209 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2210 if !ok {
2211 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2212 return false
2213 }
2214
2215 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2216 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002217 a.makeModulesToInstall = append(a.makeModulesToInstall, makeModuleName)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002218 }
2219 return true
2220 case sscpfTag:
2221 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2222 ctx.PropertyErrorf("systemserverclasspath_fragments",
2223 "%q is not a systemserverclasspath_fragment module", depName)
2224 return false
2225 }
2226 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2227 vctx.filesInfo = append(vctx.filesInfo, *af)
2228 }
2229 return true
2230 case javaLibTag:
2231 switch child.(type) {
2232 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2233 af := apexFileForJavaModule(ctx, child.(javaModule))
2234 if !af.ok() {
2235 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2236 return false
2237 }
2238 vctx.filesInfo = append(vctx.filesInfo, af)
2239 return true // track transitive dependencies
2240 default:
2241 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2242 }
2243 case androidAppTag:
2244 switch ap := child.(type) {
2245 case *java.AndroidApp:
2246 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2247 return true // track transitive dependencies
2248 case *java.AndroidAppImport:
2249 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2250 case *java.AndroidTestHelperApp:
2251 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2252 case *java.AndroidAppSet:
2253 appDir := "app"
2254 if ap.Privileged() {
2255 appDir = "priv-app"
2256 }
2257 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2258 // suffixed so that PackageManager correctly invalidates the
2259 // existing installed apk in favour of the new APK-in-APEX.
2260 // See bugs for more information.
2261 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2262 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2263 af.certificate = java.PresignedCertificate
2264 vctx.filesInfo = append(vctx.filesInfo, af)
2265 default:
2266 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2267 }
2268 case rroTag:
2269 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2270 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2271 } else {
2272 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2273 }
2274 case bpfTag:
2275 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2276 filesToCopy, _ := bpfProgram.OutputFiles("")
2277 apex_sub_dir := bpfProgram.SubDir()
2278 for _, bpfFile := range filesToCopy {
2279 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2280 }
2281 } else {
2282 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2283 }
2284 case fsTag:
2285 if fs, ok := child.(filesystem.Filesystem); ok {
2286 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2287 } else {
2288 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2289 }
2290 case prebuiltTag:
2291 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2292 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2293 } else {
2294 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2295 }
2296 case compatConfigTag:
2297 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2298 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2299 } else {
2300 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2301 }
2302 case testTag:
2303 if ccTest, ok := child.(*cc.Module); ok {
2304 if ccTest.IsTestPerSrcAllTestsVariation() {
2305 // Multiple-output test module (where `test_per_src: true`).
2306 //
2307 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2308 // We do not add this variation to `filesInfo`, as it has no output;
2309 // however, we do add the other variations of this module as indirect
2310 // dependencies (see below).
2311 } else {
2312 // Single-output test module (where `test_per_src: false`).
2313 af := apexFileForExecutable(ctx, ccTest)
2314 af.class = nativeTest
2315 vctx.filesInfo = append(vctx.filesInfo, af)
2316 }
2317 return true // track transitive dependencies
2318 } else {
2319 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2320 }
2321 case keyTag:
2322 if key, ok := child.(*apexKey); ok {
2323 a.privateKeyFile = key.privateKeyFile
2324 a.publicKeyFile = key.publicKeyFile
2325 } else {
2326 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2327 }
2328 case certificateTag:
2329 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2330 a.containerCertificateFile = dep.Certificate.Pem
2331 a.containerPrivateKeyFile = dep.Certificate.Key
2332 } else {
2333 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2334 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002335 }
2336 return false
2337 }
2338
2339 if a.vndkApex {
2340 return false
2341 }
2342
2343 // indirect dependencies
2344 am, ok := child.(android.ApexModule)
2345 if !ok {
2346 return false
2347 }
2348 // We cannot use a switch statement on `depTag` here as the checked
2349 // tags used below are private (e.g. `cc.sharedDepTag`).
2350 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2351 if ch, ok := child.(*cc.Module); ok {
2352 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2353 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2354 return false
2355 }
2356 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2357 af.transitiveDep = true
2358
2359 // Always track transitive dependencies for host.
2360 if a.Host() {
2361 vctx.filesInfo = append(vctx.filesInfo, af)
2362 return true
2363 }
2364
2365 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2366 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2367 // If the dependency is a stubs lib, don't include it in this APEX,
2368 // but make sure that the lib is installed on the device.
2369 // In case no APEX is having the lib, the lib is installed to the system
2370 // partition.
2371 //
2372 // Always include if we are a host-apex however since those won't have any
2373 // system libraries.
Colin Crossdf2043e2023-01-26 15:39:15 -08002374 //
2375 // Skip the dependency in unbundled builds where the device image is not
2376 // being built.
2377 if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() && !ctx.Config().UnbundledBuild() {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002378 // we need a module name for Make
2379 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
Jingwen Chen29743c82023-01-25 17:49:46 +00002380 if !android.InList(name, a.makeModulesToInstall) {
2381 a.makeModulesToInstall = append(a.makeModulesToInstall, name)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002382 }
2383 }
2384 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2385 // Don't track further
2386 return false
2387 }
2388
2389 // If the dep is not considered to be in the same
2390 // apex, don't add it to filesInfo so that it is not
2391 // included in this APEX.
2392 // TODO(jiyong): move this to at the top of the
2393 // else-if clause for the indirect dependencies.
2394 // Currently, that's impossible because we would
2395 // like to record requiredNativeLibs even when
2396 // DepIsInSameAPex is false. We also shouldn't do
2397 // this for host.
2398 //
2399 // TODO(jiyong): explain why the same module is passed in twice.
2400 // Switching the first am to parent breaks lots of tests.
2401 if !android.IsDepInSameApex(ctx, am, am) {
2402 return false
2403 }
2404
2405 vctx.filesInfo = append(vctx.filesInfo, af)
2406 return true // track transitive dependencies
2407 } else if rm, ok := child.(*rust.Module); ok {
2408 af := apexFileForRustLibrary(ctx, rm)
2409 af.transitiveDep = true
2410 vctx.filesInfo = append(vctx.filesInfo, af)
2411 return true // track transitive dependencies
2412 }
2413 } else if cc.IsTestPerSrcDepTag(depTag) {
2414 if ch, ok := child.(*cc.Module); ok {
2415 af := apexFileForExecutable(ctx, ch)
2416 // Handle modules created as `test_per_src` variations of a single test module:
2417 // use the name of the generated test binary (`fileToCopy`) instead of the name
2418 // of the original test module (`depName`, shared by all `test_per_src`
2419 // variations of that module).
2420 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2421 // these are not considered transitive dep
2422 af.transitiveDep = false
2423 vctx.filesInfo = append(vctx.filesInfo, af)
2424 return true // track transitive dependencies
2425 }
2426 } else if cc.IsHeaderDepTag(depTag) {
2427 // nothing
2428 } else if java.IsJniDepTag(depTag) {
2429 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2430 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2431 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2432 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2433 }
2434 } else if rust.IsDylibDepTag(depTag) {
2435 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2436 af := apexFileForRustLibrary(ctx, rustm)
2437 af.transitiveDep = true
2438 vctx.filesInfo = append(vctx.filesInfo, af)
2439 return true // track transitive dependencies
2440 }
2441 } else if rust.IsRlibDepTag(depTag) {
2442 // Rlib is statically linked, but it might have shared lib
2443 // dependencies. Track them.
2444 return true
2445 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2446 // Add the contents of the bootclasspath fragment to the apex.
2447 switch child.(type) {
2448 case *java.Library, *java.SdkLibrary:
2449 javaModule := child.(javaModule)
2450 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2451 if !af.ok() {
2452 ctx.PropertyErrorf("bootclasspath_fragments",
2453 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2454 return false
2455 }
2456 vctx.filesInfo = append(vctx.filesInfo, af)
2457 return true // track transitive dependencies
2458 default:
2459 ctx.PropertyErrorf("bootclasspath_fragments",
2460 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2461 }
2462 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2463 // Add the contents of the systemserverclasspath fragment to the apex.
2464 switch child.(type) {
2465 case *java.Library, *java.SdkLibrary:
2466 af := apexFileForJavaModule(ctx, child.(javaModule))
2467 vctx.filesInfo = append(vctx.filesInfo, af)
2468 return true // track transitive dependencies
2469 default:
2470 ctx.PropertyErrorf("systemserverclasspath_fragments",
2471 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2472 }
2473 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2474 // nothing
2475 } else if depTag == android.DarwinUniversalVariantTag {
2476 // nothing
2477 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2478 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2479 }
2480 return false
2481}
2482
Jooyung Han862c0d62022-12-21 10:15:37 +09002483func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
2484 // TODO(b/263308293) remove this
2485 if a.properties.IsCoverageVariant {
2486 return false
2487 }
2488 // TODO(b/263308515) remove this
2489 if a.testApex {
2490 return false
2491 }
2492 // TODO(b/263309864) remove this
2493 if a.Host() {
2494 return false
2495 }
2496 if a.Device() && ctx.DeviceConfig().DeviceArch() == "" {
2497 return false
2498 }
2499 return true
2500}
2501
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002502// Creates build rules for an APEX. It consists of the following major steps:
2503//
2504// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2505// 2) traverse the dependency tree to collect apexFile structs from them.
2506// 3) some fields in apexBundle struct are configured
2507// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002508func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002509 ////////////////////////////////////////////////////////////////////////////////////////////
2510 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002511 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002512 return
2513 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002514 ////////////////////////////////////////////////////////////////////////////////////////////
2515 // 2) traverse the dependency tree to collect apexFile structs from them.
braleeb0c1f0c2021-06-07 22:49:13 +08002516 // Collect the module directory for IDE info in java/jdeps.go.
2517 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2518
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002519 // TODO(jiyong): do this using WalkPayloadDeps
2520 // TODO(jiyong): make this clean!!!
Jooyung Han862c0d62022-12-21 10:15:37 +09002521 vctx := visitorContext{
2522 handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case),
2523 checkDuplicate: a.shouldCheckDuplicate(ctx),
2524 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002525 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
Jooyung Han862c0d62022-12-21 10:15:37 +09002526 vctx.normalizeFileInfo(ctx)
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002527 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002528 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002529 return
2530 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002531
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002532 ////////////////////////////////////////////////////////////////////////////////////////////
2533 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002534 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002535 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002536
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002537 a.setApexTypeAndSuffix(ctx)
2538 a.setPayloadFsType(ctx)
2539 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002540 if a.properties.ApexType != zipApex {
2541 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2542 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002543
2544 ////////////////////////////////////////////////////////////////////////////////////////////
2545 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002546 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002547 if a.properties.ApexType == flattenedApex {
2548 a.buildFlattenedApex(ctx)
2549 } else {
2550 a.buildUnflattenedApex(ctx)
2551 }
Jiyong Park956305c2020-01-09 12:32:06 +09002552 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002553 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002554
2555 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2556 if a.installable() {
2557 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2558 // along with other ordinary files. (Note that this is done by apexer for
2559 // non-flattened APEXes)
2560 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2561
2562 // Place the public key as apex_pubkey. This is also done by apexer for
2563 // non-flattened APEXes case.
2564 // TODO(jiyong): Why do we need this CP rule?
2565 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2566 ctx.Build(pctx, android.BuildParams{
2567 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002568 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002569 Output: copiedPubkey,
2570 })
2571 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2572 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002573}
2574
Paul Duffincc33ec82021-04-25 23:14:55 +01002575// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2576// the bootclasspath_fragment contributes to the apex.
2577func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2578 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2579 var filesToAdd []apexFile
2580
2581 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002582 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2583 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2584 dirInApex := filepath.Join("javalib", arch.String())
2585 for _, f := range files {
2586 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2587 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2588 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2589 filesToAdd = append(filesToAdd, af)
2590 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002591 }
2592 }
2593
satayev3db35472021-05-06 23:59:58 +01002594 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002595 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2596 filesToAdd = append(filesToAdd, *af)
2597 }
satayev3db35472021-05-06 23:59:58 +01002598
Ulya Trafimovichf5c548d2022-11-16 14:52:41 +00002599 pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2600 if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002601 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2602 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2603
2604 if pathOnHost != nil {
2605 // We need to copy the profile to a temporary path with the right filename because the apexer
2606 // will take the filename as is.
2607 ctx.Build(pctx, android.BuildParams{
2608 Rule: android.Cp,
2609 Input: pathOnHost,
2610 Output: tempPath,
2611 })
2612 } else {
2613 // At this point, the boot image profile cannot be generated. It is probably because the boot
2614 // image profile source file does not exist on the branch, or it is not available for the
2615 // current build target.
2616 // However, we cannot enforce the boot image profile to be generated because some build
2617 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2618 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2619 // only if the APEX is being built.
2620 ctx.Build(pctx, android.BuildParams{
2621 Rule: android.ErrorRule,
2622 Output: tempPath,
2623 Args: map[string]string{
2624 "error": "Boot image profile cannot be generated",
2625 },
2626 })
2627 }
2628
2629 androidMkModuleName := filepath.Base(pathInApex)
2630 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2631 filesToAdd = append(filesToAdd, af)
2632 }
2633
Paul Duffincc33ec82021-04-25 23:14:55 +01002634 return filesToAdd
2635}
2636
satayevb98371c2021-06-15 16:49:50 +01002637// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2638// the module contributes to the apex; or nil if the proto config was not generated.
2639func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2640 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2641 if !info.ClasspathFragmentProtoGenerated {
2642 return nil
2643 }
2644 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2645 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2646 return &af
satayev14e49132021-05-17 21:03:07 +01002647}
2648
Paul Duffincc33ec82021-04-25 23:14:55 +01002649// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2650// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002651func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2652 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2653
2654 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2655 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002656 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2657 if err != nil {
2658 ctx.ModuleErrorf("%s", err)
2659 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002660
2661 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2662 // bootclasspath_fragment.
2663 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2664 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002665}
2666
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002667///////////////////////////////////////////////////////////////////////////////////////////////////
2668// Factory functions
2669//
2670
2671func newApexBundle() *apexBundle {
2672 module := &apexBundle{}
2673
2674 module.AddProperties(&module.properties)
2675 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002676 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002677 module.AddProperties(&module.overridableProperties)
2678
2679 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2680 android.InitDefaultableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002681 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002682 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002683 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002684 return module
2685}
2686
Paul Duffineb8051d2021-10-18 17:49:39 +01002687func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002688 bundle := newApexBundle()
2689 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002690 return bundle
2691}
2692
2693// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2694// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002695func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002696 bundle := newApexBundle()
2697 bundle.testApex = true
2698 return bundle
2699}
2700
2701// apex packages other modules into an APEX file which is a packaging format for system-level
2702// components like binaries, shared libraries, etc.
2703func BundleFactory() android.Module {
2704 return newApexBundle()
2705}
2706
2707type Defaults struct {
2708 android.ModuleBase
2709 android.DefaultsModuleBase
2710}
2711
2712// apex_defaults provides defaultable properties to other apex modules.
2713func defaultsFactory() android.Module {
2714 return DefaultsFactory()
2715}
2716
2717func DefaultsFactory(props ...interface{}) android.Module {
2718 module := &Defaults{}
2719
2720 module.AddProperties(props...)
2721 module.AddProperties(
2722 &apexBundleProperties{},
2723 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002724 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002725 &overridableProperties{},
2726 )
2727
2728 android.InitDefaultsModule(module)
2729 return module
2730}
2731
2732type OverrideApex struct {
2733 android.ModuleBase
2734 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002735 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002736}
2737
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002738func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002739 // All the overrides happen in the base module.
2740}
2741
2742// override_apex is used to create an apex module based on another apex module by overriding some of
2743// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002744func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002745 m := &OverrideApex{}
2746
2747 m.AddProperties(&overridableProperties{})
2748
2749 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2750 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002751 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002752 return m
2753}
2754
Wei Li1c66fc72022-05-09 23:59:14 -07002755func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2756 if ctx.ModuleType() != "override_apex" {
2757 return
2758 }
2759
2760 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2761 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2762 if !baseApexExists {
2763 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2764 }
2765
2766 a, baseModuleIsApex := baseModule.(*apexBundle)
2767 if !baseModuleIsApex {
2768 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2769 }
2770 attrs, props := convertWithBp2build(a, ctx)
2771
Jingwen Chenc4c34e12022-11-29 12:07:45 +00002772 // We just want the name, not module reference.
2773 baseApexName := strings.TrimPrefix(baseApexModuleName, ":")
2774 attrs.Base_apex_name = &baseApexName
2775
Wei Li1c66fc72022-05-09 23:59:14 -07002776 for _, p := range o.GetProperties() {
2777 overridableProperties, ok := p.(*overridableProperties)
2778 if !ok {
2779 continue
2780 }
Wei Li40f98732022-05-20 22:08:11 -07002781
2782 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2783 // After it is converted in convertWithBp2build(baseApex, ctx),
2784 // the attrs.Manifest.Value.Label is the file path relative to the directory
2785 // of base apex. So the following code converts it to a label that looks like
2786 // <package of base apex>:<path of manifest file> if base apex and override
2787 // apex are not in the same package.
2788 baseApexPackage := ctx.OtherModuleDir(a)
2789 overrideApexPackage := ctx.ModuleDir()
2790 if baseApexPackage != overrideApexPackage {
2791 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2792 }
2793
Wei Li1c66fc72022-05-09 23:59:14 -07002794 // Key
2795 if overridableProperties.Key != nil {
2796 attrs.Key = bazel.LabelAttribute{}
2797 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2798 }
2799
2800 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002801 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002802 // If overridableProperties.Certificate is nil, clear this out as
2803 // well with zeroed structs, so the override_apex does not use the
2804 // base apex's certificate.
2805 attrs.Certificate = bazel.LabelAttribute{}
2806 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002807 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002808 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002809 }
2810
2811 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002812 if overridableProperties.Prebuilts != nil {
2813 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2814 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2815 }
Wei Li1c66fc72022-05-09 23:59:14 -07002816
2817 // Compressible
2818 if overridableProperties.Compressible != nil {
2819 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2820 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002821
2822 // Package name
2823 //
2824 // e.g. com.android.adbd's package name is com.android.adbd, but
2825 // com.google.android.adbd overrides the package name to com.google.android.adbd
2826 //
2827 // TODO: this can be overridden from the product configuration, see
2828 // getOverrideManifestPackageName and
2829 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2830 //
2831 // Instead of generating the BUILD files differently based on the product config
2832 // at the point of conversion, this should be handled by the BUILD file loading
2833 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2834 if overridableProperties.Package_name != "" {
2835 attrs.Package_name = &overridableProperties.Package_name
2836 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002837
2838 // Logging parent
2839 if overridableProperties.Logging_parent != "" {
2840 attrs.Logging_parent = &overridableProperties.Logging_parent
2841 }
Wei Li1c66fc72022-05-09 23:59:14 -07002842 }
2843
2844 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2845}
2846
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002847///////////////////////////////////////////////////////////////////////////////////////////////////
2848// Vality check routines
2849//
2850// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2851// certain conditions are not met.
2852//
2853// TODO(jiyong): move these checks to a separate go file.
2854
satayevad991492021-12-03 18:58:32 +00002855var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2856
Spandan Dasa5f39a12022-08-05 02:35:52 +00002857// 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 +09002858// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002859func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002860 if a.testApex || a.vndkApex {
2861 return
2862 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002863 // apexBundle::minSdkVersion reports its own errors.
2864 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002865 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002866}
2867
Albert Martineefabcf2022-03-21 20:11:16 +00002868// Returns apex's min_sdk_version string value, honoring overrides
2869func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2870 // Only override the minSdkVersion value on Apexes which already specify
2871 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2872 // min_sdk_version value is lower than the one to override with.
zhidou133c55b2023-01-31 19:34:10 +00002873 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.overridableProperties.Min_sdk_version))
Colin Cross56534df2022-10-04 09:58:58 -07002874 if minApiLevel.IsNone() {
2875 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002876 }
2877
Colin Cross56534df2022-10-04 09:58:58 -07002878 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2879 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2880 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2881 minApiLevel = overrideApiLevel
2882 }
2883
2884 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002885}
2886
2887// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002888func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2889 return android.SdkSpec{
2890 Kind: android.SdkNone,
2891 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002892 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002893 }
2894}
2895
Albert Martineefabcf2022-03-21 20:11:16 +00002896// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002897func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002898 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2899}
2900
2901// Construct ApiLevel object from min_sdk_version string value
2902func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2903 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002904 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002905 }
Albert Martineefabcf2022-03-21 20:11:16 +00002906 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002907 if err != nil {
2908 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2909 return android.NoneApiLevel
2910 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002911 return apiLevel
2912}
2913
2914// Ensures that a lib providing stub isn't statically linked
2915func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2916 // Practically, we only care about regular APEXes on the device.
2917 if ctx.Host() || a.testApex || a.vndkApex {
2918 return
2919 }
2920
2921 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2922
2923 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2924 if ccm, ok := to.(*cc.Module); ok {
2925 apexName := ctx.ModuleName()
2926 fromName := ctx.OtherModuleName(from)
2927 toName := ctx.OtherModuleName(to)
2928
2929 // If `to` is not actually in the same APEX as `from` then it does not need
2930 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002931 //
2932 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002933 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2934 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2935 return false
2936 }
2937
2938 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2939 // exception to this rule. It can't make the static dependencies dynamic
2940 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002941 // Same rule should be applied to linkerconfig, because it should be executed
2942 // only with static linked libraries before linker is available with ld.config.txt
2943 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002944 return false
2945 }
2946
2947 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2948 if isStubLibraryFromOtherApex && !externalDep {
2949 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2950 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2951 }
2952
2953 }
2954 return true
2955 })
2956}
2957
satayevb98371c2021-06-15 16:49:50 +01002958// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002959func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2960 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002961 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002962 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2963 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002964 if a.UsePlatformApis() {
2965 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2966 }
Daniel Norman69109112021-12-02 12:52:42 -08002967 if a.SocSpecific() || a.DeviceSpecific() {
2968 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2969 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002970 if a.FutureUpdatable() {
2971 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2972 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002973 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002974 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002975 }
2976}
2977
satayevb98371c2021-06-15 16:49:50 +01002978// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2979func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2980 ctx.VisitDirectDeps(func(module android.Module) {
2981 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2982 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2983 if !info.ClasspathFragmentProtoGenerated {
2984 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2985 }
2986 }
2987 })
2988}
2989
2990// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01002991func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002992 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2993 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01002994 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2995 tag := ctx.OtherModuleDependencyTag(module)
2996 switch tag {
2997 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09002998 if m, ok := module.(interface {
2999 CheckStableSdkVersion(ctx android.BaseModuleContext) error
3000 }); ok {
3001 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01003002 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
3003 }
3004 }
3005 }
3006 })
3007}
3008
satayevb98371c2021-06-15 16:49:50 +01003009// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003010func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
3011 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
3012 if ctx.Host() || a.testApex || a.vndkApex {
3013 return
3014 }
3015
3016 // Because APEXes targeting other than system/system_ext partitions can't set
3017 // apex_available, we skip checks for these APEXes
3018 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
3019 return
3020 }
3021
3022 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
3023 // Requiring them and their transitive depencies with apex_available is not right
3024 // because they just add noise.
3025 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
3026 return
3027 }
3028
3029 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
3030 // As soon as the dependency graph crosses the APEX boundary, don't go further.
3031 if externalDep {
3032 return false
3033 }
3034
3035 apexName := ctx.ModuleName()
3036 fromName := ctx.OtherModuleName(from)
3037 toName := ctx.OtherModuleName(to)
3038
3039 // If `to` is not actually in the same APEX as `from` then it does not need
3040 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00003041 //
3042 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003043 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
3044 // As soon as the dependency graph crosses the APEX boundary, don't go
3045 // further.
3046 return false
3047 }
3048
3049 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
3050 return true
3051 }
Jiyong Park767dbd92021-03-04 13:03:10 +09003052 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
3053 "\n\nDependency path:%s\n\n"+
3054 "Consider adding %q to 'apex_available' property of %q",
3055 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003056 // Visit this module's dependencies to check and report any issues with their availability.
3057 return true
3058 })
3059}
3060
Jiyong Park192600a2021-08-03 07:52:17 +00003061// checkStaticExecutable ensures that executables in an APEX are not static.
3062func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09003063 // No need to run this for host APEXes
3064 if ctx.Host() {
3065 return
3066 }
3067
Jiyong Park192600a2021-08-03 07:52:17 +00003068 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3069 if ctx.OtherModuleDependencyTag(module) != executableTag {
3070 return
3071 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09003072
3073 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00003074 apex := a.ApexVariationName()
3075 exec := ctx.OtherModuleName(module)
3076 if isStaticExecutableAllowed(apex, exec) {
3077 return
3078 }
3079 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
3080 }
3081 })
3082}
3083
3084// A small list of exceptions where static executables are allowed in APEXes.
3085func isStaticExecutableAllowed(apex string, exec string) bool {
3086 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003087 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00003088 "linker",
3089 "linkerconfig",
3090 },
3091 }
3092 execNames, ok := m[apex]
3093 return ok && android.InList(exec, execNames)
3094}
3095
braleeb0c1f0c2021-06-07 22:49:13 +08003096// Collect information for opening IDE project files in java/jdeps.go.
3097func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09003098 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
3099 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
3100 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08003101 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
3102}
3103
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003104var (
3105 apexAvailBaseline = makeApexAvailableBaseline()
3106 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
3107)
3108
Colin Cross440e0d02020-06-11 11:32:11 -07003109func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003110 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003111 moduleName = normalizeModuleName(moduleName)
3112
Colin Cross440e0d02020-06-11 11:32:11 -07003113 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003114 return true
3115 }
3116
3117 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07003118 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003119 return true
3120 }
3121
3122 return false
3123}
3124
3125func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09003126 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
3127 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00003128 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09003129 if strings.HasPrefix(moduleName, "libclang_rt.") {
3130 // This module has many arch variants that depend on the product being built.
3131 // We don't want to list them all
3132 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003133 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003134 if strings.HasPrefix(moduleName, "androidx.") {
3135 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3136 moduleName = "androidx"
3137 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003138 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003139}
3140
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003141// Transform the map of apex -> modules to module -> apexes.
3142func invertApexBaseline(m map[string][]string) map[string][]string {
3143 r := make(map[string][]string)
3144 for apex, modules := range m {
3145 for _, module := range modules {
3146 r[module] = append(r[module], apex)
3147 }
3148 }
3149 return r
3150}
3151
3152// Retrieve the baseline of apexes to which the supplied module belongs.
3153func BaselineApexAvailable(moduleName string) []string {
3154 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3155}
3156
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003157// This is a map from apex to modules, which overrides the apex_available setting for that
3158// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003159// TODO(b/147364041): remove this
3160func makeApexAvailableBaseline() map[string][]string {
3161 // The "Module separator"s below are employed to minimize merge conflicts.
3162 m := make(map[string][]string)
3163 //
3164 // Module separator
3165 //
3166 m["com.android.appsearch"] = []string{
3167 "icing-java-proto-lite",
3168 "libprotobuf-java-lite",
3169 }
3170 //
3171 // Module separator
3172 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003173 m["com.android.btservices"] = []string{
William Escande89bca3f2022-06-28 18:03:30 -07003174 // empty
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003175 }
3176 //
3177 // Module separator
3178 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003179 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3180 //
3181 // Module separator
3182 //
3183 m["com.android.extservices"] = []string{
3184 "error_prone_annotations",
3185 "ExtServices-core",
3186 "ExtServices",
3187 "libtextclassifier-java",
3188 "libz_current",
3189 "textclassifier-statsd",
3190 "TextClassifierNotificationLibNoManifest",
3191 "TextClassifierServiceLibNoManifest",
3192 }
3193 //
3194 // Module separator
3195 //
3196 m["com.android.neuralnetworks"] = []string{
3197 "android.hardware.neuralnetworks@1.0",
3198 "android.hardware.neuralnetworks@1.1",
3199 "android.hardware.neuralnetworks@1.2",
3200 "android.hardware.neuralnetworks@1.3",
3201 "android.hidl.allocator@1.0",
3202 "android.hidl.memory.token@1.0",
3203 "android.hidl.memory@1.0",
3204 "android.hidl.safe_union@1.0",
3205 "libarect",
3206 "libbuildversion",
3207 "libmath",
3208 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003209 }
3210 //
3211 // Module separator
3212 //
3213 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003214 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003215 }
3216 //
3217 // Module separator
3218 //
3219 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003220 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003221 }
3222 //
3223 // Module separator
3224 //
3225 m["com.android.mediaprovider"] = []string{
3226 "MediaProvider",
3227 "MediaProviderGoogle",
3228 "fmtlib_ndk",
3229 "libbase_ndk",
3230 "libfuse",
3231 "libfuse_jni",
3232 }
3233 //
3234 // Module separator
3235 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003236 m["com.android.runtime"] = []string{
3237 "bionic_libc_platform_headers",
3238 "libarm-optimized-routines-math",
3239 "libc_aeabi",
3240 "libc_bionic",
3241 "libc_bionic_ndk",
3242 "libc_bootstrap",
3243 "libc_common",
3244 "libc_common_shared",
3245 "libc_common_static",
3246 "libc_dns",
3247 "libc_dynamic_dispatch",
3248 "libc_fortify",
3249 "libc_freebsd",
3250 "libc_freebsd_large_stack",
3251 "libc_gdtoa",
3252 "libc_init_dynamic",
3253 "libc_init_static",
3254 "libc_jemalloc_wrapper",
3255 "libc_netbsd",
3256 "libc_nomalloc",
3257 "libc_nopthread",
3258 "libc_openbsd",
3259 "libc_openbsd_large_stack",
3260 "libc_openbsd_ndk",
3261 "libc_pthread",
3262 "libc_static_dispatch",
3263 "libc_syscalls",
3264 "libc_tzcode",
3265 "libc_unwind_static",
3266 "libdebuggerd",
3267 "libdebuggerd_common_headers",
3268 "libdebuggerd_handler_core",
3269 "libdebuggerd_handler_fallback",
3270 "libdl_static",
3271 "libjemalloc5",
3272 "liblinker_main",
3273 "liblinker_malloc",
3274 "liblz4",
3275 "liblzma",
3276 "libprocinfo",
3277 "libpropertyinfoparser",
3278 "libscudo",
3279 "libstdc++",
3280 "libsystemproperties",
3281 "libtombstoned_client_static",
3282 "libunwindstack",
3283 "libz",
3284 "libziparchive",
3285 }
3286 //
3287 // Module separator
3288 //
3289 m["com.android.tethering"] = []string{
3290 "android.hardware.tetheroffload.config-V1.0-java",
3291 "android.hardware.tetheroffload.control-V1.0-java",
3292 "android.hidl.base-V1.0-java",
3293 "libcgrouprc",
3294 "libcgrouprc_format",
3295 "libtetherutilsjni",
3296 "libvndksupport",
3297 "net-utils-framework-common",
3298 "netd_aidl_interface-V3-java",
3299 "netlink-client",
3300 "networkstack-aidl-interfaces-java",
3301 "tethering-aidl-interfaces-java",
3302 "TetheringApiCurrentLib",
3303 }
3304 //
3305 // Module separator
3306 //
3307 m["com.android.wifi"] = []string{
3308 "PlatformProperties",
3309 "android.hardware.wifi-V1.0-java",
3310 "android.hardware.wifi-V1.0-java-constants",
3311 "android.hardware.wifi-V1.1-java",
3312 "android.hardware.wifi-V1.2-java",
3313 "android.hardware.wifi-V1.3-java",
3314 "android.hardware.wifi-V1.4-java",
3315 "android.hardware.wifi.hostapd-V1.0-java",
3316 "android.hardware.wifi.hostapd-V1.1-java",
3317 "android.hardware.wifi.hostapd-V1.2-java",
3318 "android.hardware.wifi.supplicant-V1.0-java",
3319 "android.hardware.wifi.supplicant-V1.1-java",
3320 "android.hardware.wifi.supplicant-V1.2-java",
3321 "android.hardware.wifi.supplicant-V1.3-java",
3322 "android.hidl.base-V1.0-java",
3323 "android.hidl.manager-V1.0-java",
3324 "android.hidl.manager-V1.1-java",
3325 "android.hidl.manager-V1.2-java",
3326 "bouncycastle-unbundled",
3327 "dnsresolver_aidl_interface-V2-java",
3328 "error_prone_annotations",
3329 "framework-wifi-pre-jarjar",
3330 "framework-wifi-util-lib",
3331 "ipmemorystore-aidl-interfaces-V3-java",
3332 "ipmemorystore-aidl-interfaces-java",
3333 "ksoap2",
3334 "libnanohttpd",
3335 "libwifi-jni",
3336 "net-utils-services-common",
3337 "netd_aidl_interface-V2-java",
3338 "netd_aidl_interface-unstable-java",
3339 "netd_event_listener_interface-java",
3340 "netlink-client",
3341 "networkstack-client",
3342 "services.net",
3343 "wifi-lite-protos",
3344 "wifi-nano-protos",
3345 "wifi-service-pre-jarjar",
3346 "wifi-service-resources",
3347 }
3348 //
3349 // Module separator
3350 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003351 m["com.android.os.statsd"] = []string{
3352 "libstatssocket",
3353 }
3354 //
3355 // Module separator
3356 //
3357 m[android.AvailableToAnyApex] = []string{
3358 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3359 "androidx",
3360 "androidx-constraintlayout_constraintlayout",
3361 "androidx-constraintlayout_constraintlayout-nodeps",
3362 "androidx-constraintlayout_constraintlayout-solver",
3363 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3364 "com.google.android.material_material",
3365 "com.google.android.material_material-nodeps",
3366
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003367 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003368 "libprofile-clang-extras",
3369 "libprofile-clang-extras_ndk",
3370 "libprofile-extras",
3371 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003372 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003373 }
3374 return m
3375}
3376
3377func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003378 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3379 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003380}
3381
Spandan Dasf14e2542021-11-12 00:01:37 +00003382func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3383 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3384 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003385 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003386 With("name", jar).
3387 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3388 Because(jar +
3389 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003390 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003391 " 1. If the offending code is from a statically linked library, consider " +
3392 "removing that dependency and using an alternative already in the " +
3393 "bootclasspath, or perhaps a shared library." +
3394 " 2. Move the offending code into an allowed package.\n" +
3395 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3396 "health implications of bundling that code, particularly if the offending jar " +
3397 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003398
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003399 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003400 }
3401 return rules
3402}
3403
Anton Hanssone1b18362021-12-23 15:05:38 +00003404// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003405// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003406func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003407 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003408 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003409 "android.net.ssl",
3410 "com.android.org.conscrypt",
3411 },
Wei Li40f98732022-05-20 22:08:11 -07003412 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003413 "android.media",
3414 },
3415 }
3416}
3417
Anton Hanssone1b18362021-12-23 15:05:38 +00003418// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003419// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003420func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003421 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003422 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003423 "android.provider",
3424 },
Wei Li40f98732022-05-20 22:08:11 -07003425 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003426 "android.permission",
3427 "android.app.role",
3428 "com.android.permission",
3429 "com.android.role",
3430 },
Wei Li40f98732022-05-20 22:08:11 -07003431 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003432 "android.os.ext",
3433 },
Wei Li40f98732022-05-20 22:08:11 -07003434 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003435 "android.app",
3436 "android.os",
3437 "android.util",
3438 "com.android.internal.statsd",
3439 "com.android.server.stats",
3440 },
Wei Li40f98732022-05-20 22:08:11 -07003441 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003442 "com.android.server.wifi",
3443 "com.android.wifi.x",
3444 "android.hardware.wifi",
3445 "android.net.wifi",
3446 },
Wei Li40f98732022-05-20 22:08:11 -07003447 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003448 "android.net",
3449 },
3450 }
3451}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003452
3453// For Bazel / bp2build
3454
3455type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003456 Manifest bazel.LabelAttribute
3457 Android_manifest bazel.LabelAttribute
3458 File_contexts bazel.LabelAttribute
3459 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003460 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3461 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Liz Kammerb83b7b02022-12-21 14:53:41 -05003462 Min_sdk_version bazel.StringAttribute
Yu Liu4ae55d12022-01-05 17:17:23 -08003463 Updatable bazel.BoolAttribute
3464 Installable bazel.BoolAttribute
3465 Binaries bazel.LabelListAttribute
3466 Prebuilts bazel.LabelListAttribute
3467 Native_shared_libs_32 bazel.LabelListAttribute
3468 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003469 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003470 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003471 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003472 Tests bazel.LabelListAttribute
Jingwen Chenc4c34e12022-11-29 12:07:45 +00003473 Base_apex_name *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003474}
3475
3476type convertedNativeSharedLibs struct {
3477 Native_shared_libs_32 bazel.LabelListAttribute
3478 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003479}
3480
Liz Kammerb83b7b02022-12-21 14:53:41 -05003481const (
3482 minSdkVersionPropName = "Min_sdk_version"
3483)
3484
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003485// ConvertWithBp2build performs bp2build conversion of an apex
3486func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003487 // We only convert apex and apex_test modules at this time
3488 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003489 return
3490 }
3491
Wei Li1c66fc72022-05-09 23:59:14 -07003492 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003493 commonAttrs := android.CommonAttributes{
3494 Name: a.Name(),
3495 }
3496 if a.testApex {
3497 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3498 }
3499 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003500}
3501
3502func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003503 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003504 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003505
3506 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003507 if a.properties.AndroidManifest != nil {
3508 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003509 }
3510
3511 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003512 if a.properties.File_contexts == nil {
3513 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3514 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3515 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3516 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003517 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003518 } else {
3519 // File_contexts is a file
3520 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003521 }
3522
Liz Kammerb83b7b02022-12-21 14:53:41 -05003523 productVariableProps := android.ProductVariableProperties(ctx)
Albert Martineefabcf2022-03-21 20:11:16 +00003524 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3525 // given it's coming via config, we probably don't want to put it in here.
Liz Kammerb83b7b02022-12-21 14:53:41 -05003526 var minSdkVersion bazel.StringAttribute
zhidou133c55b2023-01-31 19:34:10 +00003527 if a.overridableProperties.Min_sdk_version != nil {
3528 minSdkVersion.SetValue(*a.overridableProperties.Min_sdk_version)
Liz Kammerb83b7b02022-12-21 14:53:41 -05003529 }
3530 if props, ok := productVariableProps[minSdkVersionPropName]; ok {
3531 for c, p := range props {
3532 if val, ok := p.(*string); ok {
3533 minSdkVersion.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val)
3534 }
3535 }
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003536 }
3537
3538 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003539 if a.overridableProperties.Key != nil {
3540 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003541 }
3542
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003543 // Certificate
3544 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003545
Yu Liu4ae55d12022-01-05 17:17:23 -08003546 nativeSharedLibs := &convertedNativeSharedLibs{
3547 Native_shared_libs_32: bazel.LabelListAttribute{},
3548 Native_shared_libs_64: bazel.LabelListAttribute{},
3549 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003550
3551 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3552 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3553 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3554 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3555 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003556 if a.CompileMultilib() != nil {
3557 compileMultilib = *a.CompileMultilib()
3558 }
3559
3560 // properties.Native_shared_libs is treated as "both"
3561 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3562 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3563 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3564 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3565 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003566
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003567 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003568 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3569 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3570
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003571 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003572 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003573
Yu Liu4c212ce2022-10-14 12:20:20 -07003574 var testsAttrs bazel.LabelListAttribute
3575 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3576 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3577 testsAttrs = bazel.MakeLabelListAttribute(tests)
3578 }
3579
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003580 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003581 if a.properties.Updatable != nil {
3582 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003583 }
3584
3585 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003586 if a.properties.Installable != nil {
3587 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003588 }
3589
Wei Lif034cb42022-01-19 15:54:31 -08003590 var compressibleAttribute bazel.BoolAttribute
3591 if a.overridableProperties.Compressible != nil {
3592 compressibleAttribute.Value = a.overridableProperties.Compressible
3593 }
3594
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003595 var packageName *string
3596 if a.overridableProperties.Package_name != "" {
3597 packageName = &a.overridableProperties.Package_name
3598 }
3599
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003600 var loggingParent *string
3601 if a.overridableProperties.Logging_parent != "" {
3602 loggingParent = &a.overridableProperties.Logging_parent
3603 }
3604
Wei Li1c66fc72022-05-09 23:59:14 -07003605 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003606 Manifest: manifestLabelAttribute,
3607 Android_manifest: androidManifestLabelAttribute,
3608 File_contexts: fileContextsLabelAttribute,
3609 Min_sdk_version: minSdkVersion,
3610 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003611 Certificate: certificate,
3612 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003613 Updatable: updatableAttribute,
3614 Installable: installableAttribute,
3615 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3616 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3617 Binaries: binariesLabelListAttribute,
3618 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003619 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003620 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003621 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003622 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003623 }
3624
3625 props := bazel.BazelTargetModuleProperties{
3626 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003627 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003628 }
3629
Wei Li1c66fc72022-05-09 23:59:14 -07003630 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003631}
Yu Liu4ae55d12022-01-05 17:17:23 -08003632
3633// The following conversions are based on this table where the rows are the compile_multilib
3634// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3635// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3636// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3637// should not be compiled.
3638// multib/compile_multilib, 32, 64, both, first
3639// 32, 32/32, none/none, 32/32, none/32
3640// 64, none/none, 64/none, 64/none, 64/none
3641// both, 32/32, 64/none, 32&64/32, 64/32
3642// first, 32/32, 64/none, 64/32, 64/32
3643
3644func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3645 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3646 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3647 switch compileMultilb {
3648 case "both", "32":
3649 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3650 case "first":
3651 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3652 case "64":
3653 // Incompatible, ignore
3654 default:
3655 invalidCompileMultilib(ctx, compileMultilb)
3656 }
3657}
3658
3659func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3660 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3661 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3662 switch compileMultilb {
3663 case "both", "64", "first":
3664 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3665 case "32":
3666 // Incompatible, ignore
3667 default:
3668 invalidCompileMultilib(ctx, compileMultilb)
3669 }
3670}
3671
3672func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3673 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3674 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3675 switch compileMultilb {
3676 case "both":
3677 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3678 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3679 case "first":
3680 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3681 case "32":
3682 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3683 case "64":
3684 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3685 default:
3686 invalidCompileMultilib(ctx, compileMultilb)
3687 }
3688}
3689
3690func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3691 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3692 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3693 switch compileMultilb {
3694 case "both", "first":
3695 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3696 case "32":
3697 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3698 case "64":
3699 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3700 default:
3701 invalidCompileMultilib(ctx, compileMultilb)
3702 }
3703}
3704
3705func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3706 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3707 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3708}
3709
3710func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3711 list := bazel.LabelListAttribute{}
3712 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3713 nativeSharedLibs.Native_shared_libs_32.Append(list)
3714}
3715
3716func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3717 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3718 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3719}
3720
3721func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3722 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3723 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3724}
3725
3726func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3727 labelListAttr *bazel.LabelListAttribute) {
3728 list := bazel.LabelListAttribute{}
3729 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3730 labelListAttr.Append(list)
3731}
3732
3733func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3734 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3735}