blob: a9c8afce75c9299f279857b5d9d86ed17b416d95 [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
Jiyong Parkc0ec6f92020-11-19 23:00:52 +090097 // 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.
Jiyong Park8e6d52f2020-11-19 14:37:47 +090099 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
Daniel Norman6cfb37af2021-11-16 20:28:29 +0000152 // Whether this is multi-installed APEX should skip installing symbol files.
153 // Multi-installed APEXes share the same apex_name and are installed at the same time.
154 // Default is false.
155 //
156 // Should be set to true for all multi-installed APEXes except the singular
157 // default version within the multi-installed group.
158 // Only the default version can install symbol files in $(PRODUCT_OUT}/apex,
159 // or else conflicting build rules may be created.
160 Multi_install_skip_symbol_files *bool
161
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900162 // The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
163 // 'both'. When set to image, contents are stored in a filesystem image inside a zip
164 // container. When set to zip, contents are stored in a zip container directly. This type is
165 // mostly for host-side debugging. When set to both, the two types are both built. Default
166 // is 'image'.
167 Payload_type *string
168
Huang Jianan13cac632021-08-02 15:02:17 +0800169 // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
170 // or 'erofs'. Default 'ext4'.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900171 Payload_fs_type *string
172
173 // For telling the APEX to ignore special handling for system libraries such as bionic.
174 // Default is false.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900175 Ignore_system_library_special_case *bool
176
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100177 // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
Nikita Ioffee261ae62021-06-16 18:15:03 +0100178 // Default value is true.
Nikita Ioffeda6dc312021-06-09 19:43:46 +0100179 Generate_hashtree *bool
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900180
181 // Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
182 // used in tests.
183 Test_only_unsigned_payload *bool
184
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +0000185 // Whenever apex should be compressed, regardless of product flag used. Should be only
186 // used in tests.
187 Test_only_force_compression *bool
188
Jooyung Han09c11ad2021-10-27 03:45:31 +0900189 // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
190 // with the tool to sign payload contents.
191 Custom_sign_tool *string
192
Dennis Shenaf41bc12022-08-03 16:46:43 +0000193 // Whether this is a dynamic common lib apex, if so the native shared libs will be placed
194 // in a special way that include the digest of the lib file under /lib(64)?
195 Dynamic_common_lib_apex *bool
196
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100197 // Canonical name of this APEX bundle. Used to determine the path to the
198 // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
199 // apex mutator variations. For override_apex modules, this is the name of the
200 // overridden base module.
201 ApexVariationName string `blueprint:"mutated"`
202
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900203 IsCoverageVariant bool `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900204
205 // List of sanitizer names that this APEX is enabled for
206 SanitizerNames []string `blueprint:"mutated"`
207
208 PreventInstall bool `blueprint:"mutated"`
209
210 HideFromMake bool `blueprint:"mutated"`
211
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900212 // Internal package method for this APEX. When payload_type is image, this can be either
213 // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
214 // this becomes zipApex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900215 ApexType apexPackaging `blueprint:"mutated"`
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900216}
217
218type ApexNativeDependencies struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900219 // List of native libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900220 Native_shared_libs []string
221
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900222 // List of JNI libraries that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900223 Jni_libs []string
224
Colin Cross70572ed2022-11-02 13:14:20 -0700225 // List of rust dyn libraries that are embedded inside this APEX.
Jiyong Park99644e92020-11-17 22:21:02 +0900226 Rust_dyn_libs []string
227
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900228 // List of native executables that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900229 Binaries []string
230
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900231 // List of native tests that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900232 Tests []string
Jiyong Park06711462021-02-15 17:54:43 +0900233
234 // List of filesystem images that are embedded inside this APEX bundle.
235 Filesystems []string
Colin Cross70572ed2022-11-02 13:14:20 -0700236
237 // List of native libraries to exclude from this APEX.
238 Exclude_native_shared_libs []string
239
240 // List of JNI libraries to exclude from this APEX.
241 Exclude_jni_libs []string
242
243 // List of rust dyn libraries to exclude from this APEX.
244 Exclude_rust_dyn_libs []string
245
246 // List of native executables to exclude from this APEX.
247 Exclude_binaries []string
248
249 // List of native tests to exclude from this APEX.
250 Exclude_tests []string
251
252 // List of filesystem images to exclude from this APEX bundle.
253 Exclude_filesystems []string
254}
255
256// Merge combines another ApexNativeDependencies into this one
257func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
258 a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
259 a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
260 a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
261 a.Binaries = append(a.Binaries, b.Binaries...)
262 a.Tests = append(a.Tests, b.Tests...)
263 a.Filesystems = append(a.Filesystems, b.Filesystems...)
264
265 a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
266 a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
267 a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
268 a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
269 a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
270 a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900271}
272
273type apexMultilibProperties struct {
274 // Native dependencies whose compile_multilib is "first"
275 First ApexNativeDependencies
276
277 // Native dependencies whose compile_multilib is "both"
278 Both ApexNativeDependencies
279
280 // Native dependencies whose compile_multilib is "prefer32"
281 Prefer32 ApexNativeDependencies
282
283 // Native dependencies whose compile_multilib is "32"
284 Lib32 ApexNativeDependencies
285
286 // Native dependencies whose compile_multilib is "64"
287 Lib64 ApexNativeDependencies
288}
289
290type apexTargetBundleProperties struct {
291 Target struct {
292 // Multilib properties only for android.
293 Android struct {
294 Multilib apexMultilibProperties
295 }
296
297 // Multilib properties only for host.
298 Host struct {
299 Multilib apexMultilibProperties
300 }
301
302 // Multilib properties only for host linux_bionic.
303 Linux_bionic struct {
304 Multilib apexMultilibProperties
305 }
306
307 // Multilib properties only for host linux_glibc.
308 Linux_glibc struct {
309 Multilib apexMultilibProperties
310 }
311 }
312}
313
Jiyong Park59140302020-12-14 18:44:04 +0900314type apexArchBundleProperties struct {
315 Arch struct {
316 Arm struct {
317 ApexNativeDependencies
318 }
319 Arm64 struct {
320 ApexNativeDependencies
321 }
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700322 Riscv64 struct {
323 ApexNativeDependencies
324 }
Jiyong Park59140302020-12-14 18:44:04 +0900325 X86 struct {
326 ApexNativeDependencies
327 }
328 X86_64 struct {
329 ApexNativeDependencies
330 }
331 }
332}
333
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900334// These properties can be used in override_apex to override the corresponding properties in the
335// base apex.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900336type overridableProperties struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900337 // List of APKs that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900338 Apps []string
339
Daniel Norman5a3ce132021-08-26 15:44:43 -0700340 // List of prebuilt files that are embedded inside this APEX bundle.
341 Prebuilts []string
342
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900343 // List of runtime resource overlays (RROs) that are embedded inside this APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900344 Rros []string
345
markchien7c803b82021-08-26 22:10:06 +0800346 // List of BPF programs inside this APEX bundle.
347 Bpfs []string
348
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900349 // List of bootclasspath fragments that are embedded inside this APEX bundle.
350 Bootclasspath_fragments []string
351
352 // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
353 Systemserverclasspath_fragments []string
354
355 // List of java libraries that are embedded inside this APEX bundle.
356 Java_libs []string
357
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900358 // Names of modules to be overridden. Listed modules can only be other binaries (in Make or
359 // Soong). This does not completely prevent installation of the overridden binaries, but if
360 // both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
361 // be removed from PRODUCT_PACKAGES.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900362 Overrides []string
363
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900364 // Logging parent value.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900365 Logging_parent string
366
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900367 // Apex Container package name. Override value for attribute package:name in
368 // AndroidManifest.xml
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900369 Package_name string
370
371 // A txt file containing list of files that are allowed to be included in this APEX.
372 Allowed_files *string `android:"path"`
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700373
374 // Name of the apex_key module that provides the private key to sign this APEX bundle.
375 Key *string
376
377 // Specifies the certificate and the private key to sign the zip container of this APEX. If
378 // this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
379 // as the certificate and the private key, respectively. If this is ":module", then the
380 // certificate and the private key are provided from the android_app_certificate module
381 // named "module".
382 Certificate *string
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -0400383
384 // Whether this APEX can be compressed or not. Setting this property to false means this
385 // APEX will never be compressed. When set to true, APEX will be compressed if other
386 // conditions, e.g., target device needs to support APEX compression, are also fulfilled.
387 // Default: false.
388 Compressible *bool
Dennis Shene2ed70c2023-01-11 14:15:43 +0000389
390 // Trim against a specific Dynamic Common Lib APEX
391 Trim_against *string
zhidou133c55b2023-01-31 19:34:10 +0000392
393 // The minimum SDK version that this APEX must support at minimum. This is usually set to
394 // the SDK version that the APEX was first introduced.
395 Min_sdk_version *string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900396}
397
398type apexBundle struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900399 // Inherited structs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900400 android.ModuleBase
401 android.DefaultableModuleBase
402 android.OverridableModuleBase
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -0400403 android.BazelModuleBase
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900404 multitree.ExportableModuleBase
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900405
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900406 // Properties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900407 properties apexBundleProperties
408 targetProperties apexTargetBundleProperties
Jiyong Park59140302020-12-14 18:44:04 +0900409 archProperties apexArchBundleProperties
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900410 overridableProperties overridableProperties
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900411 vndkProperties apexVndkProperties // only for apex_vndk modules
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900412
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900413 ///////////////////////////////////////////////////////////////////////////////////////////
414 // Inputs
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900415
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900416 // Keys for apex_paylaod.img
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800417 publicKeyFile android.Path
418 privateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900419
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900420 // Cert/priv-key for the zip container
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800421 containerCertificateFile android.Path
422 containerPrivateKeyFile android.Path
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900423
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900424 // Flags for special variants of APEX
425 testApex bool
426 vndkApex bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900427
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900428 // Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
429 // one gets installed to the device.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900430 primaryApexType bool
431
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900432 // Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900433 suffix string
434
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900435 // File system type of apex_payload.img
436 payloadFsType fsType
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900437
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900438 // Whether to create symlink to the system file instead of having a file inside the apex or
439 // not
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900440 linkToSystemLib bool
441
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900442 // List of files to be included in this APEX. This is filled in the first part of
443 // GenerateAndroidBuildActions.
444 filesInfo []apexFile
445
Jingwen Chen29743c82023-01-25 17:49:46 +0000446 // List of other module names that should be installed when this APEX gets installed (LOCAL_REQUIRED_MODULES).
447 makeModulesToInstall []string
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900448
449 ///////////////////////////////////////////////////////////////////////////////////////////
450 // Outputs (final and intermediates)
451
452 // Processed apex manifest in JSONson format (for Q)
453 manifestJsonOut android.WritablePath
454
455 // Processed apex manifest in PB format (for R+)
456 manifestPbOut android.WritablePath
457
458 // Processed file_contexts files
459 fileContexts android.WritablePath
460
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900461 // The built APEX file. This is the main product.
Jooyung Hana6d36672022-02-24 13:58:07 +0900462 // Could be .apex or .capex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900463 outputFile android.WritablePath
464
Jooyung Hana6d36672022-02-24 13:58:07 +0900465 // The built uncompressed .apex file.
466 outputApexFile android.WritablePath
467
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900468 // The built APEX file in app bundle format. This file is not directly installed to the
469 // device. For an APEX, multiple app bundles are created each of which is for a specific ABI
470 // like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
471 // system) to be merged into a single app bundle file that Play accepts. See
472 // vendor/google/build/build_unbundled_mainline_module.sh for more detail.
473 bundleModuleFile android.WritablePath
474
Colin Cross6340ea52021-11-04 12:01:18 -0700475 // Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900476 installDir android.InstallPath
477
Colin Cross6340ea52021-11-04 12:01:18 -0700478 // Path where this APEX was installed.
479 installedFile android.InstallPath
480
481 // Installed locations of symlinks for backward compatibility.
482 compatSymlinks android.InstallPaths
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900483
484 // Text file having the list of individual files that are included in this APEX. Used for
485 // debugging purpose.
486 installedFilesFile android.WritablePath
487
488 // List of module names that this APEX is including (to be shown via *-deps-info target).
489 // Used for debugging purpose.
490 android.ApexBundleDepsInfo
491
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900492 // Optional list of lint report zip files for apexes that contain java or app modules
493 lintReports android.Paths
494
Mohammad Samiul Islam3cd005d2020-11-26 13:32:26 +0000495 isCompressed bool
496
sophiezc80a2b32020-11-12 16:39:19 +0000497 // Path of API coverage generate file
sophiez02347372021-11-02 17:58:02 -0700498 nativeApisUsedByModuleFile android.ModuleOutPath
499 nativeApisBackedByModuleFile android.ModuleOutPath
500 javaApisUsedByModuleFile android.ModuleOutPath
braleeb0c1f0c2021-06-07 22:49:13 +0800501
502 // Collect the module directory for IDE info in java/jdeps.go.
503 modulePaths []string
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900504}
505
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900506// apexFileClass represents a type of file that can be included in APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900507type apexFileClass int
508
Jooyung Han72bd2f82019-10-23 16:46:38 +0900509const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900510 app apexFileClass = iota
511 appSet
512 etc
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900513 goBinary
514 javaSharedLib
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900515 nativeExecutable
516 nativeSharedLib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900517 nativeTest
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900518 pyBinary
519 shBinary
Jooyung Han72bd2f82019-10-23 16:46:38 +0900520)
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900521
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900522// apexFile represents a file in an APEX bundle. This is created during the first half of
523// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
524// of the function, this is used to create commands that copies the files into a staging directory,
525// where they are packaged into the APEX file. This struct is also used for creating Make modules
526// for each of the files in case when the APEX is flattened.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900527type apexFile struct {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900528 // buildFile is put in the installDir inside the APEX.
Bob Badourde6a0872022-04-01 18:00:00 +0000529 builtFile android.Path
530 installDir string
531 customStem string
532 symlinks []string // additional symlinks
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900533
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900534 // Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
535 // module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
536 // suffix>]
537 androidMkModuleName string // becomes LOCAL_MODULE
538 class apexFileClass // becomes LOCAL_MODULE_CLASS
539 moduleDir string // becomes LOCAL_PATH
540 requiredModuleNames []string // becomes LOCAL_REQUIRED_MODULES
541 targetRequiredModuleNames []string // becomes LOCAL_TARGET_REQUIRED_MODULES
542 hostRequiredModuleNames []string // becomes LOCAL_HOST_REQUIRED_MODULES
543 dataPaths []android.DataPath // becomes LOCAL_TEST_DATA
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900544
545 jacocoReportClassesFile android.Path // only for javalibs and apps
546 lintDepSets java.LintDepSets // only for javalibs and apps
547 certificate java.Certificate // only for apps
548 overriddenPackageName string // only for apps
549
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900550 transitiveDep bool
551 isJniLib bool
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900552
Jiyong Park57621b22021-01-20 20:33:11 +0900553 multilib string
554
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900555 // TODO(jiyong): remove this
556 module android.Module
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900557}
558
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900559// TODO(jiyong): shorten the arglist using an option struct
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900560func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
561 ret := apexFile{
562 builtFile: builtFile,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900563 installDir: installDir,
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900564 androidMkModuleName: androidMkModuleName,
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900565 class: class,
566 module: module,
567 }
568 if module != nil {
569 ret.moduleDir = ctx.OtherModuleDir(module)
570 ret.requiredModuleNames = module.RequiredModuleNames()
571 ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
572 ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
Jiyong Park57621b22021-01-20 20:33:11 +0900573 ret.multilib = module.Target().Arch.ArchType.Multilib
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900574 }
575 return ret
576}
577
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900578func (af *apexFile) ok() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900579 return af.builtFile != nil && af.builtFile.String() != ""
580}
581
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900582// apexRelativePath returns the relative path of the given path from the install directory of this
583// apexFile.
584// TODO(jiyong): rename this
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900585func (af *apexFile) apexRelativePath(path string) string {
586 return filepath.Join(af.installDir, path)
587}
588
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900589// path returns path of this apex file relative to the APEX root
590func (af *apexFile) path() string {
591 return af.apexRelativePath(af.stem())
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900592}
593
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900594// stem returns the base filename of this apex file
595func (af *apexFile) stem() string {
596 if af.customStem != "" {
597 return af.customStem
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900598 }
599 return af.builtFile.Base()
600}
601
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900602// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
603func (af *apexFile) symlinkPaths() []string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900604 var ret []string
605 for _, symlink := range af.symlinks {
606 ret = append(ret, af.apexRelativePath(symlink))
607 }
608 return ret
609}
610
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900611// availableToPlatform tests whether this apexFile is from a module that can be installed to the
612// platform.
613func (af *apexFile) availableToPlatform() bool {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900614 if af.module == nil {
615 return false
616 }
617 if am, ok := af.module.(android.ApexModule); ok {
618 return am.AvailableFor(android.AvailableToPlatform)
619 }
620 return false
621}
622
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900623////////////////////////////////////////////////////////////////////////////////////////////////////
624// Mutators
625//
626// Brief description about mutators for APEX. The following three mutators are the most important
627// ones.
628//
629// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
630// to the (direct) dependencies of this APEX bundle.
631//
Paul Duffin949abc02020-12-08 10:34:30 +0000632// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900633// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
634// modules are marked as being included in the APEX via BuildForApex().
635//
Paul Duffin949abc02020-12-08 10:34:30 +0000636// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
637// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900638
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900639type dependencyTag struct {
640 blueprint.BaseDependencyTag
641 name string
642
643 // Determines if the dependent will be part of the APEX payload. Can be false for the
644 // dependencies to the signing key module, etc.
645 payload bool
Paul Duffin8c535da2021-03-17 14:51:03 +0000646
647 // True if the dependent can only be a source module, false if a prebuilt module is a suitable
648 // replacement. This is needed because some prebuilt modules do not provide all the information
649 // needed by the apex.
650 sourceOnly bool
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000651
652 // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
653 // also be added as exported members of that SDK.
654 memberType android.SdkMemberType
655}
656
657func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
658 return d.memberType
659}
660
661func (d *dependencyTag) ExportMember() bool {
662 return true
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900663}
664
Paul Duffin520917a2022-05-13 13:01:59 +0000665func (d *dependencyTag) String() string {
666 return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
667}
668
669func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
Paul Duffin8c535da2021-03-17 14:51:03 +0000670 return !d.sourceOnly
671}
672
673var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000674var _ android.SdkMemberDependencyTag = &dependencyTag{}
Paul Duffin8c535da2021-03-17 14:51:03 +0000675
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900676var (
Paul Duffin520917a2022-05-13 13:01:59 +0000677 androidAppTag = &dependencyTag{name: "androidApp", payload: true}
678 bpfTag = &dependencyTag{name: "bpf", payload: true}
679 certificateTag = &dependencyTag{name: "certificate"}
Dennis Shene2ed70c2023-01-11 14:15:43 +0000680 dclaTag = &dependencyTag{name: "dcla"}
Paul Duffin520917a2022-05-13 13:01:59 +0000681 executableTag = &dependencyTag{name: "executable", payload: true}
682 fsTag = &dependencyTag{name: "filesystem", payload: true}
Paul Duffin4e7d1c42022-05-13 13:12:19 +0000683 bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
684 sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
Paul Duffinfcf79852022-07-20 14:18:24 +0000685 compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
Paul Duffin520917a2022-05-13 13:01:59 +0000686 javaLibTag = &dependencyTag{name: "javaLib", payload: true}
687 jniLibTag = &dependencyTag{name: "jniLib", payload: true}
688 keyTag = &dependencyTag{name: "key"}
689 prebuiltTag = &dependencyTag{name: "prebuilt", payload: true}
690 rroTag = &dependencyTag{name: "rro", payload: true}
691 sharedLibTag = &dependencyTag{name: "sharedLib", payload: true}
692 testForTag = &dependencyTag{name: "test for"}
693 testTag = &dependencyTag{name: "test", payload: true}
694 shBinaryTag = &dependencyTag{name: "shBinary", payload: true}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900695)
696
697// TODO(jiyong): shorten this function signature
698func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900699 binVariations := target.Variations()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900700 libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
Jiyong Park99644e92020-11-17 22:21:02 +0900701 rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900702
703 if ctx.Device() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900704 binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Parkf2cc1b72020-12-09 00:20:45 +0900705 libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
706 rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900707 }
708
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900709 // Use *FarVariation* to be able to depend on modules having conflicting variations with
710 // this module. This is required since arch variant of an APEX bundle is 'common' but it is
711 // 'arm' or 'arm64' for native shared libs.
Colin Cross70572ed2022-11-02 13:14:20 -0700712 ctx.AddFarVariationDependencies(binVariations, executableTag,
713 android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
714 ctx.AddFarVariationDependencies(binVariations, testTag,
715 android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
716 ctx.AddFarVariationDependencies(libVariations, jniLibTag,
717 android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
718 ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
719 android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
720 ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
721 android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
722 ctx.AddFarVariationDependencies(target.Variations(), fsTag,
723 android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900724}
725
726func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900727 if ctx.Device() {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900728 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
729 } else {
730 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
731 if ctx.Os().Bionic() {
732 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
733 } else {
734 proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
735 }
736 }
737}
738
Jooyung Hand045ebc2022-12-06 15:23:57 +0900739// getImageVariationPair returns a pair for the image variation name as its
740// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
741// suffix indicates the vndk version when it's vendor or product.
742// getImageVariation can simply join the result of this function to get the
743// image variation name.
744func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900745 if a.vndkApex {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900746 return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900747 }
748
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900749 var prefix string
750 var vndkVersion string
751 if deviceConfig.VndkVersion() != "" {
Steven Moreland2c4000c2021-04-27 02:08:49 +0000752 if a.SocSpecific() || a.DeviceSpecific() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900753 prefix = cc.VendorVariationPrefix
754 vndkVersion = deviceConfig.VndkVersion()
755 } else if a.ProductSpecific() {
756 prefix = cc.ProductVariationPrefix
757 vndkVersion = deviceConfig.ProductVndkVersion()
758 }
759 }
760 if vndkVersion == "current" {
761 vndkVersion = deviceConfig.PlatformVndkVersion()
762 }
763 if vndkVersion != "" {
Jooyung Hand045ebc2022-12-06 15:23:57 +0900764 return prefix, vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900765 }
766
Jooyung Hand045ebc2022-12-06 15:23:57 +0900767 return android.CoreVariation, "" // The usual case
768}
769
770// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
771// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
772func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
773 prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
774 return prefix + vndkVersion
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900775}
776
777func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900778 // apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
779 // arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
780 // each target os/architectures, appropriate dependencies are selected by their
781 // target.<os>.multilib.<type> groups and are added as (direct) dependencies.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900782 targets := ctx.MultiTargets()
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900783 imageVariation := a.getImageVariation(ctx)
784
785 a.combineProperties(ctx)
786
787 has32BitTarget := false
788 for _, target := range targets {
789 if target.Arch.ArchType.Multilib == "lib32" {
790 has32BitTarget = true
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000791 }
792 }
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900793 for i, target := range targets {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900794 // Don't include artifacts for the host cross targets because there is no way for us
795 // to run those artifacts natively on host
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900796 if target.HostCross {
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900797 continue
798 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000799
Colin Cross70572ed2022-11-02 13:14:20 -0700800 var deps ApexNativeDependencies
Paul Duffin7d74e7b2020-03-06 12:30:13 +0000801
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900802 // Add native modules targeting both ABIs. When multilib.* is omitted for
803 // native_shared_libs/jni_libs/tests, it implies multilib.both
Colin Cross70572ed2022-11-02 13:14:20 -0700804 deps.Merge(a.properties.Multilib.Both)
805 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900806 Native_shared_libs: a.properties.Native_shared_libs,
807 Tests: a.properties.Tests,
808 Jni_libs: a.properties.Jni_libs,
809 Binaries: nil,
810 })
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900811
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900812 // Add native modules targeting the first ABI When multilib.* is omitted for
813 // binaries, it implies multilib.first
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900814 isPrimaryAbi := i == 0
815 if isPrimaryAbi {
Colin Cross70572ed2022-11-02 13:14:20 -0700816 deps.Merge(a.properties.Multilib.First)
817 deps.Merge(ApexNativeDependencies{
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900818 Native_shared_libs: nil,
819 Tests: nil,
820 Jni_libs: nil,
821 Binaries: a.properties.Binaries,
822 })
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900823 }
824
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900825 // Add native modules targeting either 32-bit or 64-bit ABI
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900826 switch target.Arch.ArchType.Multilib {
827 case "lib32":
Colin Cross70572ed2022-11-02 13:14:20 -0700828 deps.Merge(a.properties.Multilib.Lib32)
829 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900830 case "lib64":
Colin Cross70572ed2022-11-02 13:14:20 -0700831 deps.Merge(a.properties.Multilib.Lib64)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900832 if !has32BitTarget {
Colin Cross70572ed2022-11-02 13:14:20 -0700833 deps.Merge(a.properties.Multilib.Prefer32)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900834 }
835 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900836
Jiyong Park59140302020-12-14 18:44:04 +0900837 // Add native modules targeting a specific arch variant
838 switch target.Arch.ArchType {
839 case android.Arm:
Colin Cross70572ed2022-11-02 13:14:20 -0700840 deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900841 case android.Arm64:
Colin Cross70572ed2022-11-02 13:14:20 -0700842 deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
Colin Crossa2aaa2f2022-10-03 12:41:50 -0700843 case android.Riscv64:
Colin Cross70572ed2022-11-02 13:14:20 -0700844 deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900845 case android.X86:
Colin Cross70572ed2022-11-02 13:14:20 -0700846 deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900847 case android.X86_64:
Colin Cross70572ed2022-11-02 13:14:20 -0700848 deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
Jiyong Park59140302020-12-14 18:44:04 +0900849 default:
850 panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
851 }
852
Colin Cross70572ed2022-11-02 13:14:20 -0700853 addDependenciesForNativeModules(ctx, deps, target, imageVariation)
Sundong Ahn80c04892021-11-23 00:57:19 +0000854 ctx.AddFarVariationDependencies([]blueprint.Variation{
855 {Mutator: "os", Variation: target.OsVariation()},
856 {Mutator: "arch", Variation: target.ArchVariation()},
857 }, shBinaryTag, a.properties.Sh_binaries...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900858 }
859
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900860 // Common-arch dependencies come next
861 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
Jiyong Park12a719c2021-01-07 15:31:24 +0900862 ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
Paul Duffin0b817782021-03-17 15:02:19 +0000863 ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
Andrei Onea115e7e72020-06-05 21:14:03 +0100864}
865
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900866// DepsMutator for the overridden properties.
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900867func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
868 if a.overridableProperties.Allowed_files != nil {
869 android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
Andrei Onea115e7e72020-06-05 21:14:03 +0100870 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900871
872 commonVariation := ctx.Config().AndroidCommonTarget.Variations()
873 ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
markchien7c803b82021-08-26 22:10:06 +0800874 ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900875 ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
Remi NGUYEN VANbe901722022-03-02 21:00:33 +0900876 ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
877 ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
878 ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
Daniel Norman5a3ce132021-08-26 15:44:43 -0700879 if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
880 // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
881 // regardless of the TARGET_PREFER_* setting. See b/144532908
882 arches := ctx.DeviceConfig().Arches()
883 if len(arches) != 0 {
884 archForPrebuiltEtc := arches[0]
885 for _, arch := range arches {
886 // Prefer 64-bit arch if there is any
887 if arch.ArchType.Multilib == "lib64" {
888 archForPrebuiltEtc = arch
889 break
890 }
891 }
892 ctx.AddFarVariationDependencies([]blueprint.Variation{
893 {Mutator: "os", Variation: ctx.Os().String()},
894 {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
895 }, prebuiltTag, prebuilts...)
896 }
897 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -0700898
899 // Dependencies for signing
900 if String(a.overridableProperties.Key) == "" {
901 ctx.PropertyErrorf("key", "missing")
902 return
903 }
904 ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
905
906 cert := android.SrcIsModule(a.getCertString(ctx))
907 if cert != "" {
908 ctx.AddDependency(ctx.Module(), certificateTag, cert)
909 // empty cert is not an error. Cert and private keys will be directly found under
910 // PRODUCT_DEFAULT_DEV_CERTIFICATE
911 }
Andrei Onea115e7e72020-06-05 21:14:03 +0100912}
913
Dennis Shene2ed70c2023-01-11 14:15:43 +0000914func apexDCLADepsMutator(mctx android.BottomUpMutatorContext) {
915 if !mctx.Config().ApexTrimEnabled() {
916 return
917 }
918 if a, ok := mctx.Module().(*apexBundle); ok && a.overridableProperties.Trim_against != nil {
919 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
920 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(a.overridableProperties.Trim_against))
921 } else if o, ok := mctx.Module().(*OverrideApex); ok {
922 for _, p := range o.GetProperties() {
923 properties, ok := p.(*overridableProperties)
924 if !ok {
925 continue
926 }
927 if properties.Trim_against != nil {
928 commonVariation := mctx.Config().AndroidCommonTarget.Variations()
929 mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(properties.Trim_against))
930 }
931 }
932 }
933}
934
935type DCLAInfo struct {
936 ProvidedLibs []string
937}
938
939var DCLAInfoProvider = blueprint.NewMutatorProvider(DCLAInfo{}, "apex_info")
940
Jiyong Park8e6d52f2020-11-19 14:37:47 +0900941type ApexBundleInfo struct {
942 Contents *android.ApexContents
Andrei Onea115e7e72020-06-05 21:14:03 +0100943}
944
Paul Duffin949abc02020-12-08 10:34:30 +0000945var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
Jiyong Park48ca7dc2018-10-10 14:01:00 +0900946
Paul Duffina7d6a892020-12-07 17:39:59 +0000947var _ ApexInfoMutator = (*apexBundle)(nil)
948
Martin Stjernholmbfffae72021-06-24 14:37:13 +0100949func (a *apexBundle) ApexVariationName() string {
950 return a.properties.ApexVariationName
951}
952
Paul Duffina7d6a892020-12-07 17:39:59 +0000953// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900954// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
955// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
956// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
957// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
Paul Duffin949abc02020-12-08 10:34:30 +0000958//
959// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
960// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
961// The apexMutator uses that list to create module variants for the apexes to which it belongs.
962// The relationship between module variants and apexes is not one-to-one as variants will be
963// shared between compatible apexes.
Paul Duffina7d6a892020-12-07 17:39:59 +0000964func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
Jooyung Handf78e212020-07-22 15:54:47 +0900965
Jiyong Parkc0ec6f92020-11-19 23:00:52 +0900966 // The VNDK APEX is special. For the APEX, the membership is described in a very different
967 // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
968 // libraries are self-identified by their vndk.enabled properties. There is no need to run
969 // this mutator for the APEX as nothing will be collected. So, let's return fast.
970 if a.vndkApex {
971 return
972 }
973
974 // Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
975 // provided with a property named use_vndk_as_stable, which when set to true doesn't collect
976 // VNDK libraries as transitive dependencies. This option is useful for reducing the size of
977 // the non-system APEXes because the VNDK libraries won't be included (and duped) in the
978 // APEX, but shared across APEXes via the VNDK APEX.
Jooyung Handf78e212020-07-22 15:54:47 +0900979 useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
980 excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
Jooyung Hanc5a96762022-02-04 11:54:50 +0900981 if proptools.Bool(a.properties.Use_vndk_as_stable) {
982 if !useVndk {
983 mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
984 }
985 mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
986 if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
987 mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
988 }
989 })
990 if mctx.Failed() {
991 return
992 }
Jooyung Handf78e212020-07-22 15:54:47 +0900993 }
994
Colin Cross56a83212020-09-15 18:30:11 -0700995 continueApexDepsWalk := func(child, parent android.Module) bool {
Jooyung Han698dd9f2020-07-22 15:17:19 +0900996 am, ok := child.(android.ApexModule)
997 if !ok || !am.CanHaveApexVariants() {
998 return false
Jiyong Parkf760cae2020-02-12 07:53:12 +0900999 }
Paul Duffin573989d2021-03-17 13:25:29 +00001000 depTag := mctx.OtherModuleDependencyTag(child)
1001
1002 // Check to see if the tag always requires that the child module has an apex variant for every
1003 // apex variant of the parent module. If it does not then it is still possible for something
1004 // else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
1005 if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
1006 return true
1007 }
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001008 if !android.IsDepInSameApex(mctx, parent, child) {
Jooyung Han698dd9f2020-07-22 15:17:19 +09001009 return false
1010 }
Jooyung Handf78e212020-07-22 15:54:47 +09001011 if excludeVndkLibs {
1012 if c, ok := child.(*cc.Module); ok && c.IsVndk() {
1013 return false
1014 }
1015 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001016 // By default, all the transitive dependencies are collected, unless filtered out
1017 // above.
Colin Cross56a83212020-09-15 18:30:11 -07001018 return true
1019 }
1020
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001021 // Records whether a certain module is included in this apexBundle via direct dependency or
1022 // inndirect dependency.
1023 contents := make(map[string]android.ApexMembership)
Colin Cross56a83212020-09-15 18:30:11 -07001024 mctx.WalkDeps(func(child, parent android.Module) bool {
1025 if !continueApexDepsWalk(child, parent) {
1026 return false
1027 }
Jooyung Han698dd9f2020-07-22 15:17:19 +09001028 // If the parent is apexBundle, this child is directly depended.
1029 _, directDep := parent.(*apexBundle)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001030 depName := mctx.OtherModuleName(child)
Colin Cross56a83212020-09-15 18:30:11 -07001031 contents[depName] = contents[depName].Add(directDep)
1032 return true
1033 })
1034
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001035 // The membership information is saved for later access
Jiyong Parke4758ed2020-11-18 01:34:22 +09001036 apexContents := android.NewApexContents(contents)
Colin Cross56a83212020-09-15 18:30:11 -07001037 mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
1038 Contents: apexContents,
1039 })
1040
Jooyung Haned124c32021-01-26 11:43:46 +09001041 minSdkVersion := a.minSdkVersion(mctx)
1042 // When min_sdk_version is not set, the apex is built against FutureApiLevel.
1043 if minSdkVersion.IsNone() {
1044 minSdkVersion = android.FutureApiLevel
1045 }
1046
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001047 // This is the main part of this mutator. Mark the collected dependencies that they need to
1048 // be built for this apexBundle.
Jiyong Park78349b52021-05-12 17:13:56 +09001049
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001050 apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
1051 a.properties.ApexVariationName = apexVariationName
Colin Cross56a83212020-09-15 18:30:11 -07001052 apexInfo := android.ApexInfo{
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001053 ApexVariationName: apexVariationName,
Jiyong Park4eab21d2021-04-15 15:17:54 +09001054 MinSdkVersion: minSdkVersion,
Colin Cross56a83212020-09-15 18:30:11 -07001055 Updatable: a.Updatable(),
Jiyong Park1bc84122021-06-22 20:23:05 +09001056 UsePlatformApis: a.UsePlatformApis(),
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001057 InApexVariants: []string{apexVariationName},
1058 InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
Colin Cross56a83212020-09-15 18:30:11 -07001059 ApexContents: []*android.ApexContents{apexContents},
1060 }
Colin Cross56a83212020-09-15 18:30:11 -07001061 mctx.WalkDeps(func(child, parent android.Module) bool {
1062 if !continueApexDepsWalk(child, parent) {
1063 return false
1064 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001065 child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
Jooyung Han698dd9f2020-07-22 15:17:19 +09001066 return true
Jiyong Parkf760cae2020-02-12 07:53:12 +09001067 })
Dennis Shene2ed70c2023-01-11 14:15:43 +00001068
1069 if a.dynamic_common_lib_apex() {
1070 mctx.SetProvider(DCLAInfoProvider, DCLAInfo{
1071 ProvidedLibs: a.properties.Native_shared_libs,
1072 })
1073 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001074}
1075
Paul Duffina7d6a892020-12-07 17:39:59 +00001076type ApexInfoMutator interface {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001077 // ApexVariationName returns the name of the APEX variation to use in the apex
1078 // mutator etc. It is the same name as ApexInfo.ApexVariationName.
1079 ApexVariationName() string
1080
Paul Duffina7d6a892020-12-07 17:39:59 +00001081 // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1082 // depended upon by an apex and which require an apex specific variant.
1083 ApexInfoMutator(android.TopDownMutatorContext)
1084}
1085
1086// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1087// specific variant to modules that support the ApexInfoMutator.
Spandan Das42e89502022-05-06 22:12:55 +00001088// It also propagates updatable=true to apps of updatable apexes
Paul Duffina7d6a892020-12-07 17:39:59 +00001089func apexInfoMutator(mctx android.TopDownMutatorContext) {
1090 if !mctx.Module().Enabled() {
1091 return
1092 }
1093
1094 if a, ok := mctx.Module().(ApexInfoMutator); ok {
1095 a.ApexInfoMutator(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001096 }
Spandan Das42e89502022-05-06 22:12:55 +00001097 enforceAppUpdatability(mctx)
Paul Duffina7d6a892020-12-07 17:39:59 +00001098}
1099
Spandan Das66773252022-01-15 00:23:18 +00001100// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
1101// This check is enforced for updatable modules
1102func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
1103 if !mctx.Module().Enabled() {
1104 return
1105 }
Spandan Das08c911f2022-01-21 22:07:26 +00001106 if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
Spandan Das66773252022-01-15 00:23:18 +00001107 mctx.WalkDeps(func(child, parent android.Module) bool {
Spandan Dasd9c23ab2022-02-10 02:34:13 +00001108 // b/208656169 Do not propagate strict updatability linting to libcore/
1109 // These libs are available on the classpath during compilation
1110 // These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
1111 // Only skip libraries defined in libcore root, not subdirectories
1112 if mctx.OtherModuleDir(child) == "libcore" {
1113 // Do not traverse transitive deps of libcore/ libs
1114 return false
1115 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001116 if android.InList(child.Name(), skipLintJavalibAllowlist) {
1117 return false
1118 }
Spandan Das66773252022-01-15 00:23:18 +00001119 if lintable, ok := child.(java.LintDepSetsIntf); ok {
1120 lintable.SetStrictUpdatabilityLinting(true)
1121 }
1122 // visit transitive deps
1123 return true
1124 })
1125 }
1126}
1127
Spandan Das42e89502022-05-06 22:12:55 +00001128// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
1129func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
1130 if !mctx.Module().Enabled() {
1131 return
1132 }
1133 if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
1134 // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
1135 mctx.VisitDirectDeps(func(module android.Module) {
1136 // ignore android_test_app
1137 if app, ok := module.(*java.AndroidApp); ok {
1138 app.SetUpdatable(true)
1139 }
1140 })
1141 }
1142}
1143
Spandan Das08c911f2022-01-21 22:07:26 +00001144// TODO: b/215736885 Whittle the denylist
1145// Transitive deps of certain mainline modules baseline NewApi errors
1146// Skip these mainline modules for now
1147var (
1148 skipStrictUpdatabilityLintAllowlist = []string{
1149 "com.android.art",
1150 "com.android.art.debug",
1151 "com.android.conscrypt",
1152 "com.android.media",
1153 // test apexes
1154 "test_com.android.art",
1155 "test_com.android.conscrypt",
1156 "test_com.android.media",
1157 "test_jitzygote_com.android.art",
1158 }
Spandan Das2cf278e2022-03-24 20:19:35 +00001159
1160 // TODO: b/215736885 Remove this list
1161 skipLintJavalibAllowlist = []string{
1162 "conscrypt.module.platform.api.stubs",
1163 "conscrypt.module.public.api.stubs",
1164 "conscrypt.module.public.api.stubs.system",
1165 "conscrypt.module.public.api.stubs.module_lib",
1166 "framework-media.stubs",
1167 "framework-media.stubs.system",
1168 "framework-media.stubs.module_lib",
1169 }
Spandan Das08c911f2022-01-21 22:07:26 +00001170)
1171
1172func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
1173 return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
1174}
1175
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001176// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1177// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1178// TODO(jiyong): move this to android/apex.go?
Colin Crossaede88c2020-08-11 12:17:01 -07001179func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1180 if !mctx.Module().Enabled() {
1181 return
1182 }
1183 if am, ok := mctx.Module().(android.ApexModule); ok {
Colin Cross56a83212020-09-15 18:30:11 -07001184 android.UpdateUniqueApexVariationsForDeps(mctx, am)
1185 }
1186}
1187
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001188// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
1189// the apex in order to retrieve its contents later.
1190// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001191func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
1192 if !mctx.Module().Enabled() {
1193 return
1194 }
Colin Cross56a83212020-09-15 18:30:11 -07001195 if am, ok := mctx.Module().(android.ApexModule); ok {
1196 if testFor := am.TestFor(); len(testFor) > 0 {
1197 mctx.AddFarVariationDependencies([]blueprint.Variation{
1198 {Mutator: "os", Variation: am.Target().OsVariation()},
1199 {"arch", "common"},
1200 }, testForTag, testFor...)
1201 }
1202 }
1203}
1204
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001205// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001206func apexTestForMutator(mctx android.BottomUpMutatorContext) {
1207 if !mctx.Module().Enabled() {
1208 return
1209 }
Colin Cross56a83212020-09-15 18:30:11 -07001210 if _, ok := mctx.Module().(android.ApexModule); ok {
1211 var contents []*android.ApexContents
1212 for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
1213 abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
1214 contents = append(contents, abInfo.Contents)
1215 }
1216 mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
1217 ApexContents: contents,
1218 })
Colin Crossaede88c2020-08-11 12:17:01 -07001219 }
1220}
1221
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001222// markPlatformAvailability marks whether or not a module can be available to platform. A module
1223// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1224// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1225// be) available to platform
1226// TODO(jiyong): move this to android/apex.go?
Jiyong Park89e850a2020-04-07 16:37:39 +09001227func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1228 // Host and recovery are not considered as platform
1229 if mctx.Host() || mctx.Module().InstallInRecovery() {
1230 return
1231 }
1232
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001233 am, ok := mctx.Module().(android.ApexModule)
1234 if !ok {
1235 return
1236 }
Jiyong Park89e850a2020-04-07 16:37:39 +09001237
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001238 availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
Jiyong Park89e850a2020-04-07 16:37:39 +09001239
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001240 // If any of the dep is not available to platform, this module is also considered as being
1241 // not available to platform even if it has "//apex_available:platform"
1242 mctx.VisitDirectDeps(func(child android.Module) {
Paul Duffin4c3e8e22021-03-18 15:41:29 +00001243 if !android.IsDepInSameApex(mctx, am, child) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001244 // if the dependency crosses apex boundary, don't consider it
1245 return
Jiyong Park89e850a2020-04-07 16:37:39 +09001246 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001247 if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1248 availableToPlatform = false
1249 // TODO(b/154889534) trigger an error when 'am' has
1250 // "//apex_available:platform"
Jiyong Park89e850a2020-04-07 16:37:39 +09001251 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001252 })
Jiyong Park89e850a2020-04-07 16:37:39 +09001253
Paul Duffinb5769c12021-05-12 16:16:51 +01001254 // Exception 1: check to see if the module always requires it.
1255 if am.AlwaysRequiresPlatformApexVariant() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001256 availableToPlatform = true
1257 }
1258
1259 // Exception 2: bootstrap bionic libraries are also always available to platform
1260 if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1261 availableToPlatform = true
1262 }
1263
1264 if !availableToPlatform {
1265 am.SetNotAvailableForPlatform()
Jiyong Park89e850a2020-04-07 16:37:39 +09001266 }
1267}
1268
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001269// apexMutator visits each module and creates apex variations if the module was marked in the
Paul Duffin949abc02020-12-08 10:34:30 +00001270// previous run of apexInfoMutator.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001271func apexMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001272 if !mctx.Module().Enabled() {
1273 return
1274 }
Colin Cross56a83212020-09-15 18:30:11 -07001275
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001276 // This is the usual path.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001277 if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
Colin Cross56a83212020-09-15 18:30:11 -07001278 android.CreateApexVariations(mctx, am)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001279 return
1280 }
1281
1282 // apexBundle itself is mutated so that it and its dependencies have the same apex variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001283 if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1284 apexBundleName := ai.ApexVariationName()
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001285 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001286 if strings.HasPrefix(apexBundleName, "com.android.art") {
1287 // Create an alias from the platform variant. This is done to make
1288 // test_for dependencies work for modules that are split by the APEX
1289 // mutator, since test_for dependencies always go to the platform variant.
1290 // This doesn't happen for normal APEXes that are disjunct, so only do
1291 // this for the overlapping ART APEXes.
1292 // TODO(b/183882457): Remove this if the test_for functionality is
1293 // refactored to depend on the proper APEX variants instead of platform.
1294 mctx.CreateAliasVariation("", apexBundleName)
1295 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001296 } else if o, ok := mctx.Module().(*OverrideApex); ok {
1297 apexBundleName := o.GetOverriddenModuleName()
1298 if apexBundleName == "" {
1299 mctx.ModuleErrorf("base property is not set")
1300 return
1301 }
1302 mctx.CreateVariations(apexBundleName)
Martin Stjernholmec009002021-03-27 15:18:31 +00001303 if strings.HasPrefix(apexBundleName, "com.android.art") {
1304 // TODO(b/183882457): See note for CreateAliasVariation above.
1305 mctx.CreateAliasVariation("", apexBundleName)
1306 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001307 }
1308}
Sundong Ahne9b55722019-09-06 17:37:42 +09001309
Paul Duffin6717d882021-06-15 19:09:41 +01001310// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1311// variant.
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001312func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
Paul Duffin6717d882021-06-15 19:09:41 +01001313 if a, ok := module.(*apexBundle); ok {
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001314 // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
Paul Duffin6717d882021-06-15 19:09:41 +01001315 return !a.vndkApex
1316 }
1317
Martin Stjernholmbfffae72021-06-24 14:37:13 +01001318 return true
Paul Duffin6717d882021-06-15 19:09:41 +01001319}
1320
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001321// See android.UpdateDirectlyInAnyApex
1322// TODO(jiyong): move this to android/apex.go?
Colin Cross56a83212020-09-15 18:30:11 -07001323func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1324 if !mctx.Module().Enabled() {
1325 return
1326 }
1327 if am, ok := mctx.Module().(android.ApexModule); ok {
1328 android.UpdateDirectlyInAnyApex(mctx, am)
1329 }
1330}
1331
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001332// apexPackaging represents a specific packaging method for an APEX.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001333type apexPackaging int
1334
1335const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001336 // imageApex is a packaging method where contents are included in a filesystem image which
1337 // is then included in a zip container. This is the most typical way of packaging.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001338 imageApex apexPackaging = iota
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001339
1340 // zipApex is a packaging method where contents are directly included in the zip container.
1341 // This is used for host-side testing - because the contents are easily accessible by
1342 // unzipping the container.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001343 zipApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001344
1345 // flattendApex is a packaging method where contents are not included in the APEX file, but
1346 // installed to /apex/<apexname> directory on the device. This packaging method is used for
1347 // old devices where the filesystem-based APEX file can't be supported.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001348 flattenedApex
1349)
1350
1351const (
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001352 // File extensions of an APEX for different packaging methods
Samiul Islam7c02e262021-09-08 17:48:28 +01001353 imageApexSuffix = ".apex"
1354 imageCapexSuffix = ".capex"
1355 zipApexSuffix = ".zipapex"
1356 flattenedSuffix = ".flattened"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001357
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001358 // variant names each of which is for a packaging method
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001359 imageApexType = "image"
1360 zipApexType = "zip"
1361 flattenedApexType = "flattened"
1362
Dan Willemsen47e1a752021-10-16 18:36:13 -07001363 ext4FsType = "ext4"
1364 f2fsFsType = "f2fs"
Huang Jianan13cac632021-08-02 15:02:17 +08001365 erofsFsType = "erofs"
Jiyong Park8e6d52f2020-11-19 14:37:47 +09001366)
1367
1368// The suffix for the output "file", not the module
1369func (a apexPackaging) suffix() string {
1370 switch a {
1371 case imageApex:
1372 return imageApexSuffix
1373 case zipApex:
1374 return zipApexSuffix
1375 default:
1376 panic(fmt.Errorf("unknown APEX type %d", a))
1377 }
1378}
1379
1380func (a apexPackaging) name() string {
1381 switch a {
1382 case imageApex:
1383 return imageApexType
1384 case zipApex:
1385 return zipApexType
1386 default:
1387 panic(fmt.Errorf("unknown APEX type %d", a))
1388 }
1389}
1390
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001391// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1392// TODO(jiyong): give a better name to this mutator
Sundong Ahne9b55722019-09-06 17:37:42 +09001393func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
Jooyung Han49f67012020-04-17 13:43:10 +09001394 if !mctx.Module().Enabled() {
1395 return
1396 }
Sundong Ahne8fb7242019-09-17 13:50:45 +09001397 if ab, ok := mctx.Module().(*apexBundle); ok {
Sundong Ahnabb64432019-10-22 13:58:29 +09001398 var variants []string
1399 switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1400 case "image":
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001401 // This is the normal case. Note that both image and flattend APEXes are
1402 // created. The image type is installed to the system partition, while the
1403 // flattened APEX is (optionally) installed to the system_ext partition.
1404 // This is mostly for GSI which has to support wide range of devices. If GSI
1405 // is installed on a newer (APEX-capable) device, the image APEX in the
1406 // system will be used. However, if the same GSI is installed on an old
1407 // device which can't support image APEX, the flattened APEX in the
1408 // system_ext partion (which still is part of GSI) is used instead.
Sundong Ahnabb64432019-10-22 13:58:29 +09001409 variants = append(variants, imageApexType, flattenedApexType)
1410 case "zip":
1411 variants = append(variants, zipApexType)
1412 case "both":
1413 variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1414 default:
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001415 mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
Sundong Ahnabb64432019-10-22 13:58:29 +09001416 return
1417 }
1418
1419 modules := mctx.CreateLocalVariations(variants...)
1420
1421 for i, v := range variants {
1422 switch v {
1423 case imageApexType:
1424 modules[i].(*apexBundle).properties.ApexType = imageApex
1425 case zipApexType:
1426 modules[i].(*apexBundle).properties.ApexType = zipApex
1427 case flattenedApexType:
1428 modules[i].(*apexBundle).properties.ApexType = flattenedApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001429 // See the comment above for why system_ext.
Jooyung Han91df2082019-11-20 01:49:42 +09001430 if !mctx.Config().FlattenApex() && ab.Platform() {
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001431 modules[i].(*apexBundle).MakeAsSystemExt()
1432 }
Sundong Ahnabb64432019-10-22 13:58:29 +09001433 }
Sundong Ahne9b55722019-09-06 17:37:42 +09001434 }
Jiyong Park5d790c32019-11-15 18:40:32 +09001435 } else if _, ok := mctx.Module().(*OverrideApex); ok {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001436 // payload_type is forcibly overridden to "image"
1437 // TODO(jiyong): is this the right decision?
Jiyong Park5d790c32019-11-15 18:40:32 +09001438 mctx.CreateVariations(imageApexType, flattenedApexType)
Sundong Ahne9b55722019-09-06 17:37:42 +09001439 }
1440}
1441
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001442var _ android.DepIsInSameApex = (*apexBundle)(nil)
Theotime Combes4ba38c12020-06-12 12:46:59 +00001443
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001444// Implements android.DepInInSameApex
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001445func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001446 // direct deps of an APEX bundle are all part of the APEX bundle
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001447 // TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
Jiyong Parka7bc8ad2019-10-15 15:20:07 +09001448 return true
1449}
1450
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001451var _ android.OutputFileProducer = (*apexBundle)(nil)
1452
1453// Implements android.OutputFileProducer
1454func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1455 switch tag {
Paul Duffin74f05592020-11-25 16:37:46 +00001456 case "", android.DefaultDistTag:
1457 // This is the default dist path.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001458 return android.Paths{a.outputFile}, nil
Jooyung Hana6d36672022-02-24 13:58:07 +09001459 case imageApexSuffix:
1460 // uncompressed one
1461 if a.outputApexFile != nil {
1462 return android.Paths{a.outputApexFile}, nil
1463 }
1464 fallthrough
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001465 default:
1466 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1467 }
1468}
1469
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001470var _ multitree.Exportable = (*apexBundle)(nil)
1471
1472func (a *apexBundle) Exportable() bool {
1473 if a.properties.ApexType == flattenedApex {
1474 return false
1475 }
1476 return true
1477}
1478
1479func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1480 ret := make(map[string]android.Paths)
1481 ret["apex"] = android.Paths{a.outputFile}
1482 return ret
1483}
1484
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001485var _ cc.Coverage = (*apexBundle)(nil)
1486
1487// Implements cc.Coverage
1488func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1489 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1490}
1491
1492// Implements cc.Coverage
Ivan Lozanod7586b62021-04-01 09:49:36 -04001493func (a *apexBundle) SetPreventInstall() {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001494 a.properties.PreventInstall = true
1495}
1496
1497// Implements cc.Coverage
1498func (a *apexBundle) HideFromMake() {
1499 a.properties.HideFromMake = true
Colin Crosse6a83e62020-12-17 18:22:34 -08001500 // This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1501 // TODO(ccross): untangle these
1502 a.ModuleBase.HideFromMake()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001503}
1504
1505// Implements cc.Coverage
1506func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1507 a.properties.IsCoverageVariant = coverage
1508}
1509
1510// Implements cc.Coverage
1511func (a *apexBundle) EnableCoverageIfNeeded() {}
1512
1513var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1514
Oriol Prieto Gascoa07099d2021-10-14 15:33:41 -04001515// Implements android.ApexBundleDepsInfoIntf
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001516func (a *apexBundle) Updatable() bool {
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +00001517 return proptools.BoolDefault(a.properties.Updatable, true)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001518}
1519
Jiyong Parkf4020582021-11-29 12:37:10 +09001520func (a *apexBundle) FutureUpdatable() bool {
1521 return proptools.BoolDefault(a.properties.Future_updatable, false)
1522}
1523
Jiyong Park1bc84122021-06-22 20:23:05 +09001524func (a *apexBundle) UsePlatformApis() bool {
1525 return proptools.BoolDefault(a.properties.Platform_apis, false)
1526}
1527
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001528// getCertString returns the name of the cert that should be used to sign this APEX. This is
1529// basically from the "certificate" property, but could be overridden by the device config.
Colin Cross0ea8ba82019-06-06 14:33:29 -07001530func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
Jooyung Han27151d92019-12-16 17:45:32 +09001531 moduleName := ctx.ModuleName()
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001532 // VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1533 // OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1534 // overridden.
Jooyung Han27151d92019-12-16 17:45:32 +09001535 if a.vndkApex {
1536 moduleName = vndkApexName
1537 }
1538 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001539 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001540 return ":" + certificate
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001541 }
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07001542 return String(a.overridableProperties.Certificate)
Jiyong Parkb2742fd2019-02-11 11:38:15 +09001543}
1544
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001545// See the installable property
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001546func (a *apexBundle) installable() bool {
Jiyong Parkee9a98d2019-08-09 14:44:36 +09001547 return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
Jiyong Park92c0f9c2018-12-13 23:14:57 +09001548}
1549
Nikita Ioffeda6dc312021-06-09 19:43:46 +01001550// See the generate_hashtree property
1551func (a *apexBundle) shouldGenerateHashtree() bool {
Nikita Ioffee261ae62021-06-16 18:15:03 +01001552 return proptools.BoolDefault(a.properties.Generate_hashtree, true)
Nikita Ioffec72b5dd2019-12-07 17:30:22 +00001553}
1554
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001555// See the test_only_unsigned_payload property
Dario Frenica913392020-04-27 18:21:11 +01001556func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1557 return proptools.Bool(a.properties.Test_only_unsigned_payload)
1558}
1559
Mohammad Samiul Islama8008f92020-12-22 10:47:50 +00001560// See the test_only_force_compression property
1561func (a *apexBundle) testOnlyShouldForceCompression() bool {
1562 return proptools.Bool(a.properties.Test_only_force_compression)
1563}
1564
Dennis Shenaf41bc12022-08-03 16:46:43 +00001565// See the dynamic_common_lib_apex property
1566func (a *apexBundle) dynamic_common_lib_apex() bool {
1567 return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1568}
1569
Dennis Shene2ed70c2023-01-11 14:15:43 +00001570// See the list of libs to trim
1571func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string {
1572 dclaModules := ctx.GetDirectDepsWithTag(dclaTag)
1573 if len(dclaModules) > 1 {
1574 panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules)))
1575 }
1576 if len(dclaModules) > 0 {
1577 DCLAInfo := ctx.OtherModuleProvider(dclaModules[0], DCLAInfoProvider).(DCLAInfo)
1578 return DCLAInfo.ProvidedLibs
1579 }
1580 return []string{}
1581}
1582
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001583// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1584// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1585// sanitizers, extra dependencies can be forcibly added as well.
Jiyong Parkda6eb592018-12-19 17:12:36 +09001586
Jiyong Parkf97782b2019-02-13 20:28:58 +09001587func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1588 if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1589 a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1590 }
1591}
1592
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001593func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
Jiyong Parkf97782b2019-02-13 20:28:58 +09001594 if android.InList(sanitizerName, a.properties.SanitizerNames) {
1595 return true
Jiyong Park235e67c2019-02-09 11:50:56 +09001596 }
1597
1598 // Then follow the global setting
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07001599 var globalSanitizerNames []string
Jiyong Park388ef3f2019-01-28 19:47:32 +09001600 if a.Host() {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001601 globalSanitizerNames = config.SanitizeHost()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001602 } else {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001603 arches := config.SanitizeDeviceArch()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001604 if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
Lukacs T. Berki01a648a2022-06-17 08:59:37 +02001605 globalSanitizerNames = config.SanitizeDevice()
Jiyong Park388ef3f2019-01-28 19:47:32 +09001606 }
1607 }
1608 return android.InList(sanitizerName, globalSanitizerNames)
Jiyong Park379de2f2018-12-19 02:47:14 +09001609}
1610
Jooyung Han8ce8db92020-05-15 19:05:05 +09001611func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001612 // TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1613 // Keep only the mechanism here.
Jooyung Han8ce8db92020-05-15 19:05:05 +09001614 if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001615 imageVariation := a.getImageVariation(ctx)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001616 for _, target := range ctx.MultiTargets() {
1617 if target.Arch.ArchType.Multilib == "lib64" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001618 addDependenciesForNativeModules(ctx, ApexNativeDependencies{
Colin Cross4c4c1be2022-02-10 11:41:18 -08001619 Native_shared_libs: []string{"libclang_rt.hwasan"},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001620 Tests: nil,
1621 Jni_libs: nil,
1622 Binaries: nil,
1623 }, target, imageVariation)
Jooyung Han8ce8db92020-05-15 19:05:05 +09001624 break
1625 }
1626 }
1627 }
1628}
1629
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001630// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1631// returned apexFile saves information about the Soong module that will be used for creating the
1632// build rules.
Jiyong Park1833cef2019-12-13 13:28:36 +09001633func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001634 // Decide the APEX-local directory by the multilib of the library In the future, we may
1635 // query this to the module.
1636 // TODO(jiyong): use the new PackagingSpec
Jiyong Parkf653b052019-11-18 15:39:01 +09001637 var dirInApex string
Martin Stjernholm279de572019-09-10 23:18:20 +01001638 switch ccMod.Arch().ArchType.Multilib {
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001639 case "lib32":
1640 dirInApex = "lib"
1641 case "lib64":
1642 dirInApex = "lib64"
1643 }
Colin Cross3b19f5d2019-09-17 14:45:31 -07001644 if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
Martin Stjernholm279de572019-09-10 23:18:20 +01001645 dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001646 }
Jooyung Han35155c42020-02-06 17:33:20 +09001647 dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
Jiyong Park1833cef2019-12-13 13:28:36 +09001648 if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001649 // Special case for Bionic libs and other libs installed with them. This is to
1650 // prevent those libs from being included in the search path
1651 // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1652 // in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1653 // init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1654 // will be loaded into the default linker namespace (aka "platform" namespace). If
1655 // the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1656 // be loaded again into the runtime linker namespace, which will result in double
1657 // loading of them, which isn't supported.
Martin Stjernholm279de572019-09-10 23:18:20 +01001658 dirInApex = filepath.Join(dirInApex, "bionic")
Jiyong Parkb0788572018-12-20 22:10:17 +09001659 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001660
Colin Cross1d487152022-10-03 19:14:46 -07001661 fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
Yo Chiange8128052020-07-23 20:09:18 +08001662 androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1663 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001664}
1665
Jiyong Park1833cef2019-12-13 13:28:36 +09001666func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
Jooyung Han35155c42020-02-06 17:33:20 +09001667 dirInApex := "bin"
Colin Cross3b19f5d2019-09-17 14:45:31 -07001668 if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dimitry8d6dde82019-07-11 10:23:53 +02001669 dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
Jiyong Parkacbf6c72019-07-09 16:19:16 +09001670 }
Jooyung Han35155c42020-02-06 17:33:20 +09001671 dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
Colin Cross1d487152022-10-03 19:14:46 -07001672 fileToCopy := android.OutputFileForModule(ctx, cc, "")
Yo Chiange8128052020-07-23 20:09:18 +08001673 androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1674 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
Jiyong Parkf653b052019-11-18 15:39:01 +09001675 af.symlinks = cc.Symlinks()
Liz Kammer1c14a212020-05-12 15:26:55 -07001676 af.dataPaths = cc.DataPaths()
Jiyong Parkf653b052019-11-18 15:39:01 +09001677 return af
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001678}
1679
Jiyong Park99644e92020-11-17 22:21:02 +09001680func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1681 dirInApex := "bin"
1682 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1683 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1684 }
Colin Cross1d487152022-10-03 19:14:46 -07001685 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001686 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1687 af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1688 return af
1689}
1690
1691func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1692 // Decide the APEX-local directory by the multilib of the library
1693 // In the future, we may query this to the module.
1694 var dirInApex string
1695 switch rustm.Arch().ArchType.Multilib {
1696 case "lib32":
1697 dirInApex = "lib"
1698 case "lib64":
1699 dirInApex = "lib64"
1700 }
1701 if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1702 dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1703 }
Colin Cross1d487152022-10-03 19:14:46 -07001704 fileToCopy := android.OutputFileForModule(ctx, rustm, "")
Jiyong Park99644e92020-11-17 22:21:02 +09001705 androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1706 return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1707}
1708
Cole Faust4d247e62023-01-23 10:14:58 -08001709func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.PythonBinaryModule) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001710 dirInApex := "bin"
1711 fileToCopy := py.HostToolPath().Path()
Yo Chiange8128052020-07-23 20:09:18 +08001712 return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
Alex Light778127a2019-02-27 14:19:50 -08001713}
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001714
Jiyong Park1833cef2019-12-13 13:28:36 +09001715func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001716 dirInApex := "bin"
Colin Crossa44551f2021-10-25 15:36:21 -07001717 fileToCopy := android.PathForGoBinary(ctx, gb)
Jiyong Parkf653b052019-11-18 15:39:01 +09001718 // NB: Since go binaries are static we don't need the module for anything here, which is
1719 // good since the go tool is a blueprint.Module not an android.Module like we would
1720 // normally use.
Jiyong Park1833cef2019-12-13 13:28:36 +09001721 return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
Alex Light778127a2019-02-27 14:19:50 -08001722}
1723
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001724func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
Jiyong Parkf653b052019-11-18 15:39:01 +09001725 dirInApex := filepath.Join("bin", sh.SubDir())
Sundong Ahn80c04892021-11-23 00:57:19 +00001726 if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1727 dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1728 }
Jiyong Parkf653b052019-11-18 15:39:01 +09001729 fileToCopy := sh.OutputFile()
Yo Chiange8128052020-07-23 20:09:18 +08001730 af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
Jiyong Parkf653b052019-11-18 15:39:01 +09001731 af.symlinks = sh.Symlinks()
1732 return af
Jiyong Park04480cf2019-02-06 00:16:29 +09001733}
1734
Jaewoong Jung4b79e982020-06-01 10:45:49 -07001735func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
Jooyung Han0703fd82020-08-26 22:11:53 +09001736 dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
Jiyong Parkf653b052019-11-18 15:39:01 +09001737 fileToCopy := prebuilt.OutputFile()
Jiyong Park1833cef2019-12-13 13:28:36 +09001738 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
Jiyong Park48ca7dc2018-10-10 14:01:00 +09001739}
1740
atrost6e126252020-01-27 17:01:16 +00001741func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1742 dirInApex := filepath.Join("etc", config.SubDir())
1743 fileToCopy := config.CompatConfig()
1744 return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1745}
1746
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001747// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1748// way.
1749type javaModule interface {
1750 android.Module
1751 BaseModuleName() string
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001752 DexJarBuildPath() java.OptionalDexJarPath
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001753 JacocoReportClassesFile() android.Path
1754 LintDepSets() java.LintDepSets
1755 Stem() string
1756}
1757
1758var _ javaModule = (*java.Library)(nil)
Bill Peckhama41a6962021-01-11 10:58:54 -08001759var _ javaModule = (*java.Import)(nil)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001760var _ javaModule = (*java.SdkLibrary)(nil)
1761var _ javaModule = (*java.DexImport)(nil)
1762var _ javaModule = (*java.SdkLibraryImport)(nil)
1763
Paul Duffin190fdef2021-04-26 10:33:59 +01001764// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001765func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001766 return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
Paul Duffin190fdef2021-04-26 10:33:59 +01001767}
1768
1769// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1770func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001771 dirInApex := "javalib"
Paul Duffin190fdef2021-04-26 10:33:59 +01001772 af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001773 af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1774 af.lintDepSets = module.LintDepSets()
1775 af.customStem = module.Stem() + ".jar"
Jiakai Zhang519c5c82021-09-16 06:15:39 +00001776 if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1777 for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1778 af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1779 }
1780 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001781 return af
1782}
1783
1784// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1785// the same way.
1786type androidApp interface {
Jiyong Parkf653b052019-11-18 15:39:01 +09001787 android.Module
1788 Privileged() bool
Jooyung Han39ee1192020-03-23 20:21:11 +09001789 InstallApkName() string
Jiyong Parkf653b052019-11-18 15:39:01 +09001790 OutputFile() android.Path
Jiyong Park618922e2020-01-08 13:35:43 +09001791 JacocoReportClassesFile() android.Path
Colin Cross503c1d02020-01-28 14:00:53 -08001792 Certificate() java.Certificate
Yo Chiange8128052020-07-23 20:09:18 +08001793 BaseModuleName() string
Colin Cross8355c152021-08-10 19:24:07 -07001794 LintDepSets() java.LintDepSets
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001795}
1796
1797var _ androidApp = (*java.AndroidApp)(nil)
1798var _ androidApp = (*java.AndroidAppImport)(nil)
1799
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001800func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1801 buildId := ctx.Config().BuildId()
1802
1803 // The build ID is used as a suffix for a filename, so ensure that
1804 // the set of characters being used are sanitized.
1805 // - any word character: [a-zA-Z0-9_]
1806 // - dots: .
1807 // - dashes: -
1808 validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1809 if !validRegex.MatchString(buildId) {
1810 ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1811 }
1812 return buildId
1813}
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001814
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001815func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
Jiyong Parkf7487312019-10-17 12:54:30 +09001816 appDir := "app"
Jiyong Parkf653b052019-11-18 15:39:01 +09001817 if aapp.Privileged() {
Jiyong Parkf7487312019-10-17 12:54:30 +09001818 appDir = "priv-app"
1819 }
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001820
1821 // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1822 // so that PackageManager correctly invalidates the existing installed apk
1823 // in favour of the new APK-in-APEX. See bugs for more information.
Oriol Prieto Gasco17e22902022-05-05 13:52:25 +00001824 dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
Jiyong Parkf653b052019-11-18 15:39:01 +09001825 fileToCopy := aapp.OutputFile()
Jingwen Chen8ce1efc2022-04-19 13:57:01 +00001826
Yo Chiange8128052020-07-23 20:09:18 +08001827 af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
Jiyong Park618922e2020-01-08 13:35:43 +09001828 af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
Colin Cross8355c152021-08-10 19:24:07 -07001829 af.lintDepSets = aapp.LintDepSets()
Colin Cross503c1d02020-01-28 14:00:53 -08001830 af.certificate = aapp.Certificate()
Jiyong Parkcfaa1642020-02-28 16:51:07 +09001831
1832 if app, ok := aapp.(interface {
1833 OverriddenManifestPackageName() string
1834 }); ok {
1835 af.overriddenPackageName = app.OverriddenManifestPackageName()
1836 }
Jiyong Park618922e2020-01-08 13:35:43 +09001837 return af
Dario Frenicde2a032019-10-27 00:29:22 +01001838}
1839
Jiyong Park69aeba92020-04-24 21:16:36 +09001840func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1841 rroDir := "overlay"
1842 dirInApex := filepath.Join(rroDir, rro.Theme())
1843 fileToCopy := rro.OutputFile()
1844 af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1845 af.certificate = rro.Certificate()
1846
1847 if a, ok := rro.(interface {
1848 OverriddenManifestPackageName() string
1849 }); ok {
1850 af.overriddenPackageName = a.OverriddenManifestPackageName()
1851 }
1852 return af
1853}
1854
Ken Chenfad7f9d2021-11-10 22:02:57 +08001855func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1856 dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
markchien2f59ec92020-09-02 16:23:38 +08001857 return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1858}
1859
Jiyong Park12a719c2021-01-07 15:31:24 +09001860func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1861 dirInApex := filepath.Join("etc", "fs")
1862 return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1863}
1864
Paul Duffin064b70c2020-11-02 17:32:38 +00001865// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001866// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1867// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1868// modules. This is used in check* functions below.
Jooyung Han749dc692020-04-15 11:03:39 +09001869func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Paul Duffindf915ff2020-03-30 17:58:21 +01001870 ctx.WalkDeps(func(child, parent android.Module) bool {
Jiyong Park0f80c182020-01-31 02:49:53 +09001871 am, ok := child.(android.ApexModule)
1872 if !ok || !am.CanHaveApexVariants() {
1873 return false
1874 }
1875
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001876 // Filter-out unwanted depedendencies
1877 depTag := ctx.OtherModuleDependencyTag(child)
1878 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1879 return false
1880 }
Paul Duffin520917a2022-05-13 13:01:59 +00001881 if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
Martin Stjernholm58c33f02020-07-06 22:56:01 +01001882 return false
1883 }
1884
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001885 ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
Jiyong Parkab50b072021-05-12 17:13:56 +09001886 externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
Jiyong Park0f80c182020-01-31 02:49:53 +09001887
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001888 // Visit actually
1889 return do(ctx, parent, am, externalDep)
Jiyong Park0f80c182020-01-31 02:49:53 +09001890 })
1891}
1892
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001893// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1894type fsType int
Jooyung Han03b51852020-02-26 22:45:42 +09001895
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001896const (
1897 ext4 fsType = iota
1898 f2fs
Huang Jianan13cac632021-08-02 15:02:17 +08001899 erofs
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001900)
Artur Satayev849f8442020-04-28 14:57:42 +01001901
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001902func (f fsType) string() string {
1903 switch f {
1904 case ext4:
1905 return ext4FsType
1906 case f2fs:
1907 return f2fsFsType
Huang Jianan13cac632021-08-02 15:02:17 +08001908 case erofs:
1909 return erofsFsType
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09001910 default:
1911 panic(fmt.Errorf("unknown APEX payload type %d", f))
Jooyung Han548640b2020-04-27 12:10:30 +09001912 }
1913}
1914
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001915var _ android.MixedBuildBuildable = (*apexBundle)(nil)
1916
1917func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
1918 return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex
1919}
1920
1921func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
1922 bazelCtx := ctx.Config().BazelContext
1923 bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
1924}
1925
Jingwen Chen889f2f22022-12-16 08:16:01 +00001926// GetBazelLabel returns the bazel label of this apexBundle, or the label of the
1927// override_apex module overriding this apexBundle. An apexBundle can be
1928// overridden by different override_apex modules (e.g. Google or Go variants),
1929// which is handled by the overrides mutators.
1930func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string {
1931 if _, ok := ctx.Module().(android.OverridableModule); ok {
1932 return android.MaybeBp2buildLabelOfOverridingModule(ctx)
1933 }
1934 return a.BazelModuleBase.GetBazelLabel(ctx, a)
1935}
1936
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001937func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
1938 if !a.commonBuildActions(ctx) {
1939 return
1940 }
1941
1942 a.setApexTypeAndSuffix(ctx)
1943 a.setPayloadFsType(ctx)
1944 a.setSystemLibLink(ctx)
1945
1946 if a.properties.ApexType != zipApex {
1947 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
1948 }
1949
1950 bazelCtx := ctx.Config().BazelContext
1951 outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
1952 if err != nil {
1953 ctx.ModuleErrorf(err.Error())
1954 return
1955 }
1956 a.installDir = android.PathForModuleInstall(ctx, "apex")
Jingwen Chen94098e82023-01-10 14:50:42 +00001957
1958 // Set the output file to .apex or .capex depending on the compression configuration.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001959 a.setCompression(ctx)
Jingwen Chen94098e82023-01-10 14:50:42 +00001960 if a.isCompressed {
1961 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedCompressedOutput)
1962 } else {
1963 a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
1964 }
1965 a.outputFile = a.outputApexFile
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001966
Liz Kammer0e255ef2022-11-04 16:07:04 -04001967 // TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
1968 // interface if these were set in a provider rather than the module itself
Wei Li32dcdf92022-10-26 22:30:48 -07001969 a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[0])
1970 a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyInfo[1])
1971 a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
1972 a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
Liz Kammer0e255ef2022-11-04 16:07:04 -04001973
Jingwen Chen29743c82023-01-25 17:49:46 +00001974 // Ensure ApexMkInfo.install_to_system make module names are installed as
1975 // part of a bundled build.
1976 a.makeModulesToInstall = append(a.makeModulesToInstall, outputs.MakeModulesToInstall...)
Vinh Tranb6803a52022-12-14 11:34:54 -05001977
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001978 apexType := a.properties.ApexType
1979 switch apexType {
1980 case imageApex:
Liz Kammer303978d2022-11-04 16:12:43 -04001981 a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001982 a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
Wei Licc73a052022-11-07 14:25:34 -08001983 a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
Jingwen Chen0c9a2762022-11-04 09:40:47 +00001984 // TODO(b/239084755): Generate the java api using.xml file from Bazel.
Jingwen Chen1ec77852022-11-07 14:36:12 +00001985 a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
Wei Li78c07de2022-11-08 16:01:05 -08001986 a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07001987 installSuffix := imageApexSuffix
1988 if a.isCompressed {
1989 installSuffix = imageCapexSuffix
1990 }
1991 a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
1992 a.compatSymlinks.Paths()...)
1993 default:
1994 panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType))
1995 }
1996
1997 /*
1998 TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not
1999 return filesInfo and requiredDeps fields (in the Soong build the latter is updated).
2000 Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go
2001 To find out what Soong build puts there, run:
2002 vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
2003 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
2004 return a.depVisitor(&vctx, ctx, child, parent)
2005 })
2006 vctx.normalizeFileInfo()
2007 */
2008
2009}
2010
2011func (a *apexBundle) setCompression(ctx android.ModuleContext) {
2012 if a.properties.ApexType != imageApex {
2013 a.isCompressed = false
2014 } else if a.testOnlyShouldForceCompression() {
2015 a.isCompressed = true
2016 } else {
2017 a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
2018 }
2019}
2020
2021func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
2022 // Optimization. If we are building bundled APEX, for the files that are gathered due to the
2023 // transitive dependencies, don't place them inside the APEX, but place a symlink pointing
2024 // the same library in the system partition, thus effectively sharing the same libraries
2025 // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
2026 // in the APEX.
2027 a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
2028
2029 // APEXes targeting other than system/system_ext partitions use vendor/product variants.
2030 // So we can't link them to /system/lib libs which are core variants.
2031 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2032 a.linkToSystemLib = false
2033 }
2034
2035 forced := ctx.Config().ForceApexSymlinkOptimization()
2036 updatable := a.Updatable() || a.FutureUpdatable()
2037
2038 // We don't need the optimization for updatable APEXes, as it might give false signal
2039 // to the system health when the APEXes are still bundled (b/149805758).
2040 if !forced && updatable && a.properties.ApexType == imageApex {
2041 a.linkToSystemLib = false
2042 }
2043
2044 // We also don't want the optimization for host APEXes, because it doesn't make sense.
2045 if ctx.Host() {
2046 a.linkToSystemLib = false
2047 }
2048}
2049
2050func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
2051 switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
2052 case ext4FsType:
2053 a.payloadFsType = ext4
2054 case f2fsFsType:
2055 a.payloadFsType = f2fs
2056 case erofsFsType:
2057 a.payloadFsType = erofs
2058 default:
2059 ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
2060 }
2061}
2062
2063func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
2064 // Set suffix and primaryApexType depending on the ApexType
2065 buildFlattenedAsDefault := ctx.Config().FlattenApex()
2066 switch a.properties.ApexType {
2067 case imageApex:
2068 if buildFlattenedAsDefault {
2069 a.suffix = imageApexSuffix
2070 } else {
2071 a.suffix = ""
2072 a.primaryApexType = true
2073
2074 if ctx.Config().InstallExtraFlattenedApexes() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002075 a.makeModulesToInstall = append(a.makeModulesToInstall, a.Name()+flattenedSuffix)
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002076 }
2077 }
2078 case zipApex:
2079 if proptools.String(a.properties.Payload_type) == "zip" {
2080 a.suffix = ""
2081 a.primaryApexType = true
2082 } else {
2083 a.suffix = zipApexSuffix
2084 }
2085 case flattenedApex:
2086 if buildFlattenedAsDefault {
2087 a.suffix = ""
2088 a.primaryApexType = true
2089 } else {
2090 a.suffix = flattenedSuffix
2091 }
2092 }
2093}
2094
2095func (a apexBundle) isCompressable() bool {
2096 return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
2097}
2098
2099func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
2100 a.checkApexAvailability(ctx)
2101 a.checkUpdatable(ctx)
2102 a.CheckMinSdkVersion(ctx)
2103 a.checkStaticLinkingToStubLibraries(ctx)
2104 a.checkStaticExecutables(ctx)
2105 if len(a.properties.Tests) > 0 && !a.testApex {
2106 ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
2107 return false
2108 }
2109 return true
2110}
2111
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002112type visitorContext struct {
2113 // all the files that will be included in this APEX
2114 filesInfo []apexFile
2115
2116 // native lib dependencies
2117 provideNativeLibs []string
2118 requireNativeLibs []string
2119
2120 handleSpecialLibs bool
Jooyung Han862c0d62022-12-21 10:15:37 +09002121
2122 // if true, raise error on duplicate apexFile
2123 checkDuplicate bool
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002124}
2125
Jooyung Han862c0d62022-12-21 10:15:37 +09002126func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002127 encountered := make(map[string]apexFile)
2128 for _, f := range vctx.filesInfo {
2129 dest := filepath.Join(f.installDir, f.builtFile.Base())
2130 if e, ok := encountered[dest]; !ok {
2131 encountered[dest] = f
2132 } else {
Jooyung Han862c0d62022-12-21 10:15:37 +09002133 if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
2134 mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
2135 dest, e.builtFile, f.builtFile)
2136 return
2137 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002138 // If a module is directly included and also transitively depended on
2139 // consider it as directly included.
2140 e.transitiveDep = e.transitiveDep && f.transitiveDep
2141 encountered[dest] = e
2142 }
2143 }
2144 vctx.filesInfo = vctx.filesInfo[:0]
2145 for _, v := range encountered {
2146 vctx.filesInfo = append(vctx.filesInfo, v)
2147 }
2148 sort.Slice(vctx.filesInfo, func(i, j int) bool {
2149 // Sort by destination path so as to ensure consistent ordering even if the source of the files
2150 // changes.
2151 return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
2152 })
2153}
2154
2155func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
2156 depTag := ctx.OtherModuleDependencyTag(child)
2157 if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2158 return false
2159 }
2160 if mod, ok := child.(android.Module); ok && !mod.Enabled() {
2161 return false
2162 }
2163 depName := ctx.OtherModuleName(child)
2164 if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2165 switch depTag {
2166 case sharedLibTag, jniLibTag:
2167 isJniLib := depTag == jniLibTag
2168 switch ch := child.(type) {
2169 case *cc.Module:
2170 fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2171 fi.isJniLib = isJniLib
2172 vctx.filesInfo = append(vctx.filesInfo, fi)
2173 // Collect the list of stub-providing libs except:
2174 // - VNDK libs are only for vendors
2175 // - bootstrap bionic libs are treated as provided by system
2176 if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
2177 vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
2178 }
2179 return true // track transitive dependencies
2180 case *rust.Module:
2181 fi := apexFileForRustLibrary(ctx, ch)
2182 fi.isJniLib = isJniLib
2183 vctx.filesInfo = append(vctx.filesInfo, fi)
2184 return true // track transitive dependencies
2185 default:
2186 propertyName := "native_shared_libs"
2187 if isJniLib {
2188 propertyName = "jni_libs"
2189 }
2190 ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2191 }
2192 case executableTag:
2193 switch ch := child.(type) {
2194 case *cc.Module:
2195 vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
2196 return true // track transitive dependencies
Cole Faust4d247e62023-01-23 10:14:58 -08002197 case *python.PythonBinaryModule:
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002198 if ch.HostToolPath().Valid() {
2199 vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
2200 }
2201 case bootstrap.GoBinaryTool:
2202 if a.Host() {
2203 vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
2204 }
2205 case *rust.Module:
2206 vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
2207 return true // track transitive dependencies
2208 default:
2209 ctx.PropertyErrorf("binaries",
2210 "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
2211 }
2212 case shBinaryTag:
2213 if csh, ok := child.(*sh.ShBinary); ok {
2214 vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
2215 } else {
2216 ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
2217 }
2218 case bcpfTag:
2219 bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
2220 if !ok {
2221 ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
2222 return false
2223 }
2224
2225 vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
2226 for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
Jingwen Chen29743c82023-01-25 17:49:46 +00002227 a.makeModulesToInstall = append(a.makeModulesToInstall, makeModuleName)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002228 }
2229 return true
2230 case sscpfTag:
2231 if _, ok := child.(*java.SystemServerClasspathModule); !ok {
2232 ctx.PropertyErrorf("systemserverclasspath_fragments",
2233 "%q is not a systemserverclasspath_fragment module", depName)
2234 return false
2235 }
2236 if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
2237 vctx.filesInfo = append(vctx.filesInfo, *af)
2238 }
2239 return true
2240 case javaLibTag:
2241 switch child.(type) {
2242 case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
2243 af := apexFileForJavaModule(ctx, child.(javaModule))
2244 if !af.ok() {
2245 ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2246 return false
2247 }
2248 vctx.filesInfo = append(vctx.filesInfo, af)
2249 return true // track transitive dependencies
2250 default:
2251 ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2252 }
2253 case androidAppTag:
2254 switch ap := child.(type) {
2255 case *java.AndroidApp:
2256 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2257 return true // track transitive dependencies
2258 case *java.AndroidAppImport:
2259 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2260 case *java.AndroidTestHelperApp:
2261 vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
2262 case *java.AndroidAppSet:
2263 appDir := "app"
2264 if ap.Privileged() {
2265 appDir = "priv-app"
2266 }
2267 // TODO(b/224589412, b/226559955): Ensure that the dirname is
2268 // suffixed so that PackageManager correctly invalidates the
2269 // existing installed apk in favour of the new APK-in-APEX.
2270 // See bugs for more information.
2271 appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
2272 af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
2273 af.certificate = java.PresignedCertificate
2274 vctx.filesInfo = append(vctx.filesInfo, af)
2275 default:
2276 ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2277 }
2278 case rroTag:
2279 if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2280 vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2281 } else {
2282 ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2283 }
2284 case bpfTag:
2285 if bpfProgram, ok := child.(bpf.BpfModule); ok {
2286 filesToCopy, _ := bpfProgram.OutputFiles("")
2287 apex_sub_dir := bpfProgram.SubDir()
2288 for _, bpfFile := range filesToCopy {
2289 vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2290 }
2291 } else {
2292 ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2293 }
2294 case fsTag:
2295 if fs, ok := child.(filesystem.Filesystem); ok {
2296 vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2297 } else {
2298 ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2299 }
2300 case prebuiltTag:
2301 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2302 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2303 } else {
2304 ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2305 }
2306 case compatConfigTag:
2307 if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2308 vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2309 } else {
2310 ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2311 }
2312 case testTag:
2313 if ccTest, ok := child.(*cc.Module); ok {
2314 if ccTest.IsTestPerSrcAllTestsVariation() {
2315 // Multiple-output test module (where `test_per_src: true`).
2316 //
2317 // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2318 // We do not add this variation to `filesInfo`, as it has no output;
2319 // however, we do add the other variations of this module as indirect
2320 // dependencies (see below).
2321 } else {
2322 // Single-output test module (where `test_per_src: false`).
2323 af := apexFileForExecutable(ctx, ccTest)
2324 af.class = nativeTest
2325 vctx.filesInfo = append(vctx.filesInfo, af)
2326 }
2327 return true // track transitive dependencies
2328 } else {
2329 ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2330 }
2331 case keyTag:
2332 if key, ok := child.(*apexKey); ok {
2333 a.privateKeyFile = key.privateKeyFile
2334 a.publicKeyFile = key.publicKeyFile
2335 } else {
2336 ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2337 }
2338 case certificateTag:
2339 if dep, ok := child.(*java.AndroidAppCertificate); ok {
2340 a.containerCertificateFile = dep.Certificate.Pem
2341 a.containerPrivateKeyFile = dep.Certificate.Key
2342 } else {
2343 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2344 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002345 }
2346 return false
2347 }
2348
2349 if a.vndkApex {
2350 return false
2351 }
2352
2353 // indirect dependencies
2354 am, ok := child.(android.ApexModule)
2355 if !ok {
2356 return false
2357 }
2358 // We cannot use a switch statement on `depTag` here as the checked
2359 // tags used below are private (e.g. `cc.sharedDepTag`).
2360 if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2361 if ch, ok := child.(*cc.Module); ok {
2362 if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
2363 vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
2364 return false
2365 }
2366 af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2367 af.transitiveDep = true
2368
2369 // Always track transitive dependencies for host.
2370 if a.Host() {
2371 vctx.filesInfo = append(vctx.filesInfo, af)
2372 return true
2373 }
2374
2375 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2376 if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
2377 // If the dependency is a stubs lib, don't include it in this APEX,
2378 // but make sure that the lib is installed on the device.
2379 // In case no APEX is having the lib, the lib is installed to the system
2380 // partition.
2381 //
2382 // Always include if we are a host-apex however since those won't have any
2383 // system libraries.
Colin Crossdf2043e2023-01-26 15:39:15 -08002384 //
2385 // Skip the dependency in unbundled builds where the device image is not
2386 // being built.
2387 if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() && !ctx.Config().UnbundledBuild() {
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002388 // we need a module name for Make
2389 name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
Jingwen Chen29743c82023-01-25 17:49:46 +00002390 if !android.InList(name, a.makeModulesToInstall) {
2391 a.makeModulesToInstall = append(a.makeModulesToInstall, name)
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002392 }
2393 }
2394 vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2395 // Don't track further
2396 return false
2397 }
2398
2399 // If the dep is not considered to be in the same
2400 // apex, don't add it to filesInfo so that it is not
2401 // included in this APEX.
2402 // TODO(jiyong): move this to at the top of the
2403 // else-if clause for the indirect dependencies.
2404 // Currently, that's impossible because we would
2405 // like to record requiredNativeLibs even when
2406 // DepIsInSameAPex is false. We also shouldn't do
2407 // this for host.
2408 //
2409 // TODO(jiyong): explain why the same module is passed in twice.
2410 // Switching the first am to parent breaks lots of tests.
2411 if !android.IsDepInSameApex(ctx, am, am) {
2412 return false
2413 }
2414
2415 vctx.filesInfo = append(vctx.filesInfo, af)
2416 return true // track transitive dependencies
2417 } else if rm, ok := child.(*rust.Module); ok {
2418 af := apexFileForRustLibrary(ctx, rm)
2419 af.transitiveDep = true
2420 vctx.filesInfo = append(vctx.filesInfo, af)
2421 return true // track transitive dependencies
2422 }
2423 } else if cc.IsTestPerSrcDepTag(depTag) {
2424 if ch, ok := child.(*cc.Module); ok {
2425 af := apexFileForExecutable(ctx, ch)
2426 // Handle modules created as `test_per_src` variations of a single test module:
2427 // use the name of the generated test binary (`fileToCopy`) instead of the name
2428 // of the original test module (`depName`, shared by all `test_per_src`
2429 // variations of that module).
2430 af.androidMkModuleName = filepath.Base(af.builtFile.String())
2431 // these are not considered transitive dep
2432 af.transitiveDep = false
2433 vctx.filesInfo = append(vctx.filesInfo, af)
2434 return true // track transitive dependencies
2435 }
2436 } else if cc.IsHeaderDepTag(depTag) {
2437 // nothing
2438 } else if java.IsJniDepTag(depTag) {
2439 // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2440 } else if java.IsXmlPermissionsFileDepTag(depTag) {
2441 if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2442 vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2443 }
2444 } else if rust.IsDylibDepTag(depTag) {
2445 if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2446 af := apexFileForRustLibrary(ctx, rustm)
2447 af.transitiveDep = true
2448 vctx.filesInfo = append(vctx.filesInfo, af)
2449 return true // track transitive dependencies
2450 }
2451 } else if rust.IsRlibDepTag(depTag) {
2452 // Rlib is statically linked, but it might have shared lib
2453 // dependencies. Track them.
2454 return true
2455 } else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2456 // Add the contents of the bootclasspath fragment to the apex.
2457 switch child.(type) {
2458 case *java.Library, *java.SdkLibrary:
2459 javaModule := child.(javaModule)
2460 af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2461 if !af.ok() {
2462 ctx.PropertyErrorf("bootclasspath_fragments",
2463 "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2464 return false
2465 }
2466 vctx.filesInfo = append(vctx.filesInfo, af)
2467 return true // track transitive dependencies
2468 default:
2469 ctx.PropertyErrorf("bootclasspath_fragments",
2470 "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2471 }
2472 } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2473 // Add the contents of the systemserverclasspath fragment to the apex.
2474 switch child.(type) {
2475 case *java.Library, *java.SdkLibrary:
2476 af := apexFileForJavaModule(ctx, child.(javaModule))
2477 vctx.filesInfo = append(vctx.filesInfo, af)
2478 return true // track transitive dependencies
2479 default:
2480 ctx.PropertyErrorf("systemserverclasspath_fragments",
2481 "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2482 }
2483 } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
2484 // nothing
2485 } else if depTag == android.DarwinUniversalVariantTag {
2486 // nothing
2487 } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2488 ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2489 }
2490 return false
2491}
2492
Jooyung Han862c0d62022-12-21 10:15:37 +09002493func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
2494 // TODO(b/263308293) remove this
2495 if a.properties.IsCoverageVariant {
2496 return false
2497 }
2498 // TODO(b/263308515) remove this
2499 if a.testApex {
2500 return false
2501 }
2502 // TODO(b/263309864) remove this
2503 if a.Host() {
2504 return false
2505 }
2506 if a.Device() && ctx.DeviceConfig().DeviceArch() == "" {
2507 return false
2508 }
2509 return true
2510}
2511
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002512// Creates build rules for an APEX. It consists of the following major steps:
2513//
2514// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2515// 2) traverse the dependency tree to collect apexFile structs from them.
2516// 3) some fields in apexBundle struct are configured
2517// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002518func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002519 ////////////////////////////////////////////////////////////////////////////////////////////
2520 // 1) do some validity checks such as apex_available, min_sdk_version, etc.
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002521 if !a.commonBuildActions(ctx) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002522 return
2523 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002524 ////////////////////////////////////////////////////////////////////////////////////////////
2525 // 2) traverse the dependency tree to collect apexFile structs from them.
braleeb0c1f0c2021-06-07 22:49:13 +08002526 // Collect the module directory for IDE info in java/jdeps.go.
2527 a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
2528
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002529 // TODO(jiyong): do this using WalkPayloadDeps
2530 // TODO(jiyong): make this clean!!!
Jooyung Han862c0d62022-12-21 10:15:37 +09002531 vctx := visitorContext{
2532 handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case),
2533 checkDuplicate: a.shouldCheckDuplicate(ctx),
2534 }
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002535 ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
Jooyung Han862c0d62022-12-21 10:15:37 +09002536 vctx.normalizeFileInfo(ctx)
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002537 if a.privateKeyFile == nil {
Jaewoong Jung4cfdf7d2021-04-20 16:21:24 -07002538 ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002539 return
2540 }
Jiyong Park48ca7dc2018-10-10 14:01:00 +09002541
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002542 ////////////////////////////////////////////////////////////////////////////////////////////
2543 // 3) some fields in apexBundle struct are configured
Jiyong Park8fd61922018-11-08 02:50:25 +09002544 a.installDir = android.PathForModuleInstall(ctx, "apex")
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002545 a.filesInfo = vctx.filesInfo
Alex Light5098a612018-11-29 17:12:15 -08002546
Sasha Smundakfe9a5b82022-07-27 14:51:45 -07002547 a.setApexTypeAndSuffix(ctx)
2548 a.setPayloadFsType(ctx)
2549 a.setSystemLibLink(ctx)
Colin Cross6340ea52021-11-04 12:01:18 -07002550 if a.properties.ApexType != zipApex {
2551 a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
2552 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002553
2554 ////////////////////////////////////////////////////////////////////////////////////////////
2555 // 4) generate the build rules to create the APEX. This is done in builder.go.
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002556 a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
Jooyung Han01a3ee22019-11-02 02:52:25 +09002557 if a.properties.ApexType == flattenedApex {
2558 a.buildFlattenedApex(ctx)
2559 } else {
2560 a.buildUnflattenedApex(ctx)
2561 }
Jiyong Park956305c2020-01-09 12:32:06 +09002562 a.buildApexDependencyInfo(ctx)
Colin Cross08dca382020-07-21 20:31:17 -07002563 a.buildLintReports(ctx)
Jiyong Parkb81b9902020-11-24 19:51:18 +09002564
2565 // Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2566 if a.installable() {
2567 // For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2568 // along with other ordinary files. (Note that this is done by apexer for
2569 // non-flattened APEXes)
2570 a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2571
2572 // Place the public key as apex_pubkey. This is also done by apexer for
2573 // non-flattened APEXes case.
2574 // TODO(jiyong): Why do we need this CP rule?
2575 copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2576 ctx.Build(pctx, android.BuildParams{
2577 Rule: android.Cp,
Jaewoong Jung18aefc12020-12-21 09:11:10 -08002578 Input: a.publicKeyFile,
Jiyong Parkb81b9902020-11-24 19:51:18 +09002579 Output: copiedPubkey,
2580 })
2581 a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2582 }
Jooyung Han01a3ee22019-11-02 02:52:25 +09002583}
2584
Paul Duffincc33ec82021-04-25 23:14:55 +01002585// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2586// the bootclasspath_fragment contributes to the apex.
2587func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2588 bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2589 var filesToAdd []apexFile
2590
2591 // Add the boot image files, e.g. .art, .oat and .vdex files.
Jiakai Zhang6decef92022-01-12 17:56:19 +00002592 if bootclasspathFragmentInfo.ShouldInstallBootImageInApex() {
2593 for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2594 dirInApex := filepath.Join("javalib", arch.String())
2595 for _, f := range files {
2596 androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2597 // TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2598 af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2599 filesToAdd = append(filesToAdd, af)
2600 }
Paul Duffincc33ec82021-04-25 23:14:55 +01002601 }
2602 }
2603
satayev3db35472021-05-06 23:59:58 +01002604 // Add classpaths.proto config.
satayevb98371c2021-06-15 16:49:50 +01002605 if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2606 filesToAdd = append(filesToAdd, *af)
2607 }
satayev3db35472021-05-06 23:59:58 +01002608
Ulya Trafimovichf5c548d2022-11-16 14:52:41 +00002609 pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2610 if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
Jiakai Zhang49b1eb62021-11-26 18:09:27 +00002611 pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2612 tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2613
2614 if pathOnHost != nil {
2615 // We need to copy the profile to a temporary path with the right filename because the apexer
2616 // will take the filename as is.
2617 ctx.Build(pctx, android.BuildParams{
2618 Rule: android.Cp,
2619 Input: pathOnHost,
2620 Output: tempPath,
2621 })
2622 } else {
2623 // At this point, the boot image profile cannot be generated. It is probably because the boot
2624 // image profile source file does not exist on the branch, or it is not available for the
2625 // current build target.
2626 // However, we cannot enforce the boot image profile to be generated because some build
2627 // targets (such as module SDK) do not need it. It is only needed when the APEX is being
2628 // built. Therefore, we create an error rule so that an error will occur at the ninja phase
2629 // only if the APEX is being built.
2630 ctx.Build(pctx, android.BuildParams{
2631 Rule: android.ErrorRule,
2632 Output: tempPath,
2633 Args: map[string]string{
2634 "error": "Boot image profile cannot be generated",
2635 },
2636 })
2637 }
2638
2639 androidMkModuleName := filepath.Base(pathInApex)
2640 af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2641 filesToAdd = append(filesToAdd, af)
2642 }
2643
Paul Duffincc33ec82021-04-25 23:14:55 +01002644 return filesToAdd
2645}
2646
satayevb98371c2021-06-15 16:49:50 +01002647// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2648// the module contributes to the apex; or nil if the proto config was not generated.
2649func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2650 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2651 if !info.ClasspathFragmentProtoGenerated {
2652 return nil
2653 }
2654 classpathProtoOutput := info.ClasspathFragmentProtoOutput
2655 af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2656 return &af
satayev14e49132021-05-17 21:03:07 +01002657}
2658
Paul Duffincc33ec82021-04-25 23:14:55 +01002659// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2660// content module, i.e. a library that is part of the bootclasspath.
Paul Duffin190fdef2021-04-26 10:33:59 +01002661func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2662 bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2663
2664 // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2665 // hidden API encpding.
Paul Duffin1a8010a2021-05-15 12:39:23 +01002666 dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2667 if err != nil {
2668 ctx.ModuleErrorf("%s", err)
2669 }
Paul Duffin190fdef2021-04-26 10:33:59 +01002670
2671 // Create an apexFile as for a normal java module but with the dex boot jar provided by the
2672 // bootclasspath_fragment.
2673 af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2674 return af
Paul Duffincc33ec82021-04-25 23:14:55 +01002675}
2676
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002677///////////////////////////////////////////////////////////////////////////////////////////////////
2678// Factory functions
2679//
2680
2681func newApexBundle() *apexBundle {
2682 module := &apexBundle{}
2683
2684 module.AddProperties(&module.properties)
2685 module.AddProperties(&module.targetProperties)
Jiyong Park59140302020-12-14 18:44:04 +09002686 module.AddProperties(&module.archProperties)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002687 module.AddProperties(&module.overridableProperties)
2688
2689 android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2690 android.InitDefaultableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002691 android.InitOverridableModule(module, &module.overridableProperties.Overrides)
Jingwen Chenf59a8e12021-07-16 09:28:53 +00002692 android.InitBazelModule(module)
Inseob Kim5eb7ee92022-04-27 10:30:34 +09002693 multitree.InitExportableModule(module)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002694 return module
2695}
2696
Paul Duffineb8051d2021-10-18 17:49:39 +01002697func ApexBundleFactory(testApex bool) android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002698 bundle := newApexBundle()
2699 bundle.testApex = testApex
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002700 return bundle
2701}
2702
2703// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2704// certain compatibility checks such as apex_available are not done for apex_test.
Yu Liu4c212ce2022-10-14 12:20:20 -07002705func TestApexBundleFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002706 bundle := newApexBundle()
2707 bundle.testApex = true
2708 return bundle
2709}
2710
2711// apex packages other modules into an APEX file which is a packaging format for system-level
2712// components like binaries, shared libraries, etc.
2713func BundleFactory() android.Module {
2714 return newApexBundle()
2715}
2716
2717type Defaults struct {
2718 android.ModuleBase
2719 android.DefaultsModuleBase
2720}
2721
2722// apex_defaults provides defaultable properties to other apex modules.
2723func defaultsFactory() android.Module {
2724 return DefaultsFactory()
2725}
2726
2727func DefaultsFactory(props ...interface{}) android.Module {
2728 module := &Defaults{}
2729
2730 module.AddProperties(props...)
2731 module.AddProperties(
2732 &apexBundleProperties{},
2733 &apexTargetBundleProperties{},
Nikita Ioffee58f5272022-10-24 17:24:38 +01002734 &apexArchBundleProperties{},
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002735 &overridableProperties{},
2736 )
2737
2738 android.InitDefaultsModule(module)
2739 return module
2740}
2741
2742type OverrideApex struct {
2743 android.ModuleBase
2744 android.OverrideModuleBase
Wei Li1c66fc72022-05-09 23:59:14 -07002745 android.BazelModuleBase
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002746}
2747
Sasha Smundak6f9e91d2022-06-28 22:43:04 -07002748func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002749 // All the overrides happen in the base module.
2750}
2751
2752// override_apex is used to create an apex module based on another apex module by overriding some of
2753// its properties.
Wei Li1c66fc72022-05-09 23:59:14 -07002754func OverrideApexFactory() android.Module {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002755 m := &OverrideApex{}
2756
2757 m.AddProperties(&overridableProperties{})
2758
2759 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2760 android.InitOverrideModule(m)
Wei Li1c66fc72022-05-09 23:59:14 -07002761 android.InitBazelModule(m)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002762 return m
2763}
2764
Wei Li1c66fc72022-05-09 23:59:14 -07002765func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
2766 if ctx.ModuleType() != "override_apex" {
2767 return
2768 }
2769
2770 baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName()
2771 baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName)
2772 if !baseApexExists {
2773 panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName))
2774 }
2775
2776 a, baseModuleIsApex := baseModule.(*apexBundle)
2777 if !baseModuleIsApex {
2778 panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
2779 }
2780 attrs, props := convertWithBp2build(a, ctx)
2781
Jingwen Chenc4c34e12022-11-29 12:07:45 +00002782 // We just want the name, not module reference.
2783 baseApexName := strings.TrimPrefix(baseApexModuleName, ":")
2784 attrs.Base_apex_name = &baseApexName
2785
Wei Li1c66fc72022-05-09 23:59:14 -07002786 for _, p := range o.GetProperties() {
2787 overridableProperties, ok := p.(*overridableProperties)
2788 if !ok {
2789 continue
2790 }
Wei Li40f98732022-05-20 22:08:11 -07002791
2792 // Manifest is either empty or a file in the directory of base APEX and is not overridable.
2793 // After it is converted in convertWithBp2build(baseApex, ctx),
2794 // the attrs.Manifest.Value.Label is the file path relative to the directory
2795 // of base apex. So the following code converts it to a label that looks like
2796 // <package of base apex>:<path of manifest file> if base apex and override
2797 // apex are not in the same package.
2798 baseApexPackage := ctx.OtherModuleDir(a)
2799 overrideApexPackage := ctx.ModuleDir()
2800 if baseApexPackage != overrideApexPackage {
2801 attrs.Manifest.Value.Label = "//" + baseApexPackage + ":" + attrs.Manifest.Value.Label
2802 }
2803
Wei Li1c66fc72022-05-09 23:59:14 -07002804 // Key
2805 if overridableProperties.Key != nil {
2806 attrs.Key = bazel.LabelAttribute{}
2807 attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key))
2808 }
2809
2810 // Certificate
Jingwen Chenbea58092022-09-29 16:56:02 +00002811 if overridableProperties.Certificate == nil {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002812 // If overridableProperties.Certificate is nil, clear this out as
2813 // well with zeroed structs, so the override_apex does not use the
2814 // base apex's certificate.
2815 attrs.Certificate = bazel.LabelAttribute{}
2816 attrs.Certificate_name = bazel.StringAttribute{}
Jingwen Chenbea58092022-09-29 16:56:02 +00002817 } else {
Jingwen Chen6817bbb2022-10-14 09:56:07 +00002818 attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
Wei Li1c66fc72022-05-09 23:59:14 -07002819 }
2820
2821 // Prebuilts
Jingwen Chendf165c92022-06-08 16:00:39 +00002822 if overridableProperties.Prebuilts != nil {
2823 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
2824 attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
2825 }
Wei Li1c66fc72022-05-09 23:59:14 -07002826
2827 // Compressible
2828 if overridableProperties.Compressible != nil {
2829 attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible}
2830 }
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00002831
2832 // Package name
2833 //
2834 // e.g. com.android.adbd's package name is com.android.adbd, but
2835 // com.google.android.adbd overrides the package name to com.google.android.adbd
2836 //
2837 // TODO: this can be overridden from the product configuration, see
2838 // getOverrideManifestPackageName and
2839 // PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES.
2840 //
2841 // Instead of generating the BUILD files differently based on the product config
2842 // at the point of conversion, this should be handled by the BUILD file loading
2843 // from the soong_injection's product_vars, so product config is decoupled from bp2build.
2844 if overridableProperties.Package_name != "" {
2845 attrs.Package_name = &overridableProperties.Package_name
2846 }
Jingwen Chenb732d7c2022-06-10 08:14:19 +00002847
2848 // Logging parent
2849 if overridableProperties.Logging_parent != "" {
2850 attrs.Logging_parent = &overridableProperties.Logging_parent
2851 }
Wei Li1c66fc72022-05-09 23:59:14 -07002852 }
2853
2854 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
2855}
2856
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002857///////////////////////////////////////////////////////////////////////////////////////////////////
2858// Vality check routines
2859//
2860// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2861// certain conditions are not met.
2862//
2863// TODO(jiyong): move these checks to a separate go file.
2864
satayevad991492021-12-03 18:58:32 +00002865var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2866
Spandan Dasa5f39a12022-08-05 02:35:52 +00002867// 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 +09002868// of this apexBundle.
satayevb3fd4112021-12-02 13:59:35 +00002869func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002870 if a.testApex || a.vndkApex {
2871 return
2872 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002873 // apexBundle::minSdkVersion reports its own errors.
2874 minSdkVersion := a.minSdkVersion(ctx)
satayevb3fd4112021-12-02 13:59:35 +00002875 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002876}
2877
Albert Martineefabcf2022-03-21 20:11:16 +00002878// Returns apex's min_sdk_version string value, honoring overrides
2879func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2880 // Only override the minSdkVersion value on Apexes which already specify
2881 // a min_sdk_version (it's optional for non-updatable apexes), and that its
2882 // min_sdk_version value is lower than the one to override with.
zhidou133c55b2023-01-31 19:34:10 +00002883 minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.overridableProperties.Min_sdk_version))
Colin Cross56534df2022-10-04 09:58:58 -07002884 if minApiLevel.IsNone() {
2885 return ""
Albert Martineefabcf2022-03-21 20:11:16 +00002886 }
2887
Colin Cross56534df2022-10-04 09:58:58 -07002888 overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2889 overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
2890 if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2891 minApiLevel = overrideApiLevel
2892 }
2893
2894 return minApiLevel.String()
Albert Martineefabcf2022-03-21 20:11:16 +00002895}
2896
2897// Returns apex's min_sdk_version SdkSpec, honoring overrides
satayevad991492021-12-03 18:58:32 +00002898func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2899 return android.SdkSpec{
2900 Kind: android.SdkNone,
2901 ApiLevel: a.minSdkVersion(ctx),
Albert Martineefabcf2022-03-21 20:11:16 +00002902 Raw: a.minSdkVersionValue(ctx),
satayevad991492021-12-03 18:58:32 +00002903 }
2904}
2905
Albert Martineefabcf2022-03-21 20:11:16 +00002906// Returns apex's min_sdk_version ApiLevel, honoring overrides
satayevad991492021-12-03 18:58:32 +00002907func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Albert Martineefabcf2022-03-21 20:11:16 +00002908 return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2909}
2910
2911// Construct ApiLevel object from min_sdk_version string value
2912func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
2913 if value == "" {
Jooyung Haned124c32021-01-26 11:43:46 +09002914 return android.NoneApiLevel
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002915 }
Albert Martineefabcf2022-03-21 20:11:16 +00002916 apiLevel, err := android.ApiLevelFromUser(ctx, value)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002917 if err != nil {
2918 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2919 return android.NoneApiLevel
2920 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002921 return apiLevel
2922}
2923
2924// Ensures that a lib providing stub isn't statically linked
2925func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2926 // Practically, we only care about regular APEXes on the device.
2927 if ctx.Host() || a.testApex || a.vndkApex {
2928 return
2929 }
2930
2931 abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2932
2933 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2934 if ccm, ok := to.(*cc.Module); ok {
2935 apexName := ctx.ModuleName()
2936 fromName := ctx.OtherModuleName(from)
2937 toName := ctx.OtherModuleName(to)
2938
2939 // If `to` is not actually in the same APEX as `from` then it does not need
2940 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00002941 //
2942 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002943 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2944 // As soon as the dependency graph crosses the APEX boundary, don't go further.
2945 return false
2946 }
2947
2948 // The dynamic linker and crash_dump tool in the runtime APEX is the only
2949 // exception to this rule. It can't make the static dependencies dynamic
2950 // because it can't do the dynamic linking for itself.
Kiyoung Kim4098c7e2020-11-30 14:42:14 +09002951 // Same rule should be applied to linkerconfig, because it should be executed
2952 // only with static linked libraries before linker is available with ld.config.txt
2953 if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002954 return false
2955 }
2956
2957 isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2958 if isStubLibraryFromOtherApex && !externalDep {
2959 ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2960 "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2961 }
2962
2963 }
2964 return true
2965 })
2966}
2967
satayevb98371c2021-06-15 16:49:50 +01002968// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002969func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2970 if a.Updatable() {
Albert Martineefabcf2022-03-21 20:11:16 +00002971 if a.minSdkVersionValue(ctx) == "" {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002972 ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2973 }
Jiyong Park1bc84122021-06-22 20:23:05 +09002974 if a.UsePlatformApis() {
2975 ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2976 }
Daniel Norman69109112021-12-02 12:52:42 -08002977 if a.SocSpecific() || a.DeviceSpecific() {
2978 ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
2979 }
Jiyong Parkf4020582021-11-29 12:37:10 +09002980 if a.FutureUpdatable() {
2981 ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2982 }
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002983 a.checkJavaStableSdkVersion(ctx)
satayevb98371c2021-06-15 16:49:50 +01002984 a.checkClasspathFragments(ctx)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09002985 }
2986}
2987
satayevb98371c2021-06-15 16:49:50 +01002988// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2989func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2990 ctx.VisitDirectDeps(func(module android.Module) {
2991 if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2992 info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2993 if !info.ClasspathFragmentProtoGenerated {
2994 ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2995 }
2996 }
2997 })
2998}
2999
3000// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
Artur Satayev8cf899a2020-04-15 17:29:42 +01003001func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003002 // Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
3003 // java's checkLinkType guarantees correct usage for transitive deps
Artur Satayev8cf899a2020-04-15 17:29:42 +01003004 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3005 tag := ctx.OtherModuleDependencyTag(module)
3006 switch tag {
3007 case javaLibTag, androidAppTag:
Jiyong Parkdbd710c2021-04-02 08:45:46 +09003008 if m, ok := module.(interface {
3009 CheckStableSdkVersion(ctx android.BaseModuleContext) error
3010 }); ok {
3011 if err := m.CheckStableSdkVersion(ctx); err != nil {
Artur Satayev8cf899a2020-04-15 17:29:42 +01003012 ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
3013 }
3014 }
3015 }
3016 })
3017}
3018
satayevb98371c2021-06-15 16:49:50 +01003019// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003020func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
3021 // Let's be practical. Availability for test, host, and the VNDK apex isn't important
3022 if ctx.Host() || a.testApex || a.vndkApex {
3023 return
3024 }
3025
3026 // Because APEXes targeting other than system/system_ext partitions can't set
3027 // apex_available, we skip checks for these APEXes
3028 if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
3029 return
3030 }
3031
3032 // Coverage build adds additional dependencies for the coverage-only runtime libraries.
3033 // Requiring them and their transitive depencies with apex_available is not right
3034 // because they just add noise.
3035 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
3036 return
3037 }
3038
3039 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
3040 // As soon as the dependency graph crosses the APEX boundary, don't go further.
3041 if externalDep {
3042 return false
3043 }
3044
3045 apexName := ctx.ModuleName()
3046 fromName := ctx.OtherModuleName(from)
3047 toName := ctx.OtherModuleName(to)
3048
3049 // If `to` is not actually in the same APEX as `from` then it does not need
3050 // apex_available and neither do any of its dependencies.
Paul Duffin4c3e8e22021-03-18 15:41:29 +00003051 //
3052 // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003053 if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
3054 // As soon as the dependency graph crosses the APEX boundary, don't go
3055 // further.
3056 return false
3057 }
3058
3059 if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
3060 return true
3061 }
Jiyong Park767dbd92021-03-04 13:03:10 +09003062 ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
3063 "\n\nDependency path:%s\n\n"+
3064 "Consider adding %q to 'apex_available' property of %q",
3065 fromName, toName, ctx.GetPathString(true), apexName, toName)
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003066 // Visit this module's dependencies to check and report any issues with their availability.
3067 return true
3068 })
3069}
3070
Jiyong Park192600a2021-08-03 07:52:17 +00003071// checkStaticExecutable ensures that executables in an APEX are not static.
3072func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
Jiyong Parkd12979d2021-08-03 13:36:09 +09003073 // No need to run this for host APEXes
3074 if ctx.Host() {
3075 return
3076 }
3077
Jiyong Park192600a2021-08-03 07:52:17 +00003078 ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
3079 if ctx.OtherModuleDependencyTag(module) != executableTag {
3080 return
3081 }
Jiyong Parkd12979d2021-08-03 13:36:09 +09003082
3083 if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
Jiyong Park192600a2021-08-03 07:52:17 +00003084 apex := a.ApexVariationName()
3085 exec := ctx.OtherModuleName(module)
3086 if isStaticExecutableAllowed(apex, exec) {
3087 return
3088 }
3089 ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
3090 }
3091 })
3092}
3093
3094// A small list of exceptions where static executables are allowed in APEXes.
3095func isStaticExecutableAllowed(apex string, exec string) bool {
3096 m := map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003097 "com.android.runtime": {
Jiyong Park192600a2021-08-03 07:52:17 +00003098 "linker",
3099 "linkerconfig",
3100 },
3101 }
3102 execNames, ok := m[apex]
3103 return ok && android.InList(exec, execNames)
3104}
3105
braleeb0c1f0c2021-06-07 22:49:13 +08003106// Collect information for opening IDE project files in java/jdeps.go.
3107func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
Remi NGUYEN VANbe901722022-03-02 21:00:33 +09003108 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
3109 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
3110 dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
braleeb0c1f0c2021-06-07 22:49:13 +08003111 dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
3112}
3113
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003114var (
3115 apexAvailBaseline = makeApexAvailableBaseline()
3116 inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
3117)
3118
Colin Cross440e0d02020-06-11 11:32:11 -07003119func baselineApexAvailable(apex, moduleName string) bool {
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003120 key := apex
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003121 moduleName = normalizeModuleName(moduleName)
3122
Colin Cross440e0d02020-06-11 11:32:11 -07003123 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003124 return true
3125 }
3126
3127 key = android.AvailableToAnyApex
Colin Cross440e0d02020-06-11 11:32:11 -07003128 if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003129 return true
3130 }
3131
3132 return false
3133}
3134
3135func normalizeModuleName(moduleName string) string {
Jiyong Park0f80c182020-01-31 02:49:53 +09003136 // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
3137 // system. Trim the prefix for the check since they are confusing
Paul Duffind23c7262020-12-11 18:13:08 +00003138 moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
Jiyong Park0f80c182020-01-31 02:49:53 +09003139 if strings.HasPrefix(moduleName, "libclang_rt.") {
3140 // This module has many arch variants that depend on the product being built.
3141 // We don't want to list them all
3142 moduleName = "libclang_rt"
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003143 }
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09003144 if strings.HasPrefix(moduleName, "androidx.") {
3145 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
3146 moduleName = "androidx"
3147 }
Paul Duffin7d74e7b2020-03-06 12:30:13 +00003148 return moduleName
Anton Hanssoneec79eb2020-01-10 15:12:39 +00003149}
3150
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003151// Transform the map of apex -> modules to module -> apexes.
3152func invertApexBaseline(m map[string][]string) map[string][]string {
3153 r := make(map[string][]string)
3154 for apex, modules := range m {
3155 for _, module := range modules {
3156 r[module] = append(r[module], apex)
3157 }
3158 }
3159 return r
3160}
3161
3162// Retrieve the baseline of apexes to which the supplied module belongs.
3163func BaselineApexAvailable(moduleName string) []string {
3164 return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
3165}
3166
Jiyong Parkc0ec6f92020-11-19 23:00:52 +09003167// This is a map from apex to modules, which overrides the apex_available setting for that
3168// particular module to make it available for the apex regardless of its setting.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003169// TODO(b/147364041): remove this
3170func makeApexAvailableBaseline() map[string][]string {
3171 // The "Module separator"s below are employed to minimize merge conflicts.
3172 m := make(map[string][]string)
3173 //
3174 // Module separator
3175 //
3176 m["com.android.appsearch"] = []string{
3177 "icing-java-proto-lite",
3178 "libprotobuf-java-lite",
3179 }
3180 //
3181 // Module separator
3182 //
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003183 m["com.android.btservices"] = []string{
William Escande89bca3f2022-06-28 18:03:30 -07003184 // empty
Oriol Prieto Gasco8132fbf2022-06-17 19:44:25 +00003185 }
3186 //
3187 // Module separator
3188 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003189 m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
3190 //
3191 // Module separator
3192 //
3193 m["com.android.extservices"] = []string{
3194 "error_prone_annotations",
3195 "ExtServices-core",
3196 "ExtServices",
3197 "libtextclassifier-java",
3198 "libz_current",
3199 "textclassifier-statsd",
3200 "TextClassifierNotificationLibNoManifest",
3201 "TextClassifierServiceLibNoManifest",
3202 }
3203 //
3204 // Module separator
3205 //
3206 m["com.android.neuralnetworks"] = []string{
3207 "android.hardware.neuralnetworks@1.0",
3208 "android.hardware.neuralnetworks@1.1",
3209 "android.hardware.neuralnetworks@1.2",
3210 "android.hardware.neuralnetworks@1.3",
3211 "android.hidl.allocator@1.0",
3212 "android.hidl.memory.token@1.0",
3213 "android.hidl.memory@1.0",
3214 "android.hidl.safe_union@1.0",
3215 "libarect",
3216 "libbuildversion",
3217 "libmath",
3218 "libprocpartition",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003219 }
3220 //
3221 // Module separator
3222 //
3223 m["com.android.media"] = []string{
Ray Essick5d240fb2022-02-07 11:01:32 -08003224 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003225 }
3226 //
3227 // Module separator
3228 //
3229 m["com.android.media.swcodec"] = []string{
Ray Essickde1e3002022-02-10 17:37:51 -08003230 // empty
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003231 }
3232 //
3233 // Module separator
3234 //
3235 m["com.android.mediaprovider"] = []string{
3236 "MediaProvider",
3237 "MediaProviderGoogle",
3238 "fmtlib_ndk",
3239 "libbase_ndk",
3240 "libfuse",
3241 "libfuse_jni",
3242 }
3243 //
3244 // Module separator
3245 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003246 m["com.android.runtime"] = []string{
3247 "bionic_libc_platform_headers",
3248 "libarm-optimized-routines-math",
3249 "libc_aeabi",
3250 "libc_bionic",
3251 "libc_bionic_ndk",
3252 "libc_bootstrap",
3253 "libc_common",
3254 "libc_common_shared",
3255 "libc_common_static",
3256 "libc_dns",
3257 "libc_dynamic_dispatch",
3258 "libc_fortify",
3259 "libc_freebsd",
3260 "libc_freebsd_large_stack",
3261 "libc_gdtoa",
3262 "libc_init_dynamic",
3263 "libc_init_static",
3264 "libc_jemalloc_wrapper",
3265 "libc_netbsd",
3266 "libc_nomalloc",
3267 "libc_nopthread",
3268 "libc_openbsd",
3269 "libc_openbsd_large_stack",
3270 "libc_openbsd_ndk",
3271 "libc_pthread",
3272 "libc_static_dispatch",
3273 "libc_syscalls",
3274 "libc_tzcode",
3275 "libc_unwind_static",
3276 "libdebuggerd",
3277 "libdebuggerd_common_headers",
3278 "libdebuggerd_handler_core",
3279 "libdebuggerd_handler_fallback",
3280 "libdl_static",
3281 "libjemalloc5",
3282 "liblinker_main",
3283 "liblinker_malloc",
3284 "liblz4",
3285 "liblzma",
3286 "libprocinfo",
3287 "libpropertyinfoparser",
3288 "libscudo",
3289 "libstdc++",
3290 "libsystemproperties",
3291 "libtombstoned_client_static",
3292 "libunwindstack",
3293 "libz",
3294 "libziparchive",
3295 }
3296 //
3297 // Module separator
3298 //
3299 m["com.android.tethering"] = []string{
3300 "android.hardware.tetheroffload.config-V1.0-java",
3301 "android.hardware.tetheroffload.control-V1.0-java",
3302 "android.hidl.base-V1.0-java",
3303 "libcgrouprc",
3304 "libcgrouprc_format",
3305 "libtetherutilsjni",
3306 "libvndksupport",
3307 "net-utils-framework-common",
3308 "netd_aidl_interface-V3-java",
3309 "netlink-client",
3310 "networkstack-aidl-interfaces-java",
3311 "tethering-aidl-interfaces-java",
3312 "TetheringApiCurrentLib",
3313 }
3314 //
3315 // Module separator
3316 //
3317 m["com.android.wifi"] = []string{
3318 "PlatformProperties",
3319 "android.hardware.wifi-V1.0-java",
3320 "android.hardware.wifi-V1.0-java-constants",
3321 "android.hardware.wifi-V1.1-java",
3322 "android.hardware.wifi-V1.2-java",
3323 "android.hardware.wifi-V1.3-java",
3324 "android.hardware.wifi-V1.4-java",
3325 "android.hardware.wifi.hostapd-V1.0-java",
3326 "android.hardware.wifi.hostapd-V1.1-java",
3327 "android.hardware.wifi.hostapd-V1.2-java",
3328 "android.hardware.wifi.supplicant-V1.0-java",
3329 "android.hardware.wifi.supplicant-V1.1-java",
3330 "android.hardware.wifi.supplicant-V1.2-java",
3331 "android.hardware.wifi.supplicant-V1.3-java",
3332 "android.hidl.base-V1.0-java",
3333 "android.hidl.manager-V1.0-java",
3334 "android.hidl.manager-V1.1-java",
3335 "android.hidl.manager-V1.2-java",
3336 "bouncycastle-unbundled",
3337 "dnsresolver_aidl_interface-V2-java",
3338 "error_prone_annotations",
3339 "framework-wifi-pre-jarjar",
3340 "framework-wifi-util-lib",
3341 "ipmemorystore-aidl-interfaces-V3-java",
3342 "ipmemorystore-aidl-interfaces-java",
3343 "ksoap2",
3344 "libnanohttpd",
3345 "libwifi-jni",
3346 "net-utils-services-common",
3347 "netd_aidl_interface-V2-java",
3348 "netd_aidl_interface-unstable-java",
3349 "netd_event_listener_interface-java",
3350 "netlink-client",
3351 "networkstack-client",
3352 "services.net",
3353 "wifi-lite-protos",
3354 "wifi-nano-protos",
3355 "wifi-service-pre-jarjar",
3356 "wifi-service-resources",
3357 }
3358 //
3359 // Module separator
3360 //
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003361 m["com.android.os.statsd"] = []string{
3362 "libstatssocket",
3363 }
3364 //
3365 // Module separator
3366 //
3367 m[android.AvailableToAnyApex] = []string{
3368 // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
3369 "androidx",
3370 "androidx-constraintlayout_constraintlayout",
3371 "androidx-constraintlayout_constraintlayout-nodeps",
3372 "androidx-constraintlayout_constraintlayout-solver",
3373 "androidx-constraintlayout_constraintlayout-solver-nodeps",
3374 "com.google.android.material_material",
3375 "com.google.android.material_material-nodeps",
3376
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003377 "libclang_rt",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003378 "libprofile-clang-extras",
3379 "libprofile-clang-extras_ndk",
3380 "libprofile-extras",
3381 "libprofile-extras_ndk",
Ryan Prichardb35a85e2021-01-13 19:18:53 -08003382 "libunwind",
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003383 }
3384 return m
3385}
3386
3387func init() {
Spandan Dasf14e2542021-11-12 00:01:37 +00003388 android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
3389 android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003390}
3391
Spandan Dasf14e2542021-11-12 00:01:37 +00003392func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
3393 rules := make([]android.Rule, 0, len(bcpPermittedPackages))
3394 for jar, permittedPackages := range bcpPermittedPackages {
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003395 permittedPackagesRule := android.NeverAllow().
Spandan Dasf14e2542021-11-12 00:01:37 +00003396 With("name", jar).
3397 WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
3398 Because(jar +
3399 " bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
Anton Hanssone1b18362021-12-23 15:05:38 +00003400 ". Please consider the following alternatives:\n" +
Andrei Onead967aee2022-01-19 15:36:40 +00003401 " 1. If the offending code is from a statically linked library, consider " +
3402 "removing that dependency and using an alternative already in the " +
3403 "bootclasspath, or perhaps a shared library." +
3404 " 2. Move the offending code into an allowed package.\n" +
3405 " 3. Jarjar the offending code. Please be mindful of the potential system " +
3406 "health implications of bundling that code, particularly if the offending jar " +
3407 "is part of the bootclasspath.")
Spandan Dasf14e2542021-11-12 00:01:37 +00003408
Jaewoong Jung18aefc12020-12-21 09:11:10 -08003409 rules = append(rules, permittedPackagesRule)
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003410 }
3411 return rules
3412}
3413
Anton Hanssone1b18362021-12-23 15:05:38 +00003414// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003415// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003416func qBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003417 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003418 "conscrypt": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003419 "android.net.ssl",
3420 "com.android.org.conscrypt",
3421 },
Wei Li40f98732022-05-20 22:08:11 -07003422 "updatable-media": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003423 "android.media",
3424 },
3425 }
3426}
3427
Anton Hanssone1b18362021-12-23 15:05:38 +00003428// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003429// Adding code to the bootclasspath in new packages will cause issues on module update.
Spandan Dasf14e2542021-11-12 00:01:37 +00003430func rBcpPackages() map[string][]string {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003431 return map[string][]string{
Wei Li40f98732022-05-20 22:08:11 -07003432 "framework-mediaprovider": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003433 "android.provider",
3434 },
Wei Li40f98732022-05-20 22:08:11 -07003435 "framework-permission": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003436 "android.permission",
3437 "android.app.role",
3438 "com.android.permission",
3439 "com.android.role",
3440 },
Wei Li40f98732022-05-20 22:08:11 -07003441 "framework-sdkextensions": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003442 "android.os.ext",
3443 },
Wei Li40f98732022-05-20 22:08:11 -07003444 "framework-statsd": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003445 "android.app",
3446 "android.os",
3447 "android.util",
3448 "com.android.internal.statsd",
3449 "com.android.server.stats",
3450 },
Wei Li40f98732022-05-20 22:08:11 -07003451 "framework-wifi": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003452 "com.android.server.wifi",
3453 "com.android.wifi.x",
3454 "android.hardware.wifi",
3455 "android.net.wifi",
3456 },
Wei Li40f98732022-05-20 22:08:11 -07003457 "framework-tethering": {
Jiyong Park8e6d52f2020-11-19 14:37:47 +09003458 "android.net",
3459 },
3460 }
3461}
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003462
3463// For Bazel / bp2build
3464
3465type bazelApexBundleAttributes struct {
Yu Liu4ae55d12022-01-05 17:17:23 -08003466 Manifest bazel.LabelAttribute
3467 Android_manifest bazel.LabelAttribute
3468 File_contexts bazel.LabelAttribute
3469 Key bazel.LabelAttribute
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003470 Certificate bazel.LabelAttribute // used when the certificate prop is a module
3471 Certificate_name bazel.StringAttribute // used when the certificate prop is a string
Liz Kammerb83b7b02022-12-21 14:53:41 -05003472 Min_sdk_version bazel.StringAttribute
Yu Liu4ae55d12022-01-05 17:17:23 -08003473 Updatable bazel.BoolAttribute
3474 Installable bazel.BoolAttribute
3475 Binaries bazel.LabelListAttribute
3476 Prebuilts bazel.LabelListAttribute
3477 Native_shared_libs_32 bazel.LabelListAttribute
3478 Native_shared_libs_64 bazel.LabelListAttribute
Wei Lif034cb42022-01-19 15:54:31 -08003479 Compressible bazel.BoolAttribute
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003480 Package_name *string
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003481 Logging_parent *string
Yu Liu4c212ce2022-10-14 12:20:20 -07003482 Tests bazel.LabelListAttribute
Jingwen Chenc4c34e12022-11-29 12:07:45 +00003483 Base_apex_name *string
Yu Liu4ae55d12022-01-05 17:17:23 -08003484}
3485
3486type convertedNativeSharedLibs struct {
3487 Native_shared_libs_32 bazel.LabelListAttribute
3488 Native_shared_libs_64 bazel.LabelListAttribute
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003489}
3490
Liz Kammerb83b7b02022-12-21 14:53:41 -05003491const (
3492 minSdkVersionPropName = "Min_sdk_version"
3493)
3494
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003495// ConvertWithBp2build performs bp2build conversion of an apex
3496func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Yu Liu4c212ce2022-10-14 12:20:20 -07003497 // We only convert apex and apex_test modules at this time
3498 if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003499 return
3500 }
3501
Wei Li1c66fc72022-05-09 23:59:14 -07003502 attrs, props := convertWithBp2build(a, ctx)
Yu Liu4c212ce2022-10-14 12:20:20 -07003503 commonAttrs := android.CommonAttributes{
3504 Name: a.Name(),
3505 }
3506 if a.testApex {
3507 commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
3508 }
3509 ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
Wei Li1c66fc72022-05-09 23:59:14 -07003510}
3511
3512func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003513 var manifestLabelAttribute bazel.LabelAttribute
Wei Li40f98732022-05-20 22:08:11 -07003514 manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003515
3516 var androidManifestLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003517 if a.properties.AndroidManifest != nil {
3518 androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003519 }
3520
3521 var fileContextsLabelAttribute bazel.LabelAttribute
Wei Li1c66fc72022-05-09 23:59:14 -07003522 if a.properties.File_contexts == nil {
3523 // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:<module name>-file_contexts
3524 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts"))
3525 } else if strings.HasPrefix(*a.properties.File_contexts, ":") {
3526 // File_contexts is a module
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003527 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
Wei Li1c66fc72022-05-09 23:59:14 -07003528 } else {
3529 // File_contexts is a file
3530 fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003531 }
3532
Liz Kammerb83b7b02022-12-21 14:53:41 -05003533 productVariableProps := android.ProductVariableProperties(ctx)
Albert Martineefabcf2022-03-21 20:11:16 +00003534 // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
3535 // given it's coming via config, we probably don't want to put it in here.
Liz Kammerb83b7b02022-12-21 14:53:41 -05003536 var minSdkVersion bazel.StringAttribute
zhidou133c55b2023-01-31 19:34:10 +00003537 if a.overridableProperties.Min_sdk_version != nil {
3538 minSdkVersion.SetValue(*a.overridableProperties.Min_sdk_version)
Liz Kammerb83b7b02022-12-21 14:53:41 -05003539 }
3540 if props, ok := productVariableProps[minSdkVersionPropName]; ok {
3541 for c, p := range props {
3542 if val, ok := p.(*string); ok {
3543 minSdkVersion.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val)
3544 }
3545 }
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003546 }
3547
3548 var keyLabelAttribute bazel.LabelAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003549 if a.overridableProperties.Key != nil {
3550 keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003551 }
3552
Jingwen Chen6817bbb2022-10-14 09:56:07 +00003553 // Certificate
3554 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003555
Yu Liu4ae55d12022-01-05 17:17:23 -08003556 nativeSharedLibs := &convertedNativeSharedLibs{
3557 Native_shared_libs_32: bazel.LabelListAttribute{},
3558 Native_shared_libs_64: bazel.LabelListAttribute{},
3559 }
Vinh Tran8f5310f2022-10-07 18:16:47 -04003560
3561 // https://cs.android.com/android/platform/superproject/+/master:build/soong/android/arch.go;l=698;drc=f05b0d35d2fbe51be9961ce8ce8031f840295c68
3562 // https://cs.android.com/android/platform/superproject/+/master:build/soong/apex/apex.go;l=2549;drc=ec731a83e3e2d80a1254e32fd4ad7ef85e262669
3563 // In Soong, decodeMultilib, used to get multilib, return "first" if defaultMultilib is set to "common".
3564 // Since apex sets defaultMultilib to be "common", equivalent compileMultilib in bp2build for apex should be "first"
3565 compileMultilib := "first"
Yu Liu4ae55d12022-01-05 17:17:23 -08003566 if a.CompileMultilib() != nil {
3567 compileMultilib = *a.CompileMultilib()
3568 }
3569
3570 // properties.Native_shared_libs is treated as "both"
3571 convertBothLibs(ctx, compileMultilib, a.properties.Native_shared_libs, nativeSharedLibs)
3572 convertBothLibs(ctx, compileMultilib, a.properties.Multilib.Both.Native_shared_libs, nativeSharedLibs)
3573 convert32Libs(ctx, compileMultilib, a.properties.Multilib.Lib32.Native_shared_libs, nativeSharedLibs)
3574 convert64Libs(ctx, compileMultilib, a.properties.Multilib.Lib64.Native_shared_libs, nativeSharedLibs)
3575 convertFirstLibs(ctx, compileMultilib, a.properties.Multilib.First.Native_shared_libs, nativeSharedLibs)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003576
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003577 prebuilts := a.overridableProperties.Prebuilts
Rupert Shuttleworth9447e1e2021-07-28 05:53:42 -04003578 prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
3579 prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
3580
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003581 binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries)
Jingwen Chenb07c9012021-12-08 10:05:45 +00003582 binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003583
Yu Liu4c212ce2022-10-14 12:20:20 -07003584 var testsAttrs bazel.LabelListAttribute
3585 if a.testApex && len(a.properties.ApexNativeDependencies.Tests) > 0 {
3586 tests := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Tests)
3587 testsAttrs = bazel.MakeLabelListAttribute(tests)
3588 }
3589
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003590 var updatableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003591 if a.properties.Updatable != nil {
3592 updatableAttribute.Value = a.properties.Updatable
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04003593 }
3594
3595 var installableAttribute bazel.BoolAttribute
Liz Kammerbe46fcc2021-11-01 15:32:43 -04003596 if a.properties.Installable != nil {
3597 installableAttribute.Value = a.properties.Installable
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003598 }
3599
Wei Lif034cb42022-01-19 15:54:31 -08003600 var compressibleAttribute bazel.BoolAttribute
3601 if a.overridableProperties.Compressible != nil {
3602 compressibleAttribute.Value = a.overridableProperties.Compressible
3603 }
3604
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003605 var packageName *string
3606 if a.overridableProperties.Package_name != "" {
3607 packageName = &a.overridableProperties.Package_name
3608 }
3609
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003610 var loggingParent *string
3611 if a.overridableProperties.Logging_parent != "" {
3612 loggingParent = &a.overridableProperties.Logging_parent
3613 }
3614
Wei Li1c66fc72022-05-09 23:59:14 -07003615 attrs := bazelApexBundleAttributes{
Yu Liu4ae55d12022-01-05 17:17:23 -08003616 Manifest: manifestLabelAttribute,
3617 Android_manifest: androidManifestLabelAttribute,
3618 File_contexts: fileContextsLabelAttribute,
3619 Min_sdk_version: minSdkVersion,
3620 Key: keyLabelAttribute,
Jingwen Chenbea58092022-09-29 16:56:02 +00003621 Certificate: certificate,
3622 Certificate_name: certificateName,
Yu Liu4ae55d12022-01-05 17:17:23 -08003623 Updatable: updatableAttribute,
3624 Installable: installableAttribute,
3625 Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
3626 Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64,
3627 Binaries: binariesLabelListAttribute,
3628 Prebuilts: prebuiltsLabelListAttribute,
Wei Lif034cb42022-01-19 15:54:31 -08003629 Compressible: compressibleAttribute,
Jingwen Chen9b7ebca2022-06-03 09:11:20 +00003630 Package_name: packageName,
Jingwen Chenb732d7c2022-06-10 08:14:19 +00003631 Logging_parent: loggingParent,
Yu Liu4c212ce2022-10-14 12:20:20 -07003632 Tests: testsAttrs,
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003633 }
3634
3635 props := bazel.BazelTargetModuleProperties{
3636 Rule_class: "apex",
Cole Faust5f90da32022-04-29 13:37:43 -07003637 Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003638 }
3639
Wei Li1c66fc72022-05-09 23:59:14 -07003640 return attrs, props
Rupert Shuttlewortha9d76dd2021-07-02 07:17:16 -04003641}
Yu Liu4ae55d12022-01-05 17:17:23 -08003642
3643// The following conversions are based on this table where the rows are the compile_multilib
3644// values and the columns are the properties.Multilib.*.Native_shared_libs. Each cell
3645// represents how the libs should be compiled for a 64-bit/32-bit device: 32 means it
3646// should be compiled as 32-bit, 64 means it should be compiled as 64-bit, none means it
3647// should not be compiled.
3648// multib/compile_multilib, 32, 64, both, first
3649// 32, 32/32, none/none, 32/32, none/32
3650// 64, none/none, 64/none, 64/none, 64/none
3651// both, 32/32, 64/none, 32&64/32, 64/32
3652// first, 32/32, 64/none, 64/32, 64/32
3653
3654func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3655 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3656 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3657 switch compileMultilb {
3658 case "both", "32":
3659 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3660 case "first":
3661 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3662 case "64":
3663 // Incompatible, ignore
3664 default:
3665 invalidCompileMultilib(ctx, compileMultilb)
3666 }
3667}
3668
3669func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
3670 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3671 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3672 switch compileMultilb {
3673 case "both", "64", "first":
3674 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3675 case "32":
3676 // Incompatible, ignore
3677 default:
3678 invalidCompileMultilib(ctx, compileMultilb)
3679 }
3680}
3681
3682func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3683 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3684 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3685 switch compileMultilb {
3686 case "both":
3687 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3688 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3689 case "first":
3690 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3691 case "32":
3692 makeNoConfig32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3693 case "64":
3694 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3695 default:
3696 invalidCompileMultilib(ctx, compileMultilb)
3697 }
3698}
3699
3700func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
3701 libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
3702 libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
3703 switch compileMultilb {
3704 case "both", "first":
3705 makeFirstSharedLibsAttributes(libsLabelList, nativeSharedLibs)
3706 case "32":
3707 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3708 case "64":
3709 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3710 default:
3711 invalidCompileMultilib(ctx, compileMultilb)
3712 }
3713}
3714
3715func makeFirstSharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3716 make32SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3717 make64SharedLibsAttributes(libsLabelList, nativeSharedLibs)
3718}
3719
3720func makeNoConfig32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3721 list := bazel.LabelListAttribute{}
3722 list.SetSelectValue(bazel.NoConfigAxis, "", libsLabelList)
3723 nativeSharedLibs.Native_shared_libs_32.Append(list)
3724}
3725
3726func make32SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3727 makeSharedLibsAttributes("x86", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3728 makeSharedLibsAttributes("arm", libsLabelList, &nativeSharedLibs.Native_shared_libs_32)
3729}
3730
3731func make64SharedLibsAttributes(libsLabelList bazel.LabelList, nativeSharedLibs *convertedNativeSharedLibs) {
3732 makeSharedLibsAttributes("x86_64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3733 makeSharedLibsAttributes("arm64", libsLabelList, &nativeSharedLibs.Native_shared_libs_64)
3734}
3735
3736func makeSharedLibsAttributes(config string, libsLabelList bazel.LabelList,
3737 labelListAttr *bazel.LabelListAttribute) {
3738 list := bazel.LabelListAttribute{}
3739 list.SetSelectValue(bazel.ArchConfigurationAxis, config, libsLabelList)
3740 labelListAttr.Append(list)
3741}
3742
3743func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
3744 ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
3745}