blob: ee5ebcd8250efb930cbd5fac659c280d3a78c08e [file] [log] [blame]
Colin Crossfabb6082018-02-20 17:22:23 -08001// Copyright 2018 Google Inc. All rights reserved.
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
15package java
16
17import (
Colin Crossa592e3e2019-02-19 16:59:53 -080018 "fmt"
Jaewoong Jung5b425e22019-06-17 17:40:56 -070019 "path/filepath"
Colin Cross312634e2023-11-21 15:13:56 -080020 "slices"
Colin Crossc20dc852020-11-10 12:27:45 -080021 "strconv"
Colin Crossa97c5d32018-03-28 14:58:31 -070022 "strings"
Colin Crossfabb6082018-02-20 17:22:23 -080023
Jaewoong Jung9befb0c2020-01-18 10:33:43 -080024 "android/soong/android"
Ulya Trafimovich31e444e2020-08-14 17:32:16 +010025 "android/soong/dexpreopt"
Jihoon Kangfe914ed2024-02-12 22:49:21 +000026
Colin Crossfabb6082018-02-20 17:22:23 -080027 "github.com/google/blueprint"
Colin Crossa97c5d32018-03-28 14:58:31 -070028 "github.com/google/blueprint/proptools"
Colin Crossfabb6082018-02-20 17:22:23 -080029)
30
Colin Crossa97c5d32018-03-28 14:58:31 -070031type AndroidLibraryDependency interface {
Colin Crossa97c5d32018-03-28 14:58:31 -070032 ExportPackage() android.Path
Colin Crossab8d1382023-07-14 17:23:41 +000033 ResourcesNodeDepSet() *android.DepSet[*resourcesNode]
34 RRODirsDepSet() *android.DepSet[rroDir]
35 ManifestsDepSet() *android.DepSet[android.Path]
Jaewoong Jungc779cd42020-10-06 18:56:10 -070036 SetRROEnforcedForDependent(enforce bool)
37 IsRROEnforced(ctx android.BaseModuleContext) bool
Colin Crossa97c5d32018-03-28 14:58:31 -070038}
39
40func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000041 RegisterAARBuildComponents(android.InitRegistrationContext)
42}
43
44func RegisterAARBuildComponents(ctx android.RegistrationContext) {
45 ctx.RegisterModuleType("android_library_import", AARImportFactory)
46 ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
Paul Duffin04ba70d2021-03-22 13:56:43 +000047 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
Colin Cross7e6a9012024-01-17 14:58:38 -080048 ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator)
Paul Duffin04ba70d2021-03-22 13:56:43 +000049 })
Colin Crossa97c5d32018-03-28 14:58:31 -070050}
51
52//
53// AAR (android library)
54//
55
56type androidLibraryProperties struct {
57 BuildAAR bool `blueprint:"mutated"`
58}
59
60type aaptProperties struct {
61 // flags passed to aapt when creating the apk
62 Aaptflags []string
63
Dan Willemsen72be5902018-10-24 20:24:57 -070064 // include all resource configurations, not just the product-configured
65 // ones.
66 Aapt_include_all_resources *bool
67
Jiakai Zhangba82e282023-10-13 18:08:59 +010068 // list of files to use as assets.
69 Assets []string `android:"path"`
70
Colin Crossa97c5d32018-03-28 14:58:31 -070071 // list of directories relative to the Blueprints file containing assets.
Colin Cross0ddae7f2019-02-07 15:30:01 -080072 // Defaults to ["assets"] if a directory called assets exists. Set to []
73 // to disable the default.
Colin Crossa97c5d32018-03-28 14:58:31 -070074 Asset_dirs []string
75
76 // list of directories relative to the Blueprints file containing
Colin Cross0ddae7f2019-02-07 15:30:01 -080077 // Android resources. Defaults to ["res"] if a directory called res exists.
78 // Set to [] to disable the default.
Colin Crossa97c5d32018-03-28 14:58:31 -070079 Resource_dirs []string
80
Colin Crossa592e3e2019-02-19 16:59:53 -080081 // list of zip files containing Android resources.
Colin Cross27b922f2019-03-04 22:35:41 -080082 Resource_zips []string `android:"path"`
Colin Crossa592e3e2019-02-19 16:59:53 -080083
Colin Crossa97c5d32018-03-28 14:58:31 -070084 // path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml".
Colin Cross27b922f2019-03-04 22:35:41 -080085 Manifest *string `android:"path"`
changho.shinb5432b72019-08-08 18:37:17 +090086
87 // paths to additional manifest files to merge with main manifest.
88 Additional_manifests []string `android:"path"`
Sasha Smundak541056c2019-10-28 15:50:06 -070089
90 // do not include AndroidManifest from dependent libraries
91 Dont_merge_manifests *bool
Jaewoong Jungc779cd42020-10-06 18:56:10 -070092
Colin Cross4eae06d2023-06-20 22:40:02 -070093 // If use_resource_processor is set, use Bazel's resource processor instead of aapt2 to generate R.class files.
94 // The resource processor produces more optimal R.class files that only list resources in the package of the
95 // library that provided them, as opposed to aapt2 which produces R.java files for every package containing
96 // every resource. Using the resource processor can provide significant build time speedups, but requires
97 // fixing the module to use the correct package to reference each resource, and to avoid having any other
98 // libraries in the tree that use the same package name. Defaults to false, but will default to true in the
99 // future.
100 Use_resource_processor *bool
101
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700102 // true if RRO is enforced for any of the dependent modules
103 RROEnforcedForDependent bool `blueprint:"mutated"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900104
105 // Filter only specified product and ignore other products
106 Filter_product *string `blueprint:"mutated"`
Jihoon Kang9049c272024-03-19 21:57:36 +0000107
108 // Names of aconfig_declarations modules that specify aconfig flags that the module depends on.
109 Flags_packages []string
Colin Crossa97c5d32018-03-28 14:58:31 -0700110}
111
112type aapt struct {
Colin Cross312634e2023-11-21 15:13:56 -0800113 aaptSrcJar android.Path
114 transitiveAaptRJars android.Paths
115 transitiveAaptResourcePackagesFile android.Path
116 exportPackage android.Path
117 manifestPath android.Path
118 proguardOptionsFile android.Path
119 rTxt android.Path
120 rJar android.Path
121 extraAaptPackagesFile android.Path
122 mergedManifestFile android.Path
123 noticeFile android.OptionalPath
124 assetPackage android.OptionalPath
125 isLibrary bool
126 defaultManifestVersion string
127 useEmbeddedNativeLibs bool
128 useEmbeddedDex bool
129 usesNonSdkApis bool
130 hasNoCode bool
131 LoggingParent string
132 resourceFiles android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700133
Colin Crosse560c4a2019-03-19 16:03:11 -0700134 splitNames []string
135 splits []split
136
Colin Crossa97c5d32018-03-28 14:58:31 -0700137 aaptProperties aaptProperties
Colin Crossab8d1382023-07-14 17:23:41 +0000138
139 resourcesNodesDepSet *android.DepSet[*resourcesNode]
140 rroDirsDepSet *android.DepSet[rroDir]
141 manifestsDepSet *android.DepSet[android.Path]
Alix96ea88452023-08-31 15:48:23 +0000142
143 manifestValues struct {
144 applicationId string
145 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700146}
147
Colin Crosse560c4a2019-03-19 16:03:11 -0700148type split struct {
149 name string
150 suffix string
151 path android.Path
152}
153
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700154// Propagate RRO enforcement flag to static lib dependencies transitively.
155func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
156 m := ctx.Module()
157 if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) {
158 ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
159 if a, ok := d.(AndroidLibraryDependency); ok {
160 a.SetRROEnforcedForDependent(true)
161 }
162 })
163 }
164}
165
Colin Cross8f1b0332024-01-25 13:39:06 -0800166func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool {
167 return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault())
Colin Cross4eae06d2023-06-20 22:40:02 -0700168}
169
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900170func (a *aapt) filterProduct() string {
171 return String(a.aaptProperties.Filter_product)
172}
173
Colin Crossa97c5d32018-03-28 14:58:31 -0700174func (a *aapt) ExportPackage() android.Path {
175 return a.exportPackage
176}
Colin Crossab8d1382023-07-14 17:23:41 +0000177func (a *aapt) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
178 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800179}
180
Colin Crossab8d1382023-07-14 17:23:41 +0000181func (a *aapt) RRODirsDepSet() *android.DepSet[rroDir] {
182 return a.rroDirsDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800183}
184
Colin Crossab8d1382023-07-14 17:23:41 +0000185func (a *aapt) ManifestsDepSet() *android.DepSet[android.Path] {
186 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800187}
188
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700189func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
190 a.aaptProperties.RROEnforcedForDependent = enforce
191}
192
193func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
194 // True if RRO is enforced for this module or...
195 return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
Jeongik Chacee5ba92021-02-19 12:11:51 +0900196 // if RRO is enforced for any of its dependents.
197 a.aaptProperties.RROEnforcedForDependent
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700198}
199
Jiyong Parkf1691d22021-03-29 20:11:58 +0900200func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkContext,
Colin Crossa0ba2f52019-06-22 12:59:27 -0700201 manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
202 resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700203
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800204 hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
205 hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
Colin Crossa97c5d32018-03-28 14:58:31 -0700206
Colin Crossa97c5d32018-03-28 14:58:31 -0700207 // Flags specified in Android.bp
208 linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
209
Eric Miao40eab202023-03-30 16:57:17 +0000210 linkFlags = append(linkFlags, "--enable-compact-entries")
Colin Crossa97c5d32018-03-28 14:58:31 -0700211
212 // Find implicit or explicit asset and resource dirs
Jiakai Zhangba82e282023-10-13 18:08:59 +0100213 assets := android.PathsRelativeToModuleSourceDir(android.SourceInput{
214 Context: ctx,
215 Paths: a.aaptProperties.Assets,
216 IncludeDirs: false,
217 })
Colin Crossa97c5d32018-03-28 14:58:31 -0700218 assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
219 resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
Colin Cross8a497952019-03-05 22:25:09 -0800220 resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
Colin Crossa97c5d32018-03-28 14:58:31 -0700221
Colin Crossa97c5d32018-03-28 14:58:31 -0700222 // Glob directories into lists of paths
223 for _, dir := range resourceDirs {
224 resDirs = append(resDirs, globbedResourceDir{
225 dir: dir,
226 files: androidResourceGlob(ctx, dir),
227 })
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700228 resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
Colin Crossa97c5d32018-03-28 14:58:31 -0700229 overlayDirs = append(overlayDirs, resOverlayDirs...)
230 rroDirs = append(rroDirs, resRRODirs...)
231 }
232
Colin Crossc20dc852020-11-10 12:27:45 -0800233 var assetDeps android.Paths
234 for i, dir := range assetDirs {
235 // Add a dependency on every file in the asset directory. This ensures the aapt2
236 // rule will be rerun if one of the files in the asset directory is modified.
237 assetDeps = append(assetDeps, androidResourceGlob(ctx, dir)...)
238
239 // Add a dependency on a file that contains a list of all the files in the asset directory.
240 // This ensures the aapt2 rule will be run if a file is removed from the asset directory,
241 // or a file is added whose timestamp is older than the output of aapt2.
242 assetFileListFile := android.PathForModuleOut(ctx, "asset_dir_globs", strconv.Itoa(i)+".glob")
243 androidResourceGlobList(ctx, dir, assetFileListFile)
244 assetDeps = append(assetDeps, assetFileListFile)
Colin Crossa97c5d32018-03-28 14:58:31 -0700245 }
246
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700247 assetDirStrings := assetDirs.Strings()
248 if a.noticeFile.Valid() {
249 assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
Colin Crossc20dc852020-11-10 12:27:45 -0800250 assetDeps = append(assetDeps, a.noticeFile.Path())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700251 }
Jiakai Zhangba82e282023-10-13 18:08:59 +0100252 if len(assets) > 0 {
253 // aapt2 doesn't support adding individual asset files. Create a temp directory to hold asset
254 // files and pass it to aapt2.
255 tmpAssetDir := android.PathForModuleOut(ctx, "tmp_asset_dir")
256
257 rule := android.NewRuleBuilder(pctx, ctx)
258 rule.Command().
259 Text("rm -rf").Text(tmpAssetDir.String()).
260 Text("&&").
261 Text("mkdir -p").Text(tmpAssetDir.String())
262
263 for _, asset := range assets {
264 output := tmpAssetDir.Join(ctx, asset.Rel())
265 assetDeps = append(assetDeps, output)
266 rule.Command().Text("mkdir -p").Text(filepath.Dir(output.String()))
267 rule.Command().Text("cp").Input(asset).Output(output)
268 }
269
270 rule.Build("tmp_asset_dir", "tmp_asset_dir")
271
272 assetDirStrings = append(assetDirStrings, tmpAssetDir.String())
273 }
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700274
Colin Crossa97c5d32018-03-28 14:58:31 -0700275 linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
276 linkDeps = append(linkDeps, manifestPath)
277
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700278 linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
Colin Crossc20dc852020-11-10 12:27:45 -0800279 linkDeps = append(linkDeps, assetDeps...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700280
Spandan Das50885c02023-02-23 21:31:33 +0000281 // Returns the effective version for {min|target}_sdk_version
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000282 effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.ApiLevel) string {
Spandan Das50885c02023-02-23 21:31:33 +0000283 // If {min|target}_sdk_version is current, use sdk_version to determine the effective level
284 // This is necessary for vendor modules.
285 // The effective version does not _only_ depend on {min|target}_sdk_version(level),
286 // but also on the sdk_version (kind+level)
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000287 if minSdkVersion.IsCurrent() {
Spandan Das50885c02023-02-23 21:31:33 +0000288 ret, err := sdkVersion.EffectiveVersionString(ctx)
289 if err != nil {
290 ctx.ModuleErrorf("invalid sdk_version: %s", err)
291 }
292 return ret
293 }
294 ret, err := minSdkVersion.EffectiveVersionString(ctx)
295 if err != nil {
296 ctx.ModuleErrorf("invalid min_sdk_version: %s", err)
297 }
298 return ret
Jiyong Park6a927c42020-01-21 02:03:43 +0900299 }
Spandan Das50885c02023-02-23 21:31:33 +0000300 // SDK version flags
301 sdkVersion := sdkContext.SdkVersion(ctx)
302 minSdkVersion := effectiveVersionString(sdkVersion, sdkContext.MinSdkVersion(ctx))
Colin Crossa97c5d32018-03-28 14:58:31 -0700303
Colin Cross83bb3162018-06-25 15:48:06 -0700304 linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
Spandan Das6450b552023-02-23 19:27:07 +0000305 // Use minSdkVersion for target-sdk-version, even if `target_sdk_version` is set
306 // This behavior has been copied from Make.
Colin Cross83bb3162018-06-25 15:48:06 -0700307 linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
Colin Crossa97c5d32018-03-28 14:58:31 -0700308
Colin Crossa97c5d32018-03-28 14:58:31 -0700309 // Version code
310 if !hasVersionCode {
Dan Albert4f378d72020-07-23 17:32:15 -0700311 linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
Colin Crossa97c5d32018-03-28 14:58:31 -0700312 }
313
314 if !hasVersionName {
Colin Cross402d5e02018-04-25 14:54:06 -0700315 var versionName string
316 if ctx.ModuleName() == "framework-res" {
317 // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
318 // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
Colin Crossbfd347d2018-05-09 11:11:35 -0700319 // if it contains the build number. Use the PlatformVersionName instead.
320 versionName = ctx.Config().PlatformVersionName()
Colin Cross402d5e02018-04-25 14:54:06 -0700321 } else {
322 versionName = ctx.Config().AppsDefaultVersionName()
323 }
Colin Cross0b9f31f2019-02-28 11:00:01 -0800324 versionName = proptools.NinjaEscape(versionName)
Colin Crossa97c5d32018-03-28 14:58:31 -0700325 linkFlags = append(linkFlags, "--version-name ", versionName)
326 }
327
Colin Crossa0ba2f52019-06-22 12:59:27 -0700328 linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
329
330 // Always set --pseudo-localize, it will be stripped out later for release
331 // builds that don't want it.
332 compileFlags = append(compileFlags, "--pseudo-localize")
333
334 return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
Colin Crossa97c5d32018-03-28 14:58:31 -0700335}
336
Paul Duffin250e6192019-06-07 10:44:37 +0100337func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
Colin Cross42308aa2018-11-14 21:44:17 -0800338 if sdkDep.frameworkResModule != "" {
339 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossa97c5d32018-03-28 14:58:31 -0700340 }
341}
342
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800343var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
344 blueprint.RuleParams{
345 Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
346 CommandDeps: []string{"${config.Zip2ZipCmd}"},
347 })
348
Alixf7a10272023-09-27 16:47:56 +0000349type aaptBuildActionOptions struct {
350 sdkContext android.SdkContext
351 classLoaderContexts dexpreopt.ClassLoaderContextMap
352 excludedLibs []string
353 enforceDefaultTargetSdkVersion bool
Rico Winda2fa2632024-03-13 13:09:17 +0100354 forceNonFinalResourceIDs bool
Alixf7a10272023-09-27 16:47:56 +0000355 extraLinkFlags []string
Jihoon Kang84b25892023-12-01 22:01:06 +0000356 aconfigTextFiles android.Paths
Jiakai Zhang22154d82024-03-28 13:50:43 +0000357 usesLibrary *usesLibrary
Alixf7a10272023-09-27 16:47:56 +0000358}
359
360func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) {
Colin Cross5446e882019-05-22 10:46:27 -0700361
Colin Cross8676c8c2023-10-12 15:58:57 -0700362 staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedExportPackages, libFlags :=
Jiakai Zhang22154d82024-03-28 13:50:43 +0000363 aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts, opts.usesLibrary)
Ulya Trafimovich31e444e2020-08-14 17:32:16 +0100364
Paul Duffin06530572022-02-03 17:54:15 +0000365 // Exclude any libraries from the supplied list.
Alixf7a10272023-09-27 16:47:56 +0000366 opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs)
Paul Duffin06530572022-02-03 17:54:15 +0000367
Colin Cross31656952018-05-24 16:11:20 -0700368 // App manifest file
369 manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
370 manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
371
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000372 manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
Alixf7a10272023-09-27 16:47:56 +0000373 SdkContext: opts.sdkContext,
374 ClassLoaderContexts: opts.classLoaderContexts,
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000375 IsLibrary: a.isLibrary,
376 DefaultManifestVersion: a.defaultManifestVersion,
377 UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
378 UsesNonSdkApis: a.usesNonSdkApis,
379 UseEmbeddedDex: a.useEmbeddedDex,
380 HasNoCode: a.hasNoCode,
381 LoggingParent: a.LoggingParent,
Alixf7a10272023-09-27 16:47:56 +0000382 EnforceDefaultTargetSdkVersion: opts.enforceDefaultTargetSdkVersion,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000383 })
Colin Cross90c25c62019-04-19 16:22:57 -0700384
Colin Crossab8d1382023-07-14 17:23:41 +0000385 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
Colin Cross8676c8c2023-10-12 15:58:57 -0700386 sharedDeps := transitiveAarDeps(sharedResourcesNodesDepSet.ToList())
Colin Crossab8d1382023-07-14 17:23:41 +0000387
Luca Stefanifd898822019-09-10 22:13:31 +0200388 // Add additional manifest files to transitive manifests.
389 additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
Colin Crossab8d1382023-07-14 17:23:41 +0000390 transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
Colin Crossab8d1382023-07-14 17:23:41 +0000391 transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
Colin Cross90c25c62019-04-19 16:22:57 -0700392
Colin Crossab8d1382023-07-14 17:23:41 +0000393 if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
Alixf7a10272023-09-27 16:47:56 +0000394 manifestMergerParams := ManifestMergerParams{
395 staticLibManifests: transitiveManifestPaths[1:],
Alix96ea88452023-08-31 15:48:23 +0000396 isLibrary: a.isLibrary,
397 packageName: a.manifestValues.applicationId,
398 }
Alixf7a10272023-09-27 16:47:56 +0000399 a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], manifestMergerParams)
Colin Cross90c25c62019-04-19 16:22:57 -0700400 if !a.isLibrary {
401 // Only use the merged manifest for applications. For libraries, the transitive closure of manifests
402 // will be propagated to the final application and merged there. The merged manifest for libraries is
403 // only passed to Make, which can't handle transitive dependencies.
404 manifestPath = a.mergedManifestFile
405 }
406 } else {
407 a.mergedManifestFile = manifestPath
408 }
Colin Cross31656952018-05-24 16:11:20 -0700409
Alixf7a10272023-09-27 16:47:56 +0000410 compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, opts.sdkContext, manifestPath)
Colin Cross31656952018-05-24 16:11:20 -0700411
412 linkFlags = append(linkFlags, libFlags...)
Colin Cross8676c8c2023-10-12 15:58:57 -0700413 linkDeps = append(linkDeps, sharedExportPackages...)
Colin Crossab8d1382023-07-14 17:23:41 +0000414 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Alixf7a10272023-09-27 16:47:56 +0000415 linkFlags = append(linkFlags, opts.extraLinkFlags...)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700416 if a.isLibrary {
417 linkFlags = append(linkFlags, "--static-lib")
418 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700419
Colin Cross7c4dc5d2024-02-13 14:29:45 -0800420 linkFlags = append(linkFlags, "--no-static-lib-packages")
Colin Cross8f1b0332024-01-25 13:39:06 -0800421 if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
Colin Cross7c4dc5d2024-02-13 14:29:45 -0800422 // When building an android_library using ResourceProcessorBusyBox pass --merge-only to skip resource
423 // references validation until the final app link step when all static libraries are present.
Colin Cross4eae06d2023-06-20 22:40:02 -0700424 linkFlags = append(linkFlags, "--merge-only")
Colin Cross4eae06d2023-06-20 22:40:02 -0700425 }
426
Colin Crossa97c5d32018-03-28 14:58:31 -0700427 packageRes := android.PathForModuleOut(ctx, "package-res.apk")
Colin Crossa97c5d32018-03-28 14:58:31 -0700428 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
429 rTxt := android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -0700430 // This file isn't used by Soong, but is generated for exporting
431 extraPackages := android.PathForModuleOut(ctx, "extra_packages")
Colin Cross4eae06d2023-06-20 22:40:02 -0700432 var transitiveRJars android.Paths
Colin Crossf3b7bad2023-08-02 15:49:00 -0700433 var srcJar android.WritablePath
Colin Crossa97c5d32018-03-28 14:58:31 -0700434
Colin Cross4aaa84a2018-08-21 15:14:37 -0700435 var compiledResDirs []android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700436 for _, dir := range resDirs {
Colin Cross014489c2020-06-02 20:09:13 -0700437 a.resourceFiles = append(a.resourceFiles, dir.files...)
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900438 compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags, a.filterProduct()).Paths())
Colin Crossa97c5d32018-03-28 14:58:31 -0700439 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700440
Colin Crossa592e3e2019-02-19 16:59:53 -0800441 for i, zip := range resZips {
442 flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
Colin Crossa0ba2f52019-06-22 12:59:27 -0700443 aapt2CompileZip(ctx, flata, zip, "", compileFlags)
Colin Crossa592e3e2019-02-19 16:59:53 -0800444 compiledResDirs = append(compiledResDirs, android.Paths{flata})
445 }
446
Colin Cross4aaa84a2018-08-21 15:14:37 -0700447 var compiledRes, compiledOverlay android.Paths
448
Colin Crossab8d1382023-07-14 17:23:41 +0000449 // AAPT2 overlays are in lowest to highest priority order, reverse the topological order
450 // of transitiveStaticLibs.
451 transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
452
Colin Cross8f1b0332024-01-25 13:39:06 -0800453 if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700454 // When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
455 // as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
456 // instead modules depending on this module will reference package-res.apk from all transitive static
457 // dependencies.
Colin Cross1d3f5902024-03-05 11:51:54 -0800458 for _, sharedDep := range sharedDeps {
459 if sharedDep.usedResourceProcessor {
460 transitiveRJars = append(transitiveRJars, sharedDep.rJar)
461 }
462 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700463 for _, staticDep := range staticDeps {
464 linkDeps = append(linkDeps, staticDep.resPackage)
465 linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
466 if staticDep.usedResourceProcessor {
467 transitiveRJars = append(transitiveRJars, staticDep.rJar)
468 }
469 }
470 } else {
471 // When building an app or building a library without ResourceProcessorBusyBox enabled all static
472 // dependencies are compiled into this module's package-res.apk as overlays.
473 compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
474 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700475
Colin Crossbec85302019-02-13 13:15:46 -0800476 if len(transitiveStaticLibs) > 0 {
Colin Cross4aaa84a2018-08-21 15:14:37 -0700477 // If we are using static android libraries, every source file becomes an overlay.
478 // This is to emulate old AAPT behavior which simulated library support.
479 for _, compiledResDir := range compiledResDirs {
480 compiledOverlay = append(compiledOverlay, compiledResDir...)
481 }
Colin Crossbec85302019-02-13 13:15:46 -0800482 } else if a.isLibrary {
483 // Otherwise, for a static library we treat all the resources equally with no overlay.
484 for _, compiledResDir := range compiledResDirs {
485 compiledRes = append(compiledRes, compiledResDir...)
486 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700487 } else if len(compiledResDirs) > 0 {
488 // Without static libraries, the first directory is our directory, which can then be
489 // overlaid by the rest.
490 compiledRes = append(compiledRes, compiledResDirs[0]...)
491 for _, compiledResDir := range compiledResDirs[1:] {
492 compiledOverlay = append(compiledOverlay, compiledResDir...)
493 }
494 }
495
Colin Crossa97c5d32018-03-28 14:58:31 -0700496 for _, dir := range overlayDirs {
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900497 compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags, a.filterProduct()).Paths()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700498 }
499
Colin Crosse560c4a2019-03-19 16:03:11 -0700500 var splitPackages android.WritablePaths
501 var splits []split
502
503 for _, s := range a.splitNames {
504 suffix := strings.Replace(s, ",", "_", -1)
505 path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
506 linkFlags = append(linkFlags, "--split", path.String()+":"+s)
507 splitPackages = append(splitPackages, path)
508 splits = append(splits, split{
509 name: s,
510 suffix: suffix,
511 path: path,
512 })
513 }
514
Colin Cross8f1b0332024-01-25 13:39:06 -0800515 if !a.useResourceProcessorBusyBox(ctx) {
Colin Crossf3b7bad2023-08-02 15:49:00 -0700516 // the subdir "android" is required to be filtered by package names
517 srcJar = android.PathForModuleGen(ctx, "android", "R.srcjar")
518 }
519
Colin Crossab8d1382023-07-14 17:23:41 +0000520 // No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
521 // provided to the final app aapt2Link step.
522 var transitiveAssets android.Paths
523 if !a.isLibrary {
524 transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
525 }
Colin Crossf3b7bad2023-08-02 15:49:00 -0700526 aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
Jihoon Kang84b25892023-12-01 22:01:06 +0000527 linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages,
528 opts.aconfigTextFiles)
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800529 // Extract assets from the resource package output so that they can be used later in aapt2link
530 // for modules that depend on this one.
Colin Crossab8d1382023-07-14 17:23:41 +0000531 if android.PrefixInList(linkFlags, "-A ") {
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800532 assets := android.PathForModuleOut(ctx, "assets.zip")
533 ctx.Build(pctx, android.BuildParams{
534 Rule: extractAssetsRule,
535 Input: packageRes,
536 Output: assets,
537 Description: "extract assets from built resource file",
538 })
539 a.assetPackage = android.OptionalPathForPath(assets)
540 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700541
Colin Cross8f1b0332024-01-25 13:39:06 -0800542 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700543 rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
Rico Winda2fa2632024-03-13 13:09:17 +0100544 resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags,
545 opts.forceNonFinalResourceIDs)
Colin Crossf3b7bad2023-08-02 15:49:00 -0700546 aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700547 transitiveRJars = append(transitiveRJars, rJar)
548 a.rJar = rJar
Colin Crossf3b7bad2023-08-02 15:49:00 -0700549 } else {
550 aapt2ExtractExtraPackages(ctx, extraPackages, srcJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700551 }
552
Colin Cross312634e2023-11-21 15:13:56 -0800553 transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
554 transitiveAaptResourcePackages = slices.DeleteFunc(transitiveAaptResourcePackages, func(p string) bool {
555 return p == packageRes.String()
556 })
557 transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
558 android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
559
Colin Cross1d3f5902024-03-05 11:51:54 -0800560 // Reverse the list of R.jar files so that the current module comes first, and direct dependencies come before
561 // transitive dependencies.
562 transitiveRJars = android.ReversePaths(transitiveRJars)
563
Colin Crossa97c5d32018-03-28 14:58:31 -0700564 a.aaptSrcJar = srcJar
Colin Cross4eae06d2023-06-20 22:40:02 -0700565 a.transitiveAaptRJars = transitiveRJars
Colin Cross312634e2023-11-21 15:13:56 -0800566 a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
Colin Crossa97c5d32018-03-28 14:58:31 -0700567 a.exportPackage = packageRes
568 a.manifestPath = manifestPath
569 a.proguardOptionsFile = proguardOptionsFile
Colin Cross66f78822018-05-02 12:58:28 -0700570 a.extraAaptPackagesFile = extraPackages
Colin Crossa97c5d32018-03-28 14:58:31 -0700571 a.rTxt = rTxt
Colin Crosse560c4a2019-03-19 16:03:11 -0700572 a.splits = splits
Colin Crossab8d1382023-07-14 17:23:41 +0000573 a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL).
574 Direct(&resourcesNode{
575 resPackage: a.exportPackage,
576 manifest: a.manifestPath,
577 additionalManifests: additionalManifests,
Colin Cross4eae06d2023-06-20 22:40:02 -0700578 rTxt: a.rTxt,
579 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +0000580 assets: a.assetPackage,
Colin Cross4eae06d2023-06-20 22:40:02 -0700581
Colin Cross8f1b0332024-01-25 13:39:06 -0800582 usedResourceProcessor: a.useResourceProcessorBusyBox(ctx),
Colin Crossab8d1382023-07-14 17:23:41 +0000583 }).
584 Transitive(staticResourcesNodesDepSet).Build()
585 a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
586 Direct(rroDirs...).
587 Transitive(staticRRODirsDepSet).Build()
588 a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
589 Direct(a.manifestPath).
590 DirectSlice(additionalManifests).
591 Transitive(staticManifestsDepSet).Build()
592}
593
Colin Cross4eae06d2023-06-20 22:40:02 -0700594var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
595 blueprint.RuleParams{
596 Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
597 "com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
598 "if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
599 CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
600 Rspfile: "${out}.args",
601 RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
602 Restat: true,
603 }, "rTxt", "manifest", "args")
604
605// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
606// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
607// supports producing classes for static dependencies that only include resources from that dependency.
608func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
Rico Winda2fa2632024-03-13 13:09:17 +0100609 rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string,
610 forceNonFinalIds bool) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700611
612 var args []string
613 var deps android.Paths
614
615 if !isLibrary {
616 // When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
617 // to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
618 // package.
619 args, deps = transitiveDeps.resourceProcessorDeps()
Rico Winda2fa2632024-03-13 13:09:17 +0100620 if forceNonFinalIds {
621 args = append(args, "--finalFields=false")
622 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700623 } else {
624 // When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
625 // library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
626 // inlined into the library before the final IDs are assigned during app compilation.
627 args = append(args, "--finalFields=false")
628 }
629
Colin Crossd3f7d1a2024-01-03 19:42:25 -0800630 for i, arg := range aaptFlags {
631 const AAPT_CUSTOM_PACKAGE = "--custom-package"
632 if strings.HasPrefix(arg, AAPT_CUSTOM_PACKAGE) {
633 pkg := strings.TrimSpace(strings.TrimPrefix(arg, AAPT_CUSTOM_PACKAGE))
634 if pkg == "" && i+1 < len(aaptFlags) {
635 pkg = aaptFlags[i+1]
636 }
637 args = append(args, "--packageForR "+pkg)
638 }
639 }
640
Colin Cross4eae06d2023-06-20 22:40:02 -0700641 deps = append(deps, rTxt, manifest)
642
643 ctx.Build(pctx, android.BuildParams{
644 Rule: resourceProcessorBusyBox,
645 Output: rJar,
646 Implicits: deps,
647 Description: "ResourceProcessorBusyBox",
648 Args: map[string]string{
649 "rTxt": rTxt.String(),
650 "manifest": manifest.String(),
651 "args": strings.Join(args, " "),
652 },
653 })
654}
655
Colin Crossab8d1382023-07-14 17:23:41 +0000656type resourcesNode struct {
657 resPackage android.Path
658 manifest android.Path
659 additionalManifests android.Paths
Colin Cross4eae06d2023-06-20 22:40:02 -0700660 rTxt android.Path
661 rJar android.Path
Colin Crossab8d1382023-07-14 17:23:41 +0000662 assets android.OptionalPath
Colin Cross4eae06d2023-06-20 22:40:02 -0700663
664 usedResourceProcessor bool
Colin Crossab8d1382023-07-14 17:23:41 +0000665}
666
667type transitiveAarDeps []*resourcesNode
668
669func (t transitiveAarDeps) resPackages() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700670 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000671 for _, dep := range t {
672 paths = append(paths, dep.resPackage)
673 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700674 return paths
Colin Crossab8d1382023-07-14 17:23:41 +0000675}
676
677func (t transitiveAarDeps) manifests() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700678 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000679 for _, dep := range t {
680 paths = append(paths, dep.manifest)
681 paths = append(paths, dep.additionalManifests...)
682 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700683 return paths
684}
685
686func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
687 for _, dep := range t {
688 args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
689 deps = append(deps, dep.rTxt, dep.manifest)
690 }
691 return args, deps
Colin Crossab8d1382023-07-14 17:23:41 +0000692}
693
694func (t transitiveAarDeps) assets() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700695 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000696 for _, dep := range t {
697 if dep.assets.Valid() {
698 paths = append(paths, dep.assets.Path())
699 }
700 }
701 return paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700702}
703
704// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
Jiakai Zhang22154d82024-03-28 13:50:43 +0000705func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext,
706 classLoaderContexts dexpreopt.ClassLoaderContextMap, usesLibrary *usesLibrary) (
Colin Cross8676c8c2023-10-12 15:58:57 -0700707 staticResourcesNodes, sharedResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
Colin Crossab8d1382023-07-14 17:23:41 +0000708 staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700709
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100710 if classLoaderContexts == nil {
Ulya Trafimovich18554242020-11-03 15:55:11 +0000711 // Not all callers need to compute class loader context, those who don't just pass nil.
712 // Create a temporary class loader context here (it will be computed, but not used).
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100713 classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000714 }
715
Colin Cross83bb3162018-06-25 15:48:06 -0700716 sdkDep := decodeSdkDep(ctx, sdkContext)
Colin Crossa97c5d32018-03-28 14:58:31 -0700717 if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700718 sharedLibs = append(sharedLibs, sdkDep.jars...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700719 }
720
Colin Cross8676c8c2023-10-12 15:58:57 -0700721 var staticResourcesNodeDepSets []*android.DepSet[*resourcesNode]
722 var sharedResourcesNodeDepSets []*android.DepSet[*resourcesNode]
Colin Crossab8d1382023-07-14 17:23:41 +0000723 rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL)
724 manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL)
725
Colin Crossa97c5d32018-03-28 14:58:31 -0700726 ctx.VisitDirectDeps(func(module android.Module) {
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000727 depTag := ctx.OtherModuleDependencyTag(module)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000728
Colin Crossa97c5d32018-03-28 14:58:31 -0700729 var exportPackage android.Path
Colin Cross66f78822018-05-02 12:58:28 -0700730 aarDep, _ := module.(AndroidLibraryDependency)
731 if aarDep != nil {
Colin Crossa97c5d32018-03-28 14:58:31 -0700732 exportPackage = aarDep.ExportPackage()
733 }
734
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000735 switch depTag {
Colin Cross4b964c02018-10-15 16:18:06 -0700736 case instrumentationForTag:
737 // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
Liz Kammeref28a4c2022-09-23 16:50:56 -0400738 case sdkLibTag, libTag:
Colin Cross5446e882019-05-22 10:46:27 -0700739 if exportPackage != nil {
Colin Cross8676c8c2023-10-12 15:58:57 -0700740 sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
Colin Cross5446e882019-05-22 10:46:27 -0700741 sharedLibs = append(sharedLibs, exportPackage)
742 }
Colin Cross5446e882019-05-22 10:46:27 -0700743 case frameworkResTag:
Colin Crossa97c5d32018-03-28 14:58:31 -0700744 if exportPackage != nil {
745 sharedLibs = append(sharedLibs, exportPackage)
746 }
747 case staticLibTag:
748 if exportPackage != nil {
Colin Cross8676c8c2023-10-12 15:58:57 -0700749 staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
Colin Crossab8d1382023-07-14 17:23:41 +0000750 rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
751 manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
Colin Crossa97c5d32018-03-28 14:58:31 -0700752 }
753 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000754
Ulya Trafimovich88bb6f62020-12-16 16:16:11 +0000755 addCLCFromDep(ctx, module, classLoaderContexts)
Jiakai Zhang22154d82024-03-28 13:50:43 +0000756 if usesLibrary != nil {
757 addMissingOptionalUsesLibsFromDep(ctx, module, usesLibrary)
758 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700759 })
760
Colin Crossab8d1382023-07-14 17:23:41 +0000761 // AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
762 // Reverse the dependency order now going into the depset so that it comes out in order after the second
763 // reverse later.
764 // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
765 // dependencies) the highest priority dependency is listed first, but for resources the highest priority
Colin Cross9055e212024-03-23 04:43:41 +0000766 // dependency has to be listed last. This is also inconsistent with the way manifests from the same
767 // transitive dependencies are merged.
Colin Crossab8d1382023-07-14 17:23:41 +0000768 staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
Colin Cross8676c8c2023-10-12 15:58:57 -0700769 android.ReverseSliceInPlace(staticResourcesNodeDepSets))
770 sharedResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
771 android.ReverseSliceInPlace(sharedResourcesNodeDepSets))
Colin Crossa97c5d32018-03-28 14:58:31 -0700772
Colin Crossab8d1382023-07-14 17:23:41 +0000773 staticRRODirs = rroDirsDepSetBuilder.Build()
774 staticManifests = manifestsDepSetBuilder.Build()
775
776 if len(staticResourcesNodes.ToList()) > 0 {
Colin Crossa97c5d32018-03-28 14:58:31 -0700777 flags = append(flags, "--auto-add-overlay")
778 }
779
780 for _, sharedLib := range sharedLibs {
781 flags = append(flags, "-I "+sharedLib.String())
782 }
783
Colin Cross8676c8c2023-10-12 15:58:57 -0700784 return staticResourcesNodes, sharedResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
Colin Crossa97c5d32018-03-28 14:58:31 -0700785}
786
787type AndroidLibrary struct {
788 Library
789 aapt
790
791 androidLibraryProperties androidLibraryProperties
792
793 aarFile android.WritablePath
Colin Cross89c31582018-04-30 15:55:11 -0700794}
795
Saeid Farivar Asanjan1fca3012021-09-14 18:40:19 +0000796var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
797
798// For OutputFileProducer interface
799func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
800 switch tag {
801 case ".aar":
802 return []android.Path{a.aarFile}, nil
803 default:
804 return a.Library.OutputFiles(tag)
805 }
806}
807
Colin Crossa97c5d32018-03-28 14:58:31 -0700808var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
809
810func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiakai Zhang3ef72832024-03-28 11:52:08 +0000811 a.usesLibrary.deps(ctx, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700812 a.Module.deps(ctx)
Jiyong Parkf1691d22021-03-29 20:11:58 +0900813 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Paul Duffin250e6192019-06-07 10:44:37 +0100814 if sdkDep.hasFrameworkLibs() {
815 a.aapt.deps(ctx, sdkDep)
Colin Crossa97c5d32018-03-28 14:58:31 -0700816 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000817
818 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
819 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
820 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700821}
822
823func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosse4246ab2019-02-05 21:55:21 -0800824 a.aapt.isLibrary = true
Ulya Trafimovich42c7f0d2021-08-17 16:20:29 +0100825 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000826 if a.usesLibrary.shouldDisableDexpreopt {
827 a.dexpreopter.disableDexpreopt()
828 }
Alixf7a10272023-09-27 16:47:56 +0000829 a.aapt.buildActions(ctx,
830 aaptBuildActionOptions{
831 sdkContext: android.SdkContext(a),
832 classLoaderContexts: a.classLoaderContexts,
833 enforceDefaultTargetSdkVersion: false,
Jihoon Kang9049c272024-03-19 21:57:36 +0000834 aconfigTextFiles: getAconfigFilePaths(ctx),
Jiakai Zhang22154d82024-03-28 13:50:43 +0000835 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000836 },
837 )
Colin Crossa97c5d32018-03-28 14:58:31 -0700838
Colin Crossff694a82023-12-13 15:54:49 -0800839 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
840 a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
Colin Cross56a83212020-09-15 18:30:11 -0700841
yangbill2af0b6e2024-03-15 09:29:29 +0000842 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000843
Colin Cross4eae06d2023-06-20 22:40:02 -0700844 ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
845 ctx.CheckbuildFile(a.aapt.exportPackage)
Colin Cross8f1b0332024-01-25 13:39:06 -0800846 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700847 ctx.CheckbuildFile(a.aapt.rJar)
Colin Crossf3b7bad2023-08-02 15:49:00 -0700848 } else {
849 ctx.CheckbuildFile(a.aapt.aaptSrcJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700850 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700851
852 // apps manifests are handled by aapt, don't let Module see them
853 a.properties.Manifest = nil
854
Colin Cross014489c2020-06-02 20:09:13 -0700855 a.linter.mergedManifest = a.aapt.mergedManifestFile
856 a.linter.manifest = a.aapt.manifestPath
857 a.linter.resources = a.aapt.resourceFiles
858
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000859 proguardSpecInfo := a.collectProguardSpecInfo(ctx)
Colin Cross40213022023-12-13 15:19:49 -0800860 android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo)
Colin Cross312634e2023-11-21 15:13:56 -0800861 exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList()
862 a.extraProguardFlagsFiles = append(a.extraProguardFlagsFiles, exportedProguardFlagsFiles...)
863 a.extraProguardFlagsFiles = append(a.extraProguardFlagsFiles, a.proguardOptionsFile)
864
865 combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags")
866 writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles)
867 a.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile
Colin Crossa97c5d32018-03-28 14:58:31 -0700868
Colin Cross4eae06d2023-06-20 22:40:02 -0700869 var extraSrcJars android.Paths
870 var extraCombinedJars android.Paths
871 var extraClasspathJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800872 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700873 // When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
874 // library and each of the transitive static android_library dependencies has already created an
875 // R.class file for the appropriate package. Add all of those R.class files to the classpath.
876 extraClasspathJars = a.transitiveAaptRJars
877 } else {
878 // When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
879 // R.java files for the library's package and the packages from all transitive static android_library
880 // dependencies. Compile the srcjar alongside the rest of the sources.
881 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
882 }
883
884 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
Colin Crossa97c5d32018-03-28 14:58:31 -0700885
Colin Crossf57c5782019-01-25 13:20:38 -0800886 a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
Colin Crossa97c5d32018-03-28 14:58:31 -0700887 var res android.Paths
888 if a.androidLibraryProperties.BuildAAR {
889 BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
890 ctx.CheckbuildFile(a.aarFile)
891 }
Colin Cross89c31582018-04-30 15:55:11 -0700892
Sam Delmerico82602492022-06-10 17:05:42 +0000893 prebuiltJniPackages := android.Paths{}
894 ctx.VisitDirectDeps(func(module android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800895 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +0000896 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
897 }
898 })
899 if len(prebuiltJniPackages) > 0 {
Colin Cross40213022023-12-13 15:19:49 -0800900 android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
Sam Delmerico82602492022-06-10 17:05:42 +0000901 JniPackages: prebuiltJniPackages,
902 })
903 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700904}
905
Colin Cross95b53b82023-10-17 13:21:02 -0700906func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) {
907 a.Library.IDEInfo(dpInfo)
908 a.aapt.IDEInfo(dpInfo)
909}
910
911func (a *aapt) IDEInfo(dpInfo *android.IdeInfo) {
Colin Cross8f1b0332024-01-25 13:39:06 -0800912 if a.rJar != nil {
Colin Cross95b53b82023-10-17 13:21:02 -0700913 dpInfo.Jars = append(dpInfo.Jars, a.rJar.String())
914 }
915}
916
Colin Cross1b16b0e2019-02-12 14:41:32 -0800917// android_library builds and links sources into a `.jar` file for the device along with Android resources.
918//
919// An android_library has a single variant that produces a `.jar` file containing `.class` files that were
Sam Delmerico82602492022-06-10 17:05:42 +0000920// compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
Colin Cross1b16b0e2019-02-12 14:41:32 -0800921// with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
922// an android_app module.
Colin Crossa97c5d32018-03-28 14:58:31 -0700923func AndroidLibraryFactory() android.Module {
924 module := &AndroidLibrary{}
925
Colin Crossce6734e2020-06-15 16:09:53 -0700926 module.Module.addHostAndDeviceProperties()
Colin Crossa97c5d32018-03-28 14:58:31 -0700927 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -0700928 &module.aaptProperties,
929 &module.androidLibraryProperties)
930
931 module.androidLibraryProperties.BuildAAR = true
Colin Cross014489c2020-06-02 20:09:13 -0700932 module.Module.linter.library = true
Colin Crossa97c5d32018-03-28 14:58:31 -0700933
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900934 android.InitApexModule(module)
Colin Cross48de9a42018-10-02 13:53:33 -0700935 InitJavaModule(module, android.DeviceSupported)
Colin Crossa97c5d32018-03-28 14:58:31 -0700936 return module
937}
938
Colin Crossfabb6082018-02-20 17:22:23 -0800939//
940// AAR (android library) prebuilts
941//
Colin Crossfabb6082018-02-20 17:22:23 -0800942
Vinh Trance0781f2022-04-13 01:30:44 +0000943// Properties for android_library_import
Colin Crossfabb6082018-02-20 17:22:23 -0800944type AARImportProperties struct {
Vinh Trance0781f2022-04-13 01:30:44 +0000945 // ARR (android library prebuilt) filepath. Exactly one ARR is required.
Colin Cross27b922f2019-03-04 22:35:41 -0800946 Aars []string `android:"path"`
Vinh Trance0781f2022-04-13 01:30:44 +0000947 // If not blank, set to the version of the sdk to compile against.
948 // Defaults to private.
949 // Values are of one of the following forms:
950 // 1) numerical API level, "current", "none", or "core_platform"
951 // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
952 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
953 // If the SDK kind is empty, it will be set to public
954 Sdk_version *string
955 // If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
956 // Defaults to sdk_version if not set. See sdk_version for possible values.
Colin Cross479884c2018-07-10 13:39:30 -0700957 Min_sdk_version *string
Vinh Trance0781f2022-04-13 01:30:44 +0000958 // List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
Colin Crossa97c5d32018-03-28 14:58:31 -0700959 Static_libs []string
Vinh Trance0781f2022-04-13 01:30:44 +0000960 // List of java libraries that the included ARR (android library prebuilts) has dependencies to.
961 Libs []string
962 // If set to true, run Jetifier against .aar file. Defaults to false.
Colin Cross1001a792019-03-21 22:21:39 -0700963 Jetifier *bool
Sam Delmerico82602492022-06-10 17:05:42 +0000964 // If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and
965 // will be passed transitively through android_libraries to an android_app.
966 //TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
967 Extract_jni *bool
Colin Crossfabb6082018-02-20 17:22:23 -0800968}
969
970type AARImport struct {
971 android.ModuleBase
Colin Cross48de9a42018-10-02 13:53:33 -0700972 android.DefaultableModuleBase
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900973 android.ApexModuleBase
Colin Crossfabb6082018-02-20 17:22:23 -0800974 prebuilt android.Prebuilt
975
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900976 // Functionality common to Module and Import.
977 embeddableInModuleAndImport
978
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500979 providesTransitiveHeaderJars
980
Colin Crossfabb6082018-02-20 17:22:23 -0800981 properties AARImportProperties
982
Colin Cross9055e212024-03-23 04:43:41 +0000983 headerJarFile android.WritablePath
984 implementationJarFile android.WritablePath
Colin Cross312634e2023-11-21 15:13:56 -0800985 proguardFlags android.WritablePath
986 exportPackage android.WritablePath
987 transitiveAaptResourcePackagesFile android.Path
988 extraAaptPackagesFile android.WritablePath
989 manifest android.WritablePath
990 assetsPackage android.WritablePath
991 rTxt android.WritablePath
992 rJar android.WritablePath
Colin Cross66f78822018-05-02 12:58:28 -0700993
Colin Crossab8d1382023-07-14 17:23:41 +0000994 resourcesNodesDepSet *android.DepSet[*resourcesNode]
995 manifestsDepSet *android.DepSet[android.Path]
Colin Cross56a83212020-09-15 18:30:11 -0700996
997 hideApexVariantFromMake bool
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +0000998
Sam Delmerico82602492022-06-10 17:05:42 +0000999 aarPath android.Path
1000 jniPackages android.Paths
Jiyong Park92315372021-04-02 08:45:46 +09001001
1002 sdkVersion android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001003 minSdkVersion android.ApiLevel
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001004
Colin Cross9055e212024-03-23 04:43:41 +00001005 usesLibrary
1006 classLoaderContexts dexpreopt.ClassLoaderContextMap
1007
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001008 // Single aconfig "cache file" merged from this module and all dependencies.
1009 mergedAconfigFiles map[string]android.Paths
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001010}
1011
1012var _ android.OutputFileProducer = (*AARImport)(nil)
1013
1014// For OutputFileProducer interface
1015func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
1016 switch tag {
1017 case ".aar":
1018 return []android.Path{a.aarPath}, nil
1019 case "":
Colin Cross9055e212024-03-23 04:43:41 +00001020 return []android.Path{a.implementationJarFile}, nil
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001021 default:
1022 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1023 }
Colin Crossfabb6082018-02-20 17:22:23 -08001024}
1025
Jiyong Park92315372021-04-02 08:45:46 +09001026func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
1027 return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -07001028}
1029
Jiyong Parkf1691d22021-03-29 20:11:58 +09001030func (a *AARImport) SystemModules() string {
Paul Duffine25c6442019-10-11 13:50:28 +01001031 return ""
1032}
1033
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001034func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Colin Cross479884c2018-07-10 13:39:30 -07001035 if a.properties.Min_sdk_version != nil {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001036 return android.ApiLevelFrom(ctx, *a.properties.Min_sdk_version)
Colin Cross479884c2018-07-10 13:39:30 -07001037 }
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001038 return a.SdkVersion(ctx).ApiLevel
Colin Cross83bb3162018-06-25 15:48:06 -07001039}
1040
Spandan Dasa26eda72023-03-02 00:56:06 +00001041func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
1042 return android.SdkSpecFrom(ctx, "").ApiLevel
William Loh5a082f92022-05-17 20:21:50 +00001043}
1044
Spandan Dasca70fc42023-03-01 23:38:49 +00001045func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
1046 return a.SdkVersion(ctx).ApiLevel
Dan Willemsen419290a2018-10-31 15:28:47 -07001047}
1048
Colin Cross1e743852019-10-28 11:37:20 -07001049func (a *AARImport) javaVersion() string {
1050 return ""
1051}
1052
Colin Crossa97c5d32018-03-28 14:58:31 -07001053var _ AndroidLibraryDependency = (*AARImport)(nil)
1054
1055func (a *AARImport) ExportPackage() android.Path {
1056 return a.exportPackage
1057}
Colin Crossab8d1382023-07-14 17:23:41 +00001058func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
1059 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -08001060}
1061
Colin Crossab8d1382023-07-14 17:23:41 +00001062func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] {
1063 return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil)
Colin Cross66f78822018-05-02 12:58:28 -07001064}
1065
Colin Crossab8d1382023-07-14 17:23:41 +00001066func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] {
1067 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -08001068}
1069
Jaewoong Jungc779cd42020-10-06 18:56:10 -07001070// RRO enforcement is not available on aar_import since its RRO dirs are not
1071// exported.
1072func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
1073}
1074
1075// RRO enforcement is not available on aar_import since its RRO dirs are not
1076// exported.
1077func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
1078 return false
1079}
1080
Colin Crossfabb6082018-02-20 17:22:23 -08001081func (a *AARImport) Prebuilt() *android.Prebuilt {
1082 return &a.prebuilt
1083}
1084
1085func (a *AARImport) Name() string {
1086 return a.prebuilt.Name(a.ModuleBase.Name())
1087}
1088
Jiyong Park618922e2020-01-08 13:35:43 +09001089func (a *AARImport) JacocoReportClassesFile() android.Path {
1090 return nil
1091}
1092
Colin Crossfabb6082018-02-20 17:22:23 -08001093func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
Jeongik Cha816a23a2020-07-08 01:09:23 +09001094 if !ctx.Config().AlwaysUsePrebuiltSdks() {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001095 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Colin Crossa97c5d32018-03-28 14:58:31 -07001096 if sdkDep.useModule && sdkDep.frameworkResModule != "" {
Colin Cross42d48b72018-08-29 14:10:52 -07001097 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossfabb6082018-02-20 17:22:23 -08001098 }
1099 }
Colin Crossa97c5d32018-03-28 14:58:31 -07001100
Colin Cross42d48b72018-08-29 14:10:52 -07001101 ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
1102 ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
Colin Cross9055e212024-03-23 04:43:41 +00001103
1104 a.usesLibrary.deps(ctx, false)
Colin Crossfabb6082018-02-20 17:22:23 -08001105}
1106
Sam Delmerico82602492022-06-10 17:05:42 +00001107type JniPackageInfo struct {
1108 // List of zip files containing JNI libraries
1109 // Zip files should have directory structure jni/<arch>/*.so
1110 JniPackages android.Paths
1111}
1112
Colin Crossbc7d76c2023-12-12 16:39:03 -08001113var JniPackageProvider = blueprint.NewProvider[JniPackageInfo]()
Sam Delmerico82602492022-06-10 17:05:42 +00001114
1115// Unzip an AAR and extract the JNI libs for $archString.
1116var extractJNI = pctx.AndroidStaticRule("extractJNI",
1117 blueprint.RuleParams{
1118 Command: `rm -rf $out $outDir && touch $out && ` +
1119 `unzip -qoDD -d $outDir $in "jni/${archString}/*" && ` +
1120 `jni_files=$$(find $outDir/jni -type f) && ` +
1121 // print error message if there are no JNI libs for this arch
1122 `[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` +
Sam Delmerico80ee45c2023-06-22 15:36:02 -04001123 `${config.SoongZipCmd} -o $out -L 0 -P 'lib/${archString}' ` +
Sam Delmerico82602492022-06-10 17:05:42 +00001124 `-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`,
1125 CommandDeps: []string{"${config.SoongZipCmd}"},
1126 },
1127 "outDir", "archString")
1128
Colin Crossfabb6082018-02-20 17:22:23 -08001129// Unzip an AAR into its constituent files and directories. Any files in Outputs that don't exist in the AAR will be
Dan Willemsen304cfec2019-05-28 14:49:06 -07001130// touched to create an empty file. The res directory is not extracted, as it will be extracted in its own rule.
Colin Crossfabb6082018-02-20 17:22:23 -08001131var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
1132 blueprint.RuleParams{
Dan Willemsen304cfec2019-05-28 14:49:06 -07001133 Command: `rm -rf $outDir && mkdir -p $outDir && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001134 `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001135 `${config.Zip2ZipCmd} -i $in -o $assetsPackage 'assets/**/*' && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001136 `${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001137 CommandDeps: []string{"${config.MergeZipsCmd}", "${config.Zip2ZipCmd}"},
Colin Crossfabb6082018-02-20 17:22:23 -08001138 },
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001139 "outDir", "combinedClassesJar", "assetsPackage")
Colin Crossfabb6082018-02-20 17:22:23 -08001140
1141func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1142 if len(a.properties.Aars) != 1 {
1143 ctx.PropertyErrorf("aars", "exactly one aar is required")
1144 return
1145 }
1146
Jiyong Park92315372021-04-02 08:45:46 +09001147 a.sdkVersion = a.SdkVersion(ctx)
1148 a.minSdkVersion = a.MinSdkVersion(ctx)
1149
Colin Crossff694a82023-12-13 15:54:49 -08001150 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
1151 a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
Colin Cross56a83212020-09-15 18:30:11 -07001152
Nan Zhang4c819fb2018-08-27 18:31:46 -07001153 aarName := ctx.ModuleName() + ".aar"
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001154 a.aarPath = android.PathForModuleSrc(ctx, a.properties.Aars[0])
1155
Colin Cross1001a792019-03-21 22:21:39 -07001156 if Bool(a.properties.Jetifier) {
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001157 inputFile := a.aarPath
1158 a.aarPath = android.PathForModuleOut(ctx, "jetifier", aarName)
1159 TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile)
Nan Zhang4c819fb2018-08-27 18:31:46 -07001160 }
Colin Crossfabb6082018-02-20 17:22:23 -08001161
1162 extractedAARDir := android.PathForModuleOut(ctx, "aar")
Colin Cross9055e212024-03-23 04:43:41 +00001163 classpathFile := extractedAARDir.Join(ctx, "classes-combined.jar")
Colin Cross10f7c4a2018-05-23 10:59:28 -07001164 a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
Colin Crossbb77d8e2024-02-15 14:43:47 -08001165 a.rTxt = extractedAARDir.Join(ctx, "R.txt")
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001166 a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
Sam Delmerico95d70942023-08-02 18:00:35 -04001167 a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
Colin Cross40213022023-12-13 15:19:49 -08001168 android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
Sam Delmerico95d70942023-08-02 18:00:35 -04001169 ProguardFlagsFiles: android.NewDepSet[android.Path](
1170 android.POSTORDER,
1171 android.Paths{a.proguardFlags},
1172 nil,
1173 ),
1174 })
Colin Crossfabb6082018-02-20 17:22:23 -08001175
1176 ctx.Build(pctx, android.BuildParams{
1177 Rule: unzipAAR,
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001178 Input: a.aarPath,
Colin Cross9055e212024-03-23 04:43:41 +00001179 Outputs: android.WritablePaths{classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt},
Colin Crossfabb6082018-02-20 17:22:23 -08001180 Description: "unzip AAR",
1181 Args: map[string]string{
Colin Cross205e9112020-08-06 13:20:17 -07001182 "outDir": extractedAARDir.String(),
Colin Cross9055e212024-03-23 04:43:41 +00001183 "combinedClassesJar": classpathFile.String(),
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001184 "assetsPackage": a.assetsPackage.String(),
Colin Crossfabb6082018-02-20 17:22:23 -08001185 },
1186 })
1187
Colin Crossa0ba2f52019-06-22 12:59:27 -07001188 // Always set --pseudo-localize, it will be stripped out later for release
1189 // builds that don't want it.
1190 compileFlags := []string{"--pseudo-localize"}
Colin Crossfabb6082018-02-20 17:22:23 -08001191 compiledResDir := android.PathForModuleOut(ctx, "flat-res")
Colin Crossfabb6082018-02-20 17:22:23 -08001192 flata := compiledResDir.Join(ctx, "gen_res.flata")
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001193 aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
Colin Crossfabb6082018-02-20 17:22:23 -08001194
1195 a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
Colin Crossfabb6082018-02-20 17:22:23 -08001196 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
Colin Crossbb77d8e2024-02-15 14:43:47 -08001197 aaptRTxt := android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -07001198 a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
Colin Crossfabb6082018-02-20 17:22:23 -08001199
1200 var linkDeps android.Paths
1201
1202 linkFlags := []string{
1203 "--static-lib",
Colin Cross4eae06d2023-06-20 22:40:02 -07001204 "--merge-only",
Colin Crossfabb6082018-02-20 17:22:23 -08001205 "--auto-add-overlay",
Colin Cross7c4dc5d2024-02-13 14:29:45 -08001206 "--no-static-lib-packages",
Colin Crossfabb6082018-02-20 17:22:23 -08001207 }
1208
Colin Cross10f7c4a2018-05-23 10:59:28 -07001209 linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
1210 linkDeps = append(linkDeps, a.manifest)
Colin Crossfabb6082018-02-20 17:22:23 -08001211
Colin Cross8676c8c2023-10-12 15:58:57 -07001212 staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
Jiakai Zhang22154d82024-03-28 13:50:43 +00001213 aaptLibs(ctx, android.SdkContext(a), nil, nil)
Colin Cross31656952018-05-24 16:11:20 -07001214
Colin Cross8676c8c2023-10-12 15:58:57 -07001215 _ = sharedResourcesNodesDepSet
Colin Crossab8d1382023-07-14 17:23:41 +00001216 _ = staticRRODirsDepSet
Colin Cross8676c8c2023-10-12 15:58:57 -07001217
Colin Crossab8d1382023-07-14 17:23:41 +00001218 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
Colin Crossfabb6082018-02-20 17:22:23 -08001219
Colin Crossab8d1382023-07-14 17:23:41 +00001220 linkDeps = append(linkDeps, sharedLibs...)
Colin Cross4eae06d2023-06-20 22:40:02 -07001221 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -07001222 linkFlags = append(linkFlags, libFlags...)
Colin Crossfabb6082018-02-20 17:22:23 -08001223
Colin Cross4eae06d2023-06-20 22:40:02 -07001224 overlayRes := android.Paths{flata}
1225
1226 // Treat static library dependencies of static libraries as imports.
1227 transitiveStaticLibs := staticDeps.resPackages()
1228 linkDeps = append(linkDeps, transitiveStaticLibs...)
1229 for _, staticLib := range transitiveStaticLibs {
1230 linkFlags = append(linkFlags, "-I "+staticLib.String())
1231 }
Colin Crossfabb6082018-02-20 17:22:23 -08001232
Colin Crossab8d1382023-07-14 17:23:41 +00001233 transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
Colin Crossbb77d8e2024-02-15 14:43:47 -08001234 aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, aaptRTxt,
Jihoon Kang84b25892023-12-01 22:01:06 +00001235 linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001236
Colin Cross4eae06d2023-06-20 22:40:02 -07001237 a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
Rico Winda2fa2632024-03-13 13:09:17 +01001238 resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil, false)
Colin Cross4eae06d2023-06-20 22:40:02 -07001239
Colin Crossf3b7bad2023-08-02 15:49:00 -07001240 aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
1241
Colin Crossab8d1382023-07-14 17:23:41 +00001242 resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
1243 resourcesNodesDepSetBuilder.Direct(&resourcesNode{
1244 resPackage: a.exportPackage,
1245 manifest: a.manifest,
Colin Cross4eae06d2023-06-20 22:40:02 -07001246 rTxt: a.rTxt,
1247 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +00001248 assets: android.OptionalPathForPath(a.assetsPackage),
Colin Cross4eae06d2023-06-20 22:40:02 -07001249
1250 usedResourceProcessor: true,
Colin Crossab8d1382023-07-14 17:23:41 +00001251 })
1252 resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
1253 a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
1254
1255 manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
Colin Cross9055e212024-03-23 04:43:41 +00001256 manifestDepSetBuilder.Transitive(staticManifestsDepSet)
Colin Crossab8d1382023-07-14 17:23:41 +00001257 a.manifestsDepSet = manifestDepSetBuilder.Build()
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001258
Colin Cross312634e2023-11-21 15:13:56 -08001259 transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
1260 transitiveAaptResourcePackages = slices.DeleteFunc(transitiveAaptResourcePackages, func(p string) bool {
1261 return p == a.exportPackage.String()
1262 })
1263 transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
1264 android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
1265 a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
Colin Cross4eae06d2023-06-20 22:40:02 -07001266
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001267 a.collectTransitiveHeaderJars(ctx)
Colin Cross9055e212024-03-23 04:43:41 +00001268
1269 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
1270
1271 var staticJars android.Paths
1272 var staticHeaderJars android.Paths
1273 ctx.VisitDirectDeps(func(module android.Module) {
1274 if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
1275 tag := ctx.OtherModuleDependencyTag(module)
1276 switch tag {
1277 case staticLibTag:
1278 staticJars = append(staticJars, dep.ImplementationJars...)
1279 staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
1280 }
1281 }
1282 addCLCFromDep(ctx, module, a.classLoaderContexts)
Jiakai Zhang22154d82024-03-28 13:50:43 +00001283 addMissingOptionalUsesLibsFromDep(ctx, module, &a.usesLibrary)
Colin Cross9055e212024-03-23 04:43:41 +00001284 })
1285
1286 if len(staticJars) > 0 {
1287 combineJars := append(android.Paths{classpathFile}, staticJars...)
1288 a.implementationJarFile = android.PathForModuleOut(ctx, "combined", ctx.ModuleName()+".jar")
1289 TransformJarsToJar(ctx, a.implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
1290 } else {
1291 a.implementationJarFile = classpathFile
1292 }
1293
1294 if len(staticHeaderJars) > 0 {
1295 combineJars := append(android.Paths{classpathFile}, staticHeaderJars...)
1296 a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", ctx.ModuleName()+".jar")
1297 TransformJarsToJar(ctx, a.headerJarFile, "combine header jars", combineJars, android.OptionalPath{}, false, nil, nil)
1298 } else {
1299 a.headerJarFile = classpathFile
1300 }
1301
Colin Cross40213022023-12-13 15:19:49 -08001302 android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
Colin Cross9055e212024-03-23 04:43:41 +00001303 HeaderJars: android.PathsIfNonNil(a.headerJarFile),
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001304 TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
1305 TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
Colin Cross9055e212024-03-23 04:43:41 +00001306 ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationJarFile),
1307 ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
Jihoon Kangfe914ed2024-02-12 22:49:21 +00001308 StubsLinkType: Implementation,
Joe Onorato6fe59eb2023-07-16 13:20:33 -07001309 // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
Colin Crossdcf71b22021-02-01 13:59:03 -08001310 })
Sam Delmerico82602492022-06-10 17:05:42 +00001311
1312 if proptools.Bool(a.properties.Extract_jni) {
1313 for _, t := range ctx.MultiTargets() {
1314 arch := t.Arch.Abi[0]
1315 path := android.PathForModuleOut(ctx, arch+"_jni.zip")
1316 a.jniPackages = append(a.jniPackages, path)
1317
1318 outDir := android.PathForModuleOut(ctx, "aarForJni")
1319 aarPath := android.PathForModuleSrc(ctx, a.properties.Aars[0])
1320 ctx.Build(pctx, android.BuildParams{
1321 Rule: extractJNI,
1322 Input: aarPath,
1323 Outputs: android.WritablePaths{path},
1324 Description: "extract JNI from AAR",
1325 Args: map[string]string{
1326 "outDir": outDir.String(),
1327 "archString": arch,
1328 },
1329 })
1330 }
Sam Delmerico82602492022-06-10 17:05:42 +00001331 }
Colin Crosse8eeec92023-12-14 14:50:05 -08001332
Colin Cross40213022023-12-13 15:19:49 -08001333 android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
Colin Crosse8eeec92023-12-14 14:50:05 -08001334 JniPackages: a.jniPackages,
1335 })
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001336 android.CollectDependencyAconfigFiles(ctx, &a.mergedAconfigFiles)
Colin Crossdcf71b22021-02-01 13:59:03 -08001337}
Colin Crossfabb6082018-02-20 17:22:23 -08001338
1339func (a *AARImport) HeaderJars() android.Paths {
Colin Cross9055e212024-03-23 04:43:41 +00001340 return android.Paths{a.headerJarFile}
Colin Crossfabb6082018-02-20 17:22:23 -08001341}
1342
Colin Cross331a1212018-08-15 20:40:52 -07001343func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
Colin Cross9055e212024-03-23 04:43:41 +00001344 return android.Paths{a.implementationJarFile}
Colin Cross331a1212018-08-15 20:40:52 -07001345}
1346
Colin Cross9055e212024-03-23 04:43:41 +00001347func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
1348 return OptionalDexJarPath{}
Colin Crossf24a22a2019-01-31 14:12:44 -08001349}
1350
Ulya Trafimovich9f3052c2020-06-09 14:31:19 +01001351func (a *AARImport) DexJarInstallPath() android.Path {
1352 return nil
1353}
1354
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +01001355func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
Colin Cross9055e212024-03-23 04:43:41 +00001356 return a.classLoaderContexts
Jiyong Park1be96912018-05-28 18:02:19 +09001357}
1358
Colin Cross9055e212024-03-23 04:43:41 +00001359var _ UsesLibraryDependency = (*AARImport)(nil)
1360
Jiyong Park45bf82e2020-12-15 22:29:02 +09001361var _ android.ApexModule = (*AARImport)(nil)
1362
1363// Implements android.ApexModule
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001364func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1365 return a.depIsInSameApex(ctx, dep)
1366}
1367
Jiyong Park45bf82e2020-12-15 22:29:02 +09001368// Implements android.ApexModule
Colin Cross9055e212024-03-23 04:43:41 +00001369func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
Dan Albertc8060532020-07-22 22:32:17 -07001370 sdkVersion android.ApiLevel) error {
Jooyung Han749dc692020-04-15 11:03:39 +09001371 return nil
1372}
1373
Sam Delmericoaf8bb702022-07-25 15:39:32 -04001374var _ android.PrebuiltInterface = (*AARImport)(nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001375
Jiakai Zhang3ef72832024-03-28 11:52:08 +00001376func (a *AARImport) UsesLibrary() *usesLibrary {
1377 return &a.usesLibrary
1378}
1379
1380var _ ModuleWithUsesLibrary = (*AARImport)(nil)
1381
Colin Cross1b16b0e2019-02-12 14:41:32 -08001382// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
1383//
1384// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
1385// an android_app module.
Colin Crossfabb6082018-02-20 17:22:23 -08001386func AARImportFactory() android.Module {
1387 module := &AARImport{}
1388
Colin Cross9055e212024-03-23 04:43:41 +00001389 module.AddProperties(
1390 &module.properties,
1391 &module.usesLibrary.usesLibraryProperties,
1392 )
Colin Crossfabb6082018-02-20 17:22:23 -08001393
1394 android.InitPrebuiltModule(module, &module.properties.Aars)
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001395 android.InitApexModule(module)
Sam Delmerico82602492022-06-10 17:05:42 +00001396 InitJavaModuleMultiTargets(module, android.DeviceSupported)
Colin Crossfabb6082018-02-20 17:22:23 -08001397 return module
1398}