blob: 7d73b03e48156ed9c0804874d0d2bf7b0fe7cb70 [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 (
Cole Faust6265120c2024-09-05 16:27:56 -070018 "crypto/sha256"
Colin Crossa592e3e2019-02-19 16:59:53 -080019 "fmt"
Jaewoong Jung5b425e22019-06-17 17:40:56 -070020 "path/filepath"
Colin Cross312634e2023-11-21 15:13:56 -080021 "slices"
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 Crossc4441622024-09-18 14:55:49 -070048 ctx.Transition("propagate_rro_enforcement", &propagateRROEnforcementTransitionMutator{})
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.
Cole Faustd65add22024-07-31 16:42:33 -070079 Resource_dirs []string `android:"path"`
Colin Crossa97c5d32018-03-28 14:58:31 -070080
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
Colin Crossc4441622024-09-18 14:55:49 -0700154// Propagate RRO enforcement flag to static lib dependencies transitively. If EnforceRROGlobally is set then
155// all modules will use the "" variant. If specific modules have RRO enforced, then modules (usually apps) with
156// RRO enabled will use the "" variation for themselves, but use the "rro" variant of direct and transitive static
157// android_library dependencies.
158type propagateRROEnforcementTransitionMutator struct{}
159
160func (p propagateRROEnforcementTransitionMutator) Split(ctx android.BaseModuleContext) []string {
161 // Never split modules, apps with or without RRO enabled use the "" variant, static android_library dependencies
162 // will use create the "rro" variant from incoming tranisitons.
163 return []string{""}
164}
165
166func (p propagateRROEnforcementTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
167 // Non-static dependencies are not involved in RRO and always use the empty variant.
168 if ctx.DepTag() != staticLibTag {
169 return ""
170 }
171
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700172 m := ctx.Module()
Colin Crossc4441622024-09-18 14:55:49 -0700173 if _, ok := m.(AndroidLibraryDependency); ok {
174 // If RRO is enforced globally don't bother using "rro" variants, the empty variant will have RRO enabled.
175 if ctx.Config().EnforceRROGlobally() {
176 return ""
177 }
178
179 // If RRO is enabled for this module use the "rro" variants of static dependencies. IncomingTransition will
180 // rewrite this back to "" if the dependency is not an android_library.
181 if ctx.Config().EnforceRROForModule(ctx.Module().Name()) {
182 return "rro"
183 }
184 }
185
186 return sourceVariation
187}
188
189func (p propagateRROEnforcementTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
190 // Propagate the "rro" variant to android_library modules, but use the empty variant for everything else.
191 if incomingVariation == "rro" {
192 m := ctx.Module()
193 if _, ok := m.(AndroidLibraryDependency); ok {
194 return "rro"
195 }
196 return ""
197 }
198
199 return ""
200}
201
202func (p propagateRROEnforcementTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
203 m := ctx.Module()
204 if d, ok := m.(AndroidLibraryDependency); ok {
205 if variation == "rro" {
206 // This is the "rro" variant of a module that has both variants, mark this one as RRO enabled and
207 // hide it from make to avoid collisions with the non-RRO empty variant.
208 d.SetRROEnforcedForDependent(true)
209 m.HideFromMake()
210 } else if ctx.Config().EnforceRROGlobally() {
211 // RRO is enabled globally, mark it enabled for this module, but there is only one variant so no
212 // need to hide it from make.
213 d.SetRROEnforcedForDependent(true)
214 }
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700215 }
216}
217
Colin Cross8f1b0332024-01-25 13:39:06 -0800218func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool {
Colin Crosseee4ab12024-03-27 11:54:10 -0700219 return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault()) &&
220 // TODO(b/331641946): remove this when ResourceProcessorBusyBox supports generating shared libraries.
Spandan Dasa62d9562024-08-06 00:13:31 +0000221 !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib") &&
222 // Use the legacy resource processor in kythe builds.
223 // The legacy resource processor creates an R.srcjar, which kythe can use for generating crossrefs.
224 // TODO(b/354854007): Re-enable BusyBox in kythe builds
225 !ctx.Config().EmitXrefRules()
Colin Cross4eae06d2023-06-20 22:40:02 -0700226}
227
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900228func (a *aapt) filterProduct() string {
229 return String(a.aaptProperties.Filter_product)
230}
231
Colin Crossa97c5d32018-03-28 14:58:31 -0700232func (a *aapt) ExportPackage() android.Path {
233 return a.exportPackage
234}
Colin Crossab8d1382023-07-14 17:23:41 +0000235func (a *aapt) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
236 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800237}
238
Colin Crossab8d1382023-07-14 17:23:41 +0000239func (a *aapt) RRODirsDepSet() *android.DepSet[rroDir] {
240 return a.rroDirsDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800241}
242
Colin Crossab8d1382023-07-14 17:23:41 +0000243func (a *aapt) ManifestsDepSet() *android.DepSet[android.Path] {
244 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800245}
246
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700247func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
248 a.aaptProperties.RROEnforcedForDependent = enforce
249}
250
251func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
252 // True if RRO is enforced for this module or...
253 return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
Jeongik Chacee5ba92021-02-19 12:11:51 +0900254 // if RRO is enforced for any of its dependents.
255 a.aaptProperties.RROEnforcedForDependent
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700256}
257
Jiyong Parkf1691d22021-03-29 20:11:58 +0900258func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkContext,
Colin Crossa0ba2f52019-06-22 12:59:27 -0700259 manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
260 resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700261
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800262 hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
263 hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
Colin Crossa97c5d32018-03-28 14:58:31 -0700264
Colin Crossa97c5d32018-03-28 14:58:31 -0700265 // Flags specified in Android.bp
266 linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
267
Eric Miao40eab202023-03-30 16:57:17 +0000268 linkFlags = append(linkFlags, "--enable-compact-entries")
Colin Crossa97c5d32018-03-28 14:58:31 -0700269
270 // Find implicit or explicit asset and resource dirs
Jiakai Zhangba82e282023-10-13 18:08:59 +0100271 assets := android.PathsRelativeToModuleSourceDir(android.SourceInput{
272 Context: ctx,
273 Paths: a.aaptProperties.Assets,
274 IncludeDirs: false,
275 })
Colin Crossa97c5d32018-03-28 14:58:31 -0700276 assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
277 resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
Colin Cross8a497952019-03-05 22:25:09 -0800278 resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
Colin Crossa97c5d32018-03-28 14:58:31 -0700279
Colin Crossa97c5d32018-03-28 14:58:31 -0700280 // Glob directories into lists of paths
281 for _, dir := range resourceDirs {
282 resDirs = append(resDirs, globbedResourceDir{
283 dir: dir,
284 files: androidResourceGlob(ctx, dir),
285 })
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700286 resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
Colin Crossa97c5d32018-03-28 14:58:31 -0700287 overlayDirs = append(overlayDirs, resOverlayDirs...)
288 rroDirs = append(rroDirs, resRRODirs...)
289 }
290
Cole Faust6265120c2024-09-05 16:27:56 -0700291 assetDirsHasher := sha256.New()
Colin Crossc20dc852020-11-10 12:27:45 -0800292 var assetDeps android.Paths
Cole Faust6265120c2024-09-05 16:27:56 -0700293 for _, dir := range assetDirs {
Colin Crossc20dc852020-11-10 12:27:45 -0800294 // Add a dependency on every file in the asset directory. This ensures the aapt2
295 // rule will be rerun if one of the files in the asset directory is modified.
Cole Faust6265120c2024-09-05 16:27:56 -0700296 dirContents := androidResourceGlob(ctx, dir)
297 assetDeps = append(assetDeps, dirContents...)
Colin Crossc20dc852020-11-10 12:27:45 -0800298
Cole Faust6265120c2024-09-05 16:27:56 -0700299 // Add a hash of all the files in the asset directory to the command line.
Colin Crossc20dc852020-11-10 12:27:45 -0800300 // This ensures the aapt2 rule will be run if a file is removed from the asset directory,
301 // or a file is added whose timestamp is older than the output of aapt2.
Cole Faust6265120c2024-09-05 16:27:56 -0700302 for _, path := range dirContents.Strings() {
303 assetDirsHasher.Write([]byte(path))
304 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700305 }
306
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700307 assetDirStrings := assetDirs.Strings()
308 if a.noticeFile.Valid() {
309 assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
Colin Crossc20dc852020-11-10 12:27:45 -0800310 assetDeps = append(assetDeps, a.noticeFile.Path())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700311 }
Jiakai Zhangba82e282023-10-13 18:08:59 +0100312 if len(assets) > 0 {
313 // aapt2 doesn't support adding individual asset files. Create a temp directory to hold asset
314 // files and pass it to aapt2.
315 tmpAssetDir := android.PathForModuleOut(ctx, "tmp_asset_dir")
316
317 rule := android.NewRuleBuilder(pctx, ctx)
318 rule.Command().
319 Text("rm -rf").Text(tmpAssetDir.String()).
320 Text("&&").
321 Text("mkdir -p").Text(tmpAssetDir.String())
322
323 for _, asset := range assets {
324 output := tmpAssetDir.Join(ctx, asset.Rel())
325 assetDeps = append(assetDeps, output)
326 rule.Command().Text("mkdir -p").Text(filepath.Dir(output.String()))
327 rule.Command().Text("cp").Input(asset).Output(output)
328 }
329
330 rule.Build("tmp_asset_dir", "tmp_asset_dir")
331
332 assetDirStrings = append(assetDirStrings, tmpAssetDir.String())
333 }
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700334
Colin Crossa97c5d32018-03-28 14:58:31 -0700335 linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
336 linkDeps = append(linkDeps, manifestPath)
337
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700338 linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
Cole Faust6265120c2024-09-05 16:27:56 -0700339 linkFlags = append(linkFlags, fmt.Sprintf("$$(: %x)", assetDirsHasher.Sum(nil)))
Colin Crossc20dc852020-11-10 12:27:45 -0800340 linkDeps = append(linkDeps, assetDeps...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700341
Spandan Das50885c02023-02-23 21:31:33 +0000342 // Returns the effective version for {min|target}_sdk_version
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000343 effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.ApiLevel) string {
Spandan Das50885c02023-02-23 21:31:33 +0000344 // If {min|target}_sdk_version is current, use sdk_version to determine the effective level
345 // This is necessary for vendor modules.
346 // The effective version does not _only_ depend on {min|target}_sdk_version(level),
347 // but also on the sdk_version (kind+level)
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000348 if minSdkVersion.IsCurrent() {
Spandan Das50885c02023-02-23 21:31:33 +0000349 ret, err := sdkVersion.EffectiveVersionString(ctx)
350 if err != nil {
351 ctx.ModuleErrorf("invalid sdk_version: %s", err)
352 }
353 return ret
354 }
355 ret, err := minSdkVersion.EffectiveVersionString(ctx)
356 if err != nil {
357 ctx.ModuleErrorf("invalid min_sdk_version: %s", err)
358 }
359 return ret
Jiyong Park6a927c42020-01-21 02:03:43 +0900360 }
Spandan Das50885c02023-02-23 21:31:33 +0000361 // SDK version flags
362 sdkVersion := sdkContext.SdkVersion(ctx)
363 minSdkVersion := effectiveVersionString(sdkVersion, sdkContext.MinSdkVersion(ctx))
Colin Crossa97c5d32018-03-28 14:58:31 -0700364
Colin Cross83bb3162018-06-25 15:48:06 -0700365 linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
Spandan Das6450b552023-02-23 19:27:07 +0000366 // Use minSdkVersion for target-sdk-version, even if `target_sdk_version` is set
367 // This behavior has been copied from Make.
Colin Cross83bb3162018-06-25 15:48:06 -0700368 linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
Colin Crossa97c5d32018-03-28 14:58:31 -0700369
Colin Crossa97c5d32018-03-28 14:58:31 -0700370 // Version code
371 if !hasVersionCode {
Dan Albert4f378d72020-07-23 17:32:15 -0700372 linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
Colin Crossa97c5d32018-03-28 14:58:31 -0700373 }
374
375 if !hasVersionName {
Colin Cross402d5e02018-04-25 14:54:06 -0700376 var versionName string
377 if ctx.ModuleName() == "framework-res" {
378 // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
379 // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
Colin Crossbfd347d2018-05-09 11:11:35 -0700380 // if it contains the build number. Use the PlatformVersionName instead.
381 versionName = ctx.Config().PlatformVersionName()
Colin Cross402d5e02018-04-25 14:54:06 -0700382 } else {
383 versionName = ctx.Config().AppsDefaultVersionName()
384 }
Colin Cross0b9f31f2019-02-28 11:00:01 -0800385 versionName = proptools.NinjaEscape(versionName)
Colin Crossa97c5d32018-03-28 14:58:31 -0700386 linkFlags = append(linkFlags, "--version-name ", versionName)
387 }
388
Colin Crossa0ba2f52019-06-22 12:59:27 -0700389 linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
390
391 // Always set --pseudo-localize, it will be stripped out later for release
392 // builds that don't want it.
393 compileFlags = append(compileFlags, "--pseudo-localize")
394
395 return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
Colin Crossa97c5d32018-03-28 14:58:31 -0700396}
397
Paul Duffin250e6192019-06-07 10:44:37 +0100398func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
Colin Cross42308aa2018-11-14 21:44:17 -0800399 if sdkDep.frameworkResModule != "" {
400 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossa97c5d32018-03-28 14:58:31 -0700401 }
402}
403
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800404var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
405 blueprint.RuleParams{
406 Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
407 CommandDeps: []string{"${config.Zip2ZipCmd}"},
408 })
409
Alixf7a10272023-09-27 16:47:56 +0000410type aaptBuildActionOptions struct {
411 sdkContext android.SdkContext
412 classLoaderContexts dexpreopt.ClassLoaderContextMap
413 excludedLibs []string
414 enforceDefaultTargetSdkVersion bool
Rico Winda2fa2632024-03-13 13:09:17 +0100415 forceNonFinalResourceIDs bool
Alixf7a10272023-09-27 16:47:56 +0000416 extraLinkFlags []string
Jihoon Kang84b25892023-12-01 22:01:06 +0000417 aconfigTextFiles android.Paths
Jiakai Zhang36937082024-04-15 11:15:50 +0000418 usesLibrary *usesLibrary
Alixf7a10272023-09-27 16:47:56 +0000419}
420
421func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) {
Colin Cross5446e882019-05-22 10:46:27 -0700422
Colin Cross8676c8c2023-10-12 15:58:57 -0700423 staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedExportPackages, libFlags :=
Jiakai Zhang36937082024-04-15 11:15:50 +0000424 aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts, opts.usesLibrary)
Ulya Trafimovich31e444e2020-08-14 17:32:16 +0100425
Paul Duffin06530572022-02-03 17:54:15 +0000426 // Exclude any libraries from the supplied list.
Alixf7a10272023-09-27 16:47:56 +0000427 opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs)
Paul Duffin06530572022-02-03 17:54:15 +0000428
Colin Cross31656952018-05-24 16:11:20 -0700429 // App manifest file
430 manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
431 manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
432
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000433 manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
Alixf7a10272023-09-27 16:47:56 +0000434 SdkContext: opts.sdkContext,
435 ClassLoaderContexts: opts.classLoaderContexts,
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000436 IsLibrary: a.isLibrary,
437 DefaultManifestVersion: a.defaultManifestVersion,
438 UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
439 UsesNonSdkApis: a.usesNonSdkApis,
440 UseEmbeddedDex: a.useEmbeddedDex,
441 HasNoCode: a.hasNoCode,
442 LoggingParent: a.LoggingParent,
Alixf7a10272023-09-27 16:47:56 +0000443 EnforceDefaultTargetSdkVersion: opts.enforceDefaultTargetSdkVersion,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000444 })
Colin Cross90c25c62019-04-19 16:22:57 -0700445
Colin Crossab8d1382023-07-14 17:23:41 +0000446 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
Colin Cross8676c8c2023-10-12 15:58:57 -0700447 sharedDeps := transitiveAarDeps(sharedResourcesNodesDepSet.ToList())
Colin Crossab8d1382023-07-14 17:23:41 +0000448
Luca Stefanifd898822019-09-10 22:13:31 +0200449 // Add additional manifest files to transitive manifests.
450 additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
Colin Crossab8d1382023-07-14 17:23:41 +0000451 transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
Colin Crossab8d1382023-07-14 17:23:41 +0000452 transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
Colin Cross90c25c62019-04-19 16:22:57 -0700453
Colin Crossab8d1382023-07-14 17:23:41 +0000454 if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
Alixf7a10272023-09-27 16:47:56 +0000455 manifestMergerParams := ManifestMergerParams{
456 staticLibManifests: transitiveManifestPaths[1:],
Alix96ea88452023-08-31 15:48:23 +0000457 isLibrary: a.isLibrary,
458 packageName: a.manifestValues.applicationId,
459 }
Alixf7a10272023-09-27 16:47:56 +0000460 a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], manifestMergerParams)
Colin Crossa6182ab2024-08-21 10:47:44 -0700461 ctx.CheckbuildFile(a.mergedManifestFile)
Colin Cross90c25c62019-04-19 16:22:57 -0700462 if !a.isLibrary {
463 // Only use the merged manifest for applications. For libraries, the transitive closure of manifests
464 // will be propagated to the final application and merged there. The merged manifest for libraries is
465 // only passed to Make, which can't handle transitive dependencies.
466 manifestPath = a.mergedManifestFile
467 }
468 } else {
469 a.mergedManifestFile = manifestPath
470 }
Colin Cross31656952018-05-24 16:11:20 -0700471
Alixf7a10272023-09-27 16:47:56 +0000472 compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, opts.sdkContext, manifestPath)
Colin Cross31656952018-05-24 16:11:20 -0700473
474 linkFlags = append(linkFlags, libFlags...)
Colin Cross8676c8c2023-10-12 15:58:57 -0700475 linkDeps = append(linkDeps, sharedExportPackages...)
Colin Crossab8d1382023-07-14 17:23:41 +0000476 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Alixf7a10272023-09-27 16:47:56 +0000477 linkFlags = append(linkFlags, opts.extraLinkFlags...)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700478 if a.isLibrary {
479 linkFlags = append(linkFlags, "--static-lib")
480 }
Rico Wind7152e822024-04-19 08:14:15 +0200481 if opts.forceNonFinalResourceIDs {
482 linkFlags = append(linkFlags, "--non-final-ids")
483 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700484
Colin Cross7c4dc5d2024-02-13 14:29:45 -0800485 linkFlags = append(linkFlags, "--no-static-lib-packages")
Colin Cross8f1b0332024-01-25 13:39:06 -0800486 if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
Colin Cross7c4dc5d2024-02-13 14:29:45 -0800487 // When building an android_library using ResourceProcessorBusyBox pass --merge-only to skip resource
488 // references validation until the final app link step when all static libraries are present.
Colin Cross4eae06d2023-06-20 22:40:02 -0700489 linkFlags = append(linkFlags, "--merge-only")
Colin Cross4eae06d2023-06-20 22:40:02 -0700490 }
491
Colin Crossa97c5d32018-03-28 14:58:31 -0700492 packageRes := android.PathForModuleOut(ctx, "package-res.apk")
Colin Crossa97c5d32018-03-28 14:58:31 -0700493 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
494 rTxt := android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -0700495 // This file isn't used by Soong, but is generated for exporting
496 extraPackages := android.PathForModuleOut(ctx, "extra_packages")
Colin Cross4eae06d2023-06-20 22:40:02 -0700497 var transitiveRJars android.Paths
Colin Crossf3b7bad2023-08-02 15:49:00 -0700498 var srcJar android.WritablePath
Colin Crossa97c5d32018-03-28 14:58:31 -0700499
Colin Cross4aaa84a2018-08-21 15:14:37 -0700500 var compiledResDirs []android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700501 for _, dir := range resDirs {
Colin Cross014489c2020-06-02 20:09:13 -0700502 a.resourceFiles = append(a.resourceFiles, dir.files...)
Jihoon Kang98ea8362024-07-16 18:20:03 +0000503 compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files,
504 compileFlags, a.filterProduct(), opts.aconfigTextFiles).Paths())
Colin Crossa97c5d32018-03-28 14:58:31 -0700505 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700506
Colin Crossa592e3e2019-02-19 16:59:53 -0800507 for i, zip := range resZips {
508 flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
Colin Crossa0ba2f52019-06-22 12:59:27 -0700509 aapt2CompileZip(ctx, flata, zip, "", compileFlags)
Colin Crossa592e3e2019-02-19 16:59:53 -0800510 compiledResDirs = append(compiledResDirs, android.Paths{flata})
511 }
512
Colin Cross4aaa84a2018-08-21 15:14:37 -0700513 var compiledRes, compiledOverlay android.Paths
514
Colin Crossab8d1382023-07-14 17:23:41 +0000515 // AAPT2 overlays are in lowest to highest priority order, reverse the topological order
516 // of transitiveStaticLibs.
517 transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
518
Colin Cross8f1b0332024-01-25 13:39:06 -0800519 if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700520 // When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
521 // as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
522 // instead modules depending on this module will reference package-res.apk from all transitive static
523 // dependencies.
Colin Cross1d3f5902024-03-05 11:51:54 -0800524 for _, sharedDep := range sharedDeps {
525 if sharedDep.usedResourceProcessor {
526 transitiveRJars = append(transitiveRJars, sharedDep.rJar)
527 }
528 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700529 for _, staticDep := range staticDeps {
530 linkDeps = append(linkDeps, staticDep.resPackage)
531 linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
532 if staticDep.usedResourceProcessor {
533 transitiveRJars = append(transitiveRJars, staticDep.rJar)
534 }
535 }
536 } else {
537 // When building an app or building a library without ResourceProcessorBusyBox enabled all static
538 // dependencies are compiled into this module's package-res.apk as overlays.
539 compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
540 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700541
Colin Crossbec85302019-02-13 13:15:46 -0800542 if len(transitiveStaticLibs) > 0 {
Colin Cross4aaa84a2018-08-21 15:14:37 -0700543 // If we are using static android libraries, every source file becomes an overlay.
544 // This is to emulate old AAPT behavior which simulated library support.
545 for _, compiledResDir := range compiledResDirs {
546 compiledOverlay = append(compiledOverlay, compiledResDir...)
547 }
Colin Crossbec85302019-02-13 13:15:46 -0800548 } else if a.isLibrary {
549 // Otherwise, for a static library we treat all the resources equally with no overlay.
550 for _, compiledResDir := range compiledResDirs {
551 compiledRes = append(compiledRes, compiledResDir...)
552 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700553 } else if len(compiledResDirs) > 0 {
554 // Without static libraries, the first directory is our directory, which can then be
555 // overlaid by the rest.
556 compiledRes = append(compiledRes, compiledResDirs[0]...)
557 for _, compiledResDir := range compiledResDirs[1:] {
558 compiledOverlay = append(compiledOverlay, compiledResDir...)
559 }
560 }
561
Colin Crossa97c5d32018-03-28 14:58:31 -0700562 for _, dir := range overlayDirs {
Jihoon Kang98ea8362024-07-16 18:20:03 +0000563 compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files,
564 compileFlags, a.filterProduct(), opts.aconfigTextFiles).Paths()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700565 }
566
Colin Crosse560c4a2019-03-19 16:03:11 -0700567 var splitPackages android.WritablePaths
568 var splits []split
569
570 for _, s := range a.splitNames {
571 suffix := strings.Replace(s, ",", "_", -1)
572 path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
573 linkFlags = append(linkFlags, "--split", path.String()+":"+s)
574 splitPackages = append(splitPackages, path)
575 splits = append(splits, split{
576 name: s,
577 suffix: suffix,
578 path: path,
579 })
580 }
581
Colin Cross8f1b0332024-01-25 13:39:06 -0800582 if !a.useResourceProcessorBusyBox(ctx) {
Colin Crossf3b7bad2023-08-02 15:49:00 -0700583 // the subdir "android" is required to be filtered by package names
584 srcJar = android.PathForModuleGen(ctx, "android", "R.srcjar")
585 }
586
Colin Crossab8d1382023-07-14 17:23:41 +0000587 // No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
588 // provided to the final app aapt2Link step.
589 var transitiveAssets android.Paths
590 if !a.isLibrary {
591 transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
592 }
Colin Crossf3b7bad2023-08-02 15:49:00 -0700593 aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
Jihoon Kang84b25892023-12-01 22:01:06 +0000594 linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages,
595 opts.aconfigTextFiles)
Colin Crossa6182ab2024-08-21 10:47:44 -0700596 ctx.CheckbuildFile(packageRes)
597
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800598 // Extract assets from the resource package output so that they can be used later in aapt2link
599 // for modules that depend on this one.
Colin Crossab8d1382023-07-14 17:23:41 +0000600 if android.PrefixInList(linkFlags, "-A ") {
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800601 assets := android.PathForModuleOut(ctx, "assets.zip")
602 ctx.Build(pctx, android.BuildParams{
603 Rule: extractAssetsRule,
604 Input: packageRes,
605 Output: assets,
606 Description: "extract assets from built resource file",
607 })
608 a.assetPackage = android.OptionalPathForPath(assets)
609 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700610
Colin Cross8f1b0332024-01-25 13:39:06 -0800611 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700612 rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
Rico Winda2fa2632024-03-13 13:09:17 +0100613 resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags,
614 opts.forceNonFinalResourceIDs)
Colin Crossf3b7bad2023-08-02 15:49:00 -0700615 aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700616 transitiveRJars = append(transitiveRJars, rJar)
617 a.rJar = rJar
Colin Crossf3b7bad2023-08-02 15:49:00 -0700618 } else {
619 aapt2ExtractExtraPackages(ctx, extraPackages, srcJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700620 }
621
Colin Cross312634e2023-11-21 15:13:56 -0800622 transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
623 transitiveAaptResourcePackages = slices.DeleteFunc(transitiveAaptResourcePackages, func(p string) bool {
624 return p == packageRes.String()
625 })
626 transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
627 android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
628
Colin Cross1d3f5902024-03-05 11:51:54 -0800629 // Reverse the list of R.jar files so that the current module comes first, and direct dependencies come before
630 // transitive dependencies.
631 transitiveRJars = android.ReversePaths(transitiveRJars)
632
Colin Crossa97c5d32018-03-28 14:58:31 -0700633 a.aaptSrcJar = srcJar
Colin Cross4eae06d2023-06-20 22:40:02 -0700634 a.transitiveAaptRJars = transitiveRJars
Colin Cross312634e2023-11-21 15:13:56 -0800635 a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
Colin Crossa97c5d32018-03-28 14:58:31 -0700636 a.exportPackage = packageRes
637 a.manifestPath = manifestPath
638 a.proguardOptionsFile = proguardOptionsFile
Colin Cross66f78822018-05-02 12:58:28 -0700639 a.extraAaptPackagesFile = extraPackages
Colin Crossa97c5d32018-03-28 14:58:31 -0700640 a.rTxt = rTxt
Colin Crosse560c4a2019-03-19 16:03:11 -0700641 a.splits = splits
Colin Crossab8d1382023-07-14 17:23:41 +0000642 a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL).
643 Direct(&resourcesNode{
644 resPackage: a.exportPackage,
645 manifest: a.manifestPath,
646 additionalManifests: additionalManifests,
Colin Cross4eae06d2023-06-20 22:40:02 -0700647 rTxt: a.rTxt,
648 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +0000649 assets: a.assetPackage,
Colin Cross4eae06d2023-06-20 22:40:02 -0700650
Colin Cross8f1b0332024-01-25 13:39:06 -0800651 usedResourceProcessor: a.useResourceProcessorBusyBox(ctx),
Colin Crossab8d1382023-07-14 17:23:41 +0000652 }).
653 Transitive(staticResourcesNodesDepSet).Build()
654 a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
655 Direct(rroDirs...).
656 Transitive(staticRRODirsDepSet).Build()
657 a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
658 Direct(a.manifestPath).
659 DirectSlice(additionalManifests).
660 Transitive(staticManifestsDepSet).Build()
661}
662
Colin Cross4eae06d2023-06-20 22:40:02 -0700663var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
664 blueprint.RuleParams{
665 Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
666 "com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
667 "if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
668 CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
669 Rspfile: "${out}.args",
670 RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
671 Restat: true,
672 }, "rTxt", "manifest", "args")
673
674// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
675// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
676// supports producing classes for static dependencies that only include resources from that dependency.
677func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
Rico Winda2fa2632024-03-13 13:09:17 +0100678 rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string,
679 forceNonFinalIds bool) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700680
681 var args []string
682 var deps android.Paths
683
684 if !isLibrary {
685 // When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
686 // to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
687 // package.
688 args, deps = transitiveDeps.resourceProcessorDeps()
Rico Winda2fa2632024-03-13 13:09:17 +0100689 if forceNonFinalIds {
690 args = append(args, "--finalFields=false")
691 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700692 } else {
693 // When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
694 // library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
695 // inlined into the library before the final IDs are assigned during app compilation.
696 args = append(args, "--finalFields=false")
697 }
698
Colin Crossd3f7d1a2024-01-03 19:42:25 -0800699 for i, arg := range aaptFlags {
700 const AAPT_CUSTOM_PACKAGE = "--custom-package"
701 if strings.HasPrefix(arg, AAPT_CUSTOM_PACKAGE) {
702 pkg := strings.TrimSpace(strings.TrimPrefix(arg, AAPT_CUSTOM_PACKAGE))
703 if pkg == "" && i+1 < len(aaptFlags) {
704 pkg = aaptFlags[i+1]
705 }
706 args = append(args, "--packageForR "+pkg)
707 }
708 }
709
Colin Cross4eae06d2023-06-20 22:40:02 -0700710 deps = append(deps, rTxt, manifest)
711
712 ctx.Build(pctx, android.BuildParams{
713 Rule: resourceProcessorBusyBox,
714 Output: rJar,
715 Implicits: deps,
716 Description: "ResourceProcessorBusyBox",
717 Args: map[string]string{
718 "rTxt": rTxt.String(),
719 "manifest": manifest.String(),
720 "args": strings.Join(args, " "),
721 },
722 })
723}
724
Colin Crossab8d1382023-07-14 17:23:41 +0000725type resourcesNode struct {
726 resPackage android.Path
727 manifest android.Path
728 additionalManifests android.Paths
Colin Cross4eae06d2023-06-20 22:40:02 -0700729 rTxt android.Path
730 rJar android.Path
Colin Crossab8d1382023-07-14 17:23:41 +0000731 assets android.OptionalPath
Colin Cross4eae06d2023-06-20 22:40:02 -0700732
733 usedResourceProcessor bool
Colin Crossab8d1382023-07-14 17:23:41 +0000734}
735
736type transitiveAarDeps []*resourcesNode
737
738func (t transitiveAarDeps) resPackages() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700739 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000740 for _, dep := range t {
741 paths = append(paths, dep.resPackage)
742 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700743 return paths
Colin Crossab8d1382023-07-14 17:23:41 +0000744}
745
746func (t transitiveAarDeps) manifests() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700747 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000748 for _, dep := range t {
749 paths = append(paths, dep.manifest)
750 paths = append(paths, dep.additionalManifests...)
751 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700752 return paths
753}
754
755func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
756 for _, dep := range t {
757 args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
758 deps = append(deps, dep.rTxt, dep.manifest)
759 }
760 return args, deps
Colin Crossab8d1382023-07-14 17:23:41 +0000761}
762
763func (t transitiveAarDeps) assets() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700764 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000765 for _, dep := range t {
766 if dep.assets.Valid() {
767 paths = append(paths, dep.assets.Path())
768 }
769 }
770 return paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700771}
772
773// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
Jiakai Zhang36937082024-04-15 11:15:50 +0000774func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext,
775 classLoaderContexts dexpreopt.ClassLoaderContextMap, usesLibrary *usesLibrary) (
Colin Cross8676c8c2023-10-12 15:58:57 -0700776 staticResourcesNodes, sharedResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
Colin Crossab8d1382023-07-14 17:23:41 +0000777 staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700778
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100779 if classLoaderContexts == nil {
Ulya Trafimovich18554242020-11-03 15:55:11 +0000780 // Not all callers need to compute class loader context, those who don't just pass nil.
781 // Create a temporary class loader context here (it will be computed, but not used).
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100782 classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000783 }
784
Colin Cross83bb3162018-06-25 15:48:06 -0700785 sdkDep := decodeSdkDep(ctx, sdkContext)
Colin Crossa97c5d32018-03-28 14:58:31 -0700786 if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700787 sharedLibs = append(sharedLibs, sdkDep.jars...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700788 }
789
Colin Cross8676c8c2023-10-12 15:58:57 -0700790 var staticResourcesNodeDepSets []*android.DepSet[*resourcesNode]
791 var sharedResourcesNodeDepSets []*android.DepSet[*resourcesNode]
Colin Crossab8d1382023-07-14 17:23:41 +0000792 rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL)
793 manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL)
794
Colin Crossa97c5d32018-03-28 14:58:31 -0700795 ctx.VisitDirectDeps(func(module android.Module) {
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000796 depTag := ctx.OtherModuleDependencyTag(module)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000797
Colin Crossa97c5d32018-03-28 14:58:31 -0700798 var exportPackage android.Path
Colin Cross66f78822018-05-02 12:58:28 -0700799 aarDep, _ := module.(AndroidLibraryDependency)
800 if aarDep != nil {
Colin Crossa97c5d32018-03-28 14:58:31 -0700801 exportPackage = aarDep.ExportPackage()
802 }
803
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000804 switch depTag {
Colin Cross4b964c02018-10-15 16:18:06 -0700805 case instrumentationForTag:
806 // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
Liz Kammeref28a4c2022-09-23 16:50:56 -0400807 case sdkLibTag, libTag:
Colin Cross5446e882019-05-22 10:46:27 -0700808 if exportPackage != nil {
Colin Cross8676c8c2023-10-12 15:58:57 -0700809 sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
Colin Cross5446e882019-05-22 10:46:27 -0700810 sharedLibs = append(sharedLibs, exportPackage)
811 }
Colin Cross5446e882019-05-22 10:46:27 -0700812 case frameworkResTag:
Colin Crossa97c5d32018-03-28 14:58:31 -0700813 if exportPackage != nil {
814 sharedLibs = append(sharedLibs, exportPackage)
815 }
816 case staticLibTag:
817 if exportPackage != nil {
Colin Cross8676c8c2023-10-12 15:58:57 -0700818 staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
Colin Crossab8d1382023-07-14 17:23:41 +0000819 rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
820 manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
Colin Crossa97c5d32018-03-28 14:58:31 -0700821 }
822 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000823
Ulya Trafimovich88bb6f62020-12-16 16:16:11 +0000824 addCLCFromDep(ctx, module, classLoaderContexts)
Jiakai Zhang36937082024-04-15 11:15:50 +0000825 if usesLibrary != nil {
826 addMissingOptionalUsesLibsFromDep(ctx, module, usesLibrary)
827 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700828 })
829
Colin Crossab8d1382023-07-14 17:23:41 +0000830 // AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
831 // Reverse the dependency order now going into the depset so that it comes out in order after the second
832 // reverse later.
833 // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
834 // dependencies) the highest priority dependency is listed first, but for resources the highest priority
Colin Cross9055e212024-03-23 04:43:41 +0000835 // dependency has to be listed last. This is also inconsistent with the way manifests from the same
836 // transitive dependencies are merged.
Colin Crossab8d1382023-07-14 17:23:41 +0000837 staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
Colin Cross8676c8c2023-10-12 15:58:57 -0700838 android.ReverseSliceInPlace(staticResourcesNodeDepSets))
839 sharedResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
840 android.ReverseSliceInPlace(sharedResourcesNodeDepSets))
Colin Crossa97c5d32018-03-28 14:58:31 -0700841
Colin Crossab8d1382023-07-14 17:23:41 +0000842 staticRRODirs = rroDirsDepSetBuilder.Build()
843 staticManifests = manifestsDepSetBuilder.Build()
844
845 if len(staticResourcesNodes.ToList()) > 0 {
Colin Crossa97c5d32018-03-28 14:58:31 -0700846 flags = append(flags, "--auto-add-overlay")
847 }
848
849 for _, sharedLib := range sharedLibs {
850 flags = append(flags, "-I "+sharedLib.String())
851 }
852
Colin Cross8676c8c2023-10-12 15:58:57 -0700853 return staticResourcesNodes, sharedResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
Colin Crossa97c5d32018-03-28 14:58:31 -0700854}
855
856type AndroidLibrary struct {
857 Library
858 aapt
859
860 androidLibraryProperties androidLibraryProperties
861
862 aarFile android.WritablePath
Colin Cross89c31582018-04-30 15:55:11 -0700863}
864
Colin Crossa97c5d32018-03-28 14:58:31 -0700865var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
866
867func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000868 a.usesLibrary.deps(ctx, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700869 a.Module.deps(ctx)
Jiyong Parkf1691d22021-03-29 20:11:58 +0900870 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Paul Duffin250e6192019-06-07 10:44:37 +0100871 if sdkDep.hasFrameworkLibs() {
872 a.aapt.deps(ctx, sdkDep)
Colin Crossa97c5d32018-03-28 14:58:31 -0700873 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000874
875 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
876 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
877 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700878}
879
880func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosse4246ab2019-02-05 21:55:21 -0800881 a.aapt.isLibrary = true
Ulya Trafimovich42c7f0d2021-08-17 16:20:29 +0100882 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000883 if a.usesLibrary.shouldDisableDexpreopt {
884 a.dexpreopter.disableDexpreopt()
885 }
Jihoon Kang9aef7772024-06-14 23:45:06 +0000886 aconfigTextFilePaths := getAconfigFilePaths(ctx)
Alixf7a10272023-09-27 16:47:56 +0000887 a.aapt.buildActions(ctx,
888 aaptBuildActionOptions{
889 sdkContext: android.SdkContext(a),
890 classLoaderContexts: a.classLoaderContexts,
891 enforceDefaultTargetSdkVersion: false,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000892 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000893 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000894 },
895 )
Colin Crossa97c5d32018-03-28 14:58:31 -0700896
Colin Crossff694a82023-12-13 15:54:49 -0800897 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
898 a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
Colin Cross56a83212020-09-15 18:30:11 -0700899
yangbill2af0b6e2024-03-15 09:29:29 +0000900 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000901
Colin Cross4eae06d2023-06-20 22:40:02 -0700902 ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
903 ctx.CheckbuildFile(a.aapt.exportPackage)
Colin Cross8f1b0332024-01-25 13:39:06 -0800904 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700905 ctx.CheckbuildFile(a.aapt.rJar)
Colin Crossf3b7bad2023-08-02 15:49:00 -0700906 } else {
907 ctx.CheckbuildFile(a.aapt.aaptSrcJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700908 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700909
910 // apps manifests are handled by aapt, don't let Module see them
911 a.properties.Manifest = nil
912
Colin Cross014489c2020-06-02 20:09:13 -0700913 a.linter.mergedManifest = a.aapt.mergedManifestFile
914 a.linter.manifest = a.aapt.manifestPath
915 a.linter.resources = a.aapt.resourceFiles
916
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000917 proguardSpecInfo := a.collectProguardSpecInfo(ctx)
Colin Cross40213022023-12-13 15:19:49 -0800918 android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo)
Colin Cross312634e2023-11-21 15:13:56 -0800919 exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList()
920 a.extraProguardFlagsFiles = append(a.extraProguardFlagsFiles, exportedProguardFlagsFiles...)
921 a.extraProguardFlagsFiles = append(a.extraProguardFlagsFiles, a.proguardOptionsFile)
922
923 combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags")
924 writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles)
925 a.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile
Colin Crossa97c5d32018-03-28 14:58:31 -0700926
Colin Cross4eae06d2023-06-20 22:40:02 -0700927 var extraSrcJars android.Paths
928 var extraCombinedJars android.Paths
929 var extraClasspathJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800930 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700931 // When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
932 // library and each of the transitive static android_library dependencies has already created an
933 // R.class file for the appropriate package. Add all of those R.class files to the classpath.
934 extraClasspathJars = a.transitiveAaptRJars
935 } else {
936 // When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
937 // R.java files for the library's package and the packages from all transitive static android_library
938 // dependencies. Compile the srcjar alongside the rest of the sources.
939 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
940 }
941
Colin Crossfdaa6722024-08-23 11:58:08 -0700942 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Colin Crossa97c5d32018-03-28 14:58:31 -0700943
Colin Crossf57c5782019-01-25 13:20:38 -0800944 a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
Colin Crossa97c5d32018-03-28 14:58:31 -0700945 var res android.Paths
946 if a.androidLibraryProperties.BuildAAR {
947 BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
Colin Crossa97c5d32018-03-28 14:58:31 -0700948 }
Colin Cross89c31582018-04-30 15:55:11 -0700949
Sam Delmerico82602492022-06-10 17:05:42 +0000950 prebuiltJniPackages := android.Paths{}
951 ctx.VisitDirectDeps(func(module android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800952 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +0000953 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
954 }
955 })
956 if len(prebuiltJniPackages) > 0 {
Colin Cross40213022023-12-13 15:19:49 -0800957 android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
Sam Delmerico82602492022-06-10 17:05:42 +0000958 JniPackages: prebuiltJniPackages,
959 })
960 }
Jihoon Kang9aef7772024-06-14 23:45:06 +0000961
962 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
963 AconfigTextFiles: aconfigTextFilePaths,
964 })
mrziwang9f7b9f42024-07-10 12:18:06 -0700965
966 a.setOutputFiles(ctx)
967}
968
969func (a *AndroidLibrary) setOutputFiles(ctx android.ModuleContext) {
970 ctx.SetOutputFiles([]android.Path{a.aarFile}, ".aar")
971 setOutputFiles(ctx, a.Library.Module)
Colin Crossa97c5d32018-03-28 14:58:31 -0700972}
973
Cole Faustb36d31d2024-08-27 16:04:28 -0700974func (a *AndroidLibrary) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
975 a.Library.IDEInfo(ctx, dpInfo)
976 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -0700977}
978
Cole Faustb36d31d2024-08-27 16:04:28 -0700979func (a *aapt) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
Colin Cross8f1b0332024-01-25 13:39:06 -0800980 if a.rJar != nil {
Colin Cross95b53b82023-10-17 13:21:02 -0700981 dpInfo.Jars = append(dpInfo.Jars, a.rJar.String())
982 }
983}
984
Colin Cross1b16b0e2019-02-12 14:41:32 -0800985// android_library builds and links sources into a `.jar` file for the device along with Android resources.
986//
987// An android_library has a single variant that produces a `.jar` file containing `.class` files that were
Sam Delmerico82602492022-06-10 17:05:42 +0000988// compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
Colin Cross1b16b0e2019-02-12 14:41:32 -0800989// with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
990// an android_app module.
Colin Crossa97c5d32018-03-28 14:58:31 -0700991func AndroidLibraryFactory() android.Module {
992 module := &AndroidLibrary{}
993
Colin Crossce6734e2020-06-15 16:09:53 -0700994 module.Module.addHostAndDeviceProperties()
Colin Crossa97c5d32018-03-28 14:58:31 -0700995 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -0700996 &module.aaptProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700997 &module.androidLibraryProperties,
998 &module.sourceProperties)
Colin Crossa97c5d32018-03-28 14:58:31 -0700999
1000 module.androidLibraryProperties.BuildAAR = true
Colin Cross014489c2020-06-02 20:09:13 -07001001 module.Module.linter.library = true
Colin Crossa97c5d32018-03-28 14:58:31 -07001002
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001003 android.InitApexModule(module)
Colin Cross48de9a42018-10-02 13:53:33 -07001004 InitJavaModule(module, android.DeviceSupported)
Colin Crossa97c5d32018-03-28 14:58:31 -07001005 return module
1006}
1007
Colin Crossfabb6082018-02-20 17:22:23 -08001008//
1009// AAR (android library) prebuilts
1010//
Colin Crossfabb6082018-02-20 17:22:23 -08001011
Vinh Trance0781f2022-04-13 01:30:44 +00001012// Properties for android_library_import
Colin Crossfabb6082018-02-20 17:22:23 -08001013type AARImportProperties struct {
Vinh Trance0781f2022-04-13 01:30:44 +00001014 // ARR (android library prebuilt) filepath. Exactly one ARR is required.
Colin Cross27b922f2019-03-04 22:35:41 -08001015 Aars []string `android:"path"`
Vinh Trance0781f2022-04-13 01:30:44 +00001016 // If not blank, set to the version of the sdk to compile against.
1017 // Defaults to private.
1018 // Values are of one of the following forms:
1019 // 1) numerical API level, "current", "none", or "core_platform"
1020 // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
1021 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
1022 // If the SDK kind is empty, it will be set to public
1023 Sdk_version *string
1024 // If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
1025 // Defaults to sdk_version if not set. See sdk_version for possible values.
Colin Cross479884c2018-07-10 13:39:30 -07001026 Min_sdk_version *string
Vinh Trance0781f2022-04-13 01:30:44 +00001027 // List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
Cole Faustb7493472024-08-28 11:55:52 -07001028 Static_libs proptools.Configurable[[]string]
Vinh Trance0781f2022-04-13 01:30:44 +00001029 // List of java libraries that the included ARR (android library prebuilts) has dependencies to.
1030 Libs []string
1031 // If set to true, run Jetifier against .aar file. Defaults to false.
Colin Cross1001a792019-03-21 22:21:39 -07001032 Jetifier *bool
Sam Delmerico82602492022-06-10 17:05:42 +00001033 // If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and
1034 // will be passed transitively through android_libraries to an android_app.
1035 //TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
1036 Extract_jni *bool
Colin Cross21ed4692024-04-24 20:23:38 +00001037
1038 // If set, overrides the manifest extracted from the AAR with the provided path.
1039 Manifest *string `android:"path"`
Colin Crossfabb6082018-02-20 17:22:23 -08001040}
1041
1042type AARImport struct {
1043 android.ModuleBase
Colin Cross48de9a42018-10-02 13:53:33 -07001044 android.DefaultableModuleBase
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001045 android.ApexModuleBase
Colin Crossfabb6082018-02-20 17:22:23 -08001046 prebuilt android.Prebuilt
1047
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001048 // Functionality common to Module and Import.
1049 embeddableInModuleAndImport
1050
Colin Cross9ffaf282024-08-12 13:50:09 -07001051 providesTransitiveHeaderJarsForR8
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001052
Colin Crossfabb6082018-02-20 17:22:23 -08001053 properties AARImportProperties
1054
Colin Cross7707b242024-07-26 12:02:36 -07001055 headerJarFile android.Path
1056 implementationJarFile android.Path
1057 implementationAndResourcesJarFile android.Path
1058 proguardFlags android.Path
1059 exportPackage android.Path
Colin Cross312634e2023-11-21 15:13:56 -08001060 transitiveAaptResourcePackagesFile android.Path
Colin Cross7707b242024-07-26 12:02:36 -07001061 extraAaptPackagesFile android.Path
Colin Cross21ed4692024-04-24 20:23:38 +00001062 manifest android.Path
Colin Cross7707b242024-07-26 12:02:36 -07001063 assetsPackage android.Path
1064 rTxt android.Path
1065 rJar android.Path
Colin Cross66f78822018-05-02 12:58:28 -07001066
Colin Crossab8d1382023-07-14 17:23:41 +00001067 resourcesNodesDepSet *android.DepSet[*resourcesNode]
1068 manifestsDepSet *android.DepSet[android.Path]
Colin Cross56a83212020-09-15 18:30:11 -07001069
1070 hideApexVariantFromMake bool
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001071
Sam Delmerico82602492022-06-10 17:05:42 +00001072 aarPath android.Path
1073 jniPackages android.Paths
Jiyong Park92315372021-04-02 08:45:46 +09001074
1075 sdkVersion android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001076 minSdkVersion android.ApiLevel
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001077
Colin Cross9055e212024-03-23 04:43:41 +00001078 usesLibrary
1079 classLoaderContexts dexpreopt.ClassLoaderContextMap
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001080}
1081
Jiyong Park92315372021-04-02 08:45:46 +09001082func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
1083 return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -07001084}
1085
Jiyong Parkf1691d22021-03-29 20:11:58 +09001086func (a *AARImport) SystemModules() string {
Paul Duffine25c6442019-10-11 13:50:28 +01001087 return ""
1088}
1089
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001090func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Colin Cross479884c2018-07-10 13:39:30 -07001091 if a.properties.Min_sdk_version != nil {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001092 return android.ApiLevelFrom(ctx, *a.properties.Min_sdk_version)
Colin Cross479884c2018-07-10 13:39:30 -07001093 }
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001094 return a.SdkVersion(ctx).ApiLevel
Colin Cross83bb3162018-06-25 15:48:06 -07001095}
1096
Spandan Dasa26eda72023-03-02 00:56:06 +00001097func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
1098 return android.SdkSpecFrom(ctx, "").ApiLevel
William Loh5a082f92022-05-17 20:21:50 +00001099}
1100
Spandan Dasca70fc42023-03-01 23:38:49 +00001101func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
1102 return a.SdkVersion(ctx).ApiLevel
Dan Willemsen419290a2018-10-31 15:28:47 -07001103}
1104
Colin Cross1e743852019-10-28 11:37:20 -07001105func (a *AARImport) javaVersion() string {
1106 return ""
1107}
1108
Colin Crossa97c5d32018-03-28 14:58:31 -07001109var _ AndroidLibraryDependency = (*AARImport)(nil)
1110
1111func (a *AARImport) ExportPackage() android.Path {
1112 return a.exportPackage
1113}
Colin Crossab8d1382023-07-14 17:23:41 +00001114func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
1115 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -08001116}
1117
Colin Crossab8d1382023-07-14 17:23:41 +00001118func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] {
1119 return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil)
Colin Cross66f78822018-05-02 12:58:28 -07001120}
1121
Colin Crossab8d1382023-07-14 17:23:41 +00001122func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] {
1123 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -08001124}
1125
Jaewoong Jungc779cd42020-10-06 18:56:10 -07001126// RRO enforcement is not available on aar_import since its RRO dirs are not
1127// exported.
1128func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
1129}
1130
1131// RRO enforcement is not available on aar_import since its RRO dirs are not
1132// exported.
1133func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
1134 return false
1135}
1136
Colin Crossfabb6082018-02-20 17:22:23 -08001137func (a *AARImport) Prebuilt() *android.Prebuilt {
1138 return &a.prebuilt
1139}
1140
1141func (a *AARImport) Name() string {
1142 return a.prebuilt.Name(a.ModuleBase.Name())
1143}
1144
Jiyong Park618922e2020-01-08 13:35:43 +09001145func (a *AARImport) JacocoReportClassesFile() android.Path {
1146 return nil
1147}
1148
Colin Crossfabb6082018-02-20 17:22:23 -08001149func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
Jeongik Cha816a23a2020-07-08 01:09:23 +09001150 if !ctx.Config().AlwaysUsePrebuiltSdks() {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001151 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Colin Crossa97c5d32018-03-28 14:58:31 -07001152 if sdkDep.useModule && sdkDep.frameworkResModule != "" {
Colin Cross42d48b72018-08-29 14:10:52 -07001153 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossfabb6082018-02-20 17:22:23 -08001154 }
1155 }
Colin Crossa97c5d32018-03-28 14:58:31 -07001156
Colin Cross42d48b72018-08-29 14:10:52 -07001157 ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
Cole Faustb7493472024-08-28 11:55:52 -07001158 ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs.GetOrDefault(ctx, nil)...)
Colin Cross9055e212024-03-23 04:43:41 +00001159
1160 a.usesLibrary.deps(ctx, false)
Colin Crossfabb6082018-02-20 17:22:23 -08001161}
1162
Sam Delmerico82602492022-06-10 17:05:42 +00001163type JniPackageInfo struct {
1164 // List of zip files containing JNI libraries
1165 // Zip files should have directory structure jni/<arch>/*.so
1166 JniPackages android.Paths
1167}
1168
Colin Crossbc7d76c2023-12-12 16:39:03 -08001169var JniPackageProvider = blueprint.NewProvider[JniPackageInfo]()
Sam Delmerico82602492022-06-10 17:05:42 +00001170
1171// Unzip an AAR and extract the JNI libs for $archString.
1172var extractJNI = pctx.AndroidStaticRule("extractJNI",
1173 blueprint.RuleParams{
1174 Command: `rm -rf $out $outDir && touch $out && ` +
1175 `unzip -qoDD -d $outDir $in "jni/${archString}/*" && ` +
1176 `jni_files=$$(find $outDir/jni -type f) && ` +
1177 // print error message if there are no JNI libs for this arch
1178 `[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` +
Sam Delmerico80ee45c2023-06-22 15:36:02 -04001179 `${config.SoongZipCmd} -o $out -L 0 -P 'lib/${archString}' ` +
Sam Delmerico82602492022-06-10 17:05:42 +00001180 `-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`,
1181 CommandDeps: []string{"${config.SoongZipCmd}"},
1182 },
1183 "outDir", "archString")
1184
Colin Crossfabb6082018-02-20 17:22:23 -08001185// 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 -07001186// 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 -08001187var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
1188 blueprint.RuleParams{
Dan Willemsen304cfec2019-05-28 14:49:06 -07001189 Command: `rm -rf $outDir && mkdir -p $outDir && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001190 `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001191 `${config.Zip2ZipCmd} -i $in -o $assetsPackage 'assets/**/*' && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001192 `${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001193 CommandDeps: []string{"${config.MergeZipsCmd}", "${config.Zip2ZipCmd}"},
Colin Crossfabb6082018-02-20 17:22:23 -08001194 },
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001195 "outDir", "combinedClassesJar", "assetsPackage")
Colin Crossfabb6082018-02-20 17:22:23 -08001196
1197func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1198 if len(a.properties.Aars) != 1 {
1199 ctx.PropertyErrorf("aars", "exactly one aar is required")
1200 return
1201 }
1202
Jiyong Park92315372021-04-02 08:45:46 +09001203 a.sdkVersion = a.SdkVersion(ctx)
1204 a.minSdkVersion = a.MinSdkVersion(ctx)
1205
Colin Crossff694a82023-12-13 15:54:49 -08001206 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
1207 a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
Colin Cross56a83212020-09-15 18:30:11 -07001208
Nan Zhang4c819fb2018-08-27 18:31:46 -07001209 aarName := ctx.ModuleName() + ".aar"
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001210 a.aarPath = android.PathForModuleSrc(ctx, a.properties.Aars[0])
1211
Colin Cross1001a792019-03-21 22:21:39 -07001212 if Bool(a.properties.Jetifier) {
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001213 inputFile := a.aarPath
Colin Cross77965d92024-08-15 17:11:08 -07001214 jetifierPath := android.PathForModuleOut(ctx, "jetifier", aarName)
1215 TransformJetifier(ctx, jetifierPath, inputFile)
1216 a.aarPath = jetifierPath
Nan Zhang4c819fb2018-08-27 18:31:46 -07001217 }
Colin Crossfabb6082018-02-20 17:22:23 -08001218
Colin Cross607bbd62024-04-12 13:44:45 -07001219 jarName := ctx.ModuleName() + ".jar"
Colin Crossfabb6082018-02-20 17:22:23 -08001220 extractedAARDir := android.PathForModuleOut(ctx, "aar")
Colin Cross607bbd62024-04-12 13:44:45 -07001221 classpathFile := extractedAARDir.Join(ctx, jarName)
Colin Cross21ed4692024-04-24 20:23:38 +00001222
1223 extractedManifest := extractedAARDir.Join(ctx, "AndroidManifest.xml")
1224 providedManifest := android.OptionalPathForModuleSrc(ctx, a.properties.Manifest)
1225 if providedManifest.Valid() {
1226 a.manifest = providedManifest.Path()
1227 } else {
1228 a.manifest = extractedManifest
1229 }
1230
Colin Cross7707b242024-07-26 12:02:36 -07001231 rTxt := extractedAARDir.Join(ctx, "R.txt")
1232 assetsPackage := android.PathForModuleOut(ctx, "assets.zip")
1233 proguardFlags := extractedAARDir.Join(ctx, "proguard.txt")
Colin Crosscde55342024-03-27 14:11:51 -07001234 transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
Colin Cross40213022023-12-13 15:19:49 -08001235 android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
Sam Delmerico95d70942023-08-02 18:00:35 -04001236 ProguardFlagsFiles: android.NewDepSet[android.Path](
1237 android.POSTORDER,
Colin Cross7707b242024-07-26 12:02:36 -07001238 android.Paths{proguardFlags},
Colin Crosscde55342024-03-27 14:11:51 -07001239 transitiveProguardFlags,
1240 ),
1241 UnconditionallyExportedProguardFlags: android.NewDepSet[android.Path](
1242 android.POSTORDER,
Sam Delmerico95d70942023-08-02 18:00:35 -04001243 nil,
Colin Crosscde55342024-03-27 14:11:51 -07001244 transitiveUnconditionalExportedFlags,
Sam Delmerico95d70942023-08-02 18:00:35 -04001245 ),
1246 })
Colin Crossfabb6082018-02-20 17:22:23 -08001247
1248 ctx.Build(pctx, android.BuildParams{
1249 Rule: unzipAAR,
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001250 Input: a.aarPath,
Colin Cross7707b242024-07-26 12:02:36 -07001251 Outputs: android.WritablePaths{classpathFile, proguardFlags, extractedManifest, assetsPackage, rTxt},
Colin Crossfabb6082018-02-20 17:22:23 -08001252 Description: "unzip AAR",
1253 Args: map[string]string{
Colin Cross205e9112020-08-06 13:20:17 -07001254 "outDir": extractedAARDir.String(),
Colin Cross9055e212024-03-23 04:43:41 +00001255 "combinedClassesJar": classpathFile.String(),
Colin Cross7707b242024-07-26 12:02:36 -07001256 "assetsPackage": assetsPackage.String(),
Colin Crossfabb6082018-02-20 17:22:23 -08001257 },
1258 })
1259
Colin Cross7707b242024-07-26 12:02:36 -07001260 a.proguardFlags = proguardFlags
1261 a.assetsPackage = assetsPackage
1262 a.rTxt = rTxt
1263
Colin Crossa0ba2f52019-06-22 12:59:27 -07001264 // Always set --pseudo-localize, it will be stripped out later for release
1265 // builds that don't want it.
1266 compileFlags := []string{"--pseudo-localize"}
Colin Crossfabb6082018-02-20 17:22:23 -08001267 compiledResDir := android.PathForModuleOut(ctx, "flat-res")
Colin Crossfabb6082018-02-20 17:22:23 -08001268 flata := compiledResDir.Join(ctx, "gen_res.flata")
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001269 aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
Colin Crossfabb6082018-02-20 17:22:23 -08001270
Colin Cross7707b242024-07-26 12:02:36 -07001271 exportPackage := android.PathForModuleOut(ctx, "package-res.apk")
Colin Crossfabb6082018-02-20 17:22:23 -08001272 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
Colin Crossbb77d8e2024-02-15 14:43:47 -08001273 aaptRTxt := android.PathForModuleOut(ctx, "R.txt")
Colin Cross7707b242024-07-26 12:02:36 -07001274 extraAaptPackagesFile := android.PathForModuleOut(ctx, "extra_packages")
Colin Crossfabb6082018-02-20 17:22:23 -08001275
1276 var linkDeps android.Paths
1277
1278 linkFlags := []string{
1279 "--static-lib",
Colin Cross4eae06d2023-06-20 22:40:02 -07001280 "--merge-only",
Colin Crossfabb6082018-02-20 17:22:23 -08001281 "--auto-add-overlay",
Colin Cross7c4dc5d2024-02-13 14:29:45 -08001282 "--no-static-lib-packages",
Colin Crossfabb6082018-02-20 17:22:23 -08001283 }
1284
Colin Cross10f7c4a2018-05-23 10:59:28 -07001285 linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
1286 linkDeps = append(linkDeps, a.manifest)
Colin Crossfabb6082018-02-20 17:22:23 -08001287
Colin Cross8676c8c2023-10-12 15:58:57 -07001288 staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
Jiakai Zhang36937082024-04-15 11:15:50 +00001289 aaptLibs(ctx, android.SdkContext(a), nil, nil)
Colin Cross31656952018-05-24 16:11:20 -07001290
Colin Cross8676c8c2023-10-12 15:58:57 -07001291 _ = sharedResourcesNodesDepSet
Colin Crossab8d1382023-07-14 17:23:41 +00001292 _ = staticRRODirsDepSet
Colin Cross8676c8c2023-10-12 15:58:57 -07001293
Colin Crossab8d1382023-07-14 17:23:41 +00001294 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
Colin Crossfabb6082018-02-20 17:22:23 -08001295
Colin Crossab8d1382023-07-14 17:23:41 +00001296 linkDeps = append(linkDeps, sharedLibs...)
Colin Cross4eae06d2023-06-20 22:40:02 -07001297 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -07001298 linkFlags = append(linkFlags, libFlags...)
Colin Crossfabb6082018-02-20 17:22:23 -08001299
Colin Cross4eae06d2023-06-20 22:40:02 -07001300 overlayRes := android.Paths{flata}
1301
1302 // Treat static library dependencies of static libraries as imports.
1303 transitiveStaticLibs := staticDeps.resPackages()
1304 linkDeps = append(linkDeps, transitiveStaticLibs...)
1305 for _, staticLib := range transitiveStaticLibs {
1306 linkFlags = append(linkFlags, "-I "+staticLib.String())
1307 }
Colin Crossfabb6082018-02-20 17:22:23 -08001308
Colin Crossab8d1382023-07-14 17:23:41 +00001309 transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
Colin Cross7707b242024-07-26 12:02:36 -07001310 aapt2Link(ctx, exportPackage, nil, proguardOptionsFile, aaptRTxt,
Jihoon Kang84b25892023-12-01 22:01:06 +00001311 linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
Colin Crossa6182ab2024-08-21 10:47:44 -07001312 ctx.CheckbuildFile(exportPackage)
Colin Cross7707b242024-07-26 12:02:36 -07001313 a.exportPackage = exportPackage
Colin Crossfabb6082018-02-20 17:22:23 -08001314
Colin Cross7707b242024-07-26 12:02:36 -07001315 rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
1316 resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, rJar, nil, true, nil, false)
Colin Crossa6182ab2024-08-21 10:47:44 -07001317 ctx.CheckbuildFile(rJar)
Colin Cross7707b242024-07-26 12:02:36 -07001318 a.rJar = rJar
Colin Cross4eae06d2023-06-20 22:40:02 -07001319
Colin Cross7707b242024-07-26 12:02:36 -07001320 aapt2ExtractExtraPackages(ctx, extraAaptPackagesFile, a.rJar)
1321 a.extraAaptPackagesFile = extraAaptPackagesFile
Colin Crossf3b7bad2023-08-02 15:49:00 -07001322
Colin Crossab8d1382023-07-14 17:23:41 +00001323 resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
1324 resourcesNodesDepSetBuilder.Direct(&resourcesNode{
1325 resPackage: a.exportPackage,
1326 manifest: a.manifest,
Colin Cross4eae06d2023-06-20 22:40:02 -07001327 rTxt: a.rTxt,
1328 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +00001329 assets: android.OptionalPathForPath(a.assetsPackage),
Colin Cross4eae06d2023-06-20 22:40:02 -07001330
1331 usedResourceProcessor: true,
Colin Crossab8d1382023-07-14 17:23:41 +00001332 })
1333 resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
1334 a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
1335
1336 manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
Colin Cross9055e212024-03-23 04:43:41 +00001337 manifestDepSetBuilder.Transitive(staticManifestsDepSet)
Colin Crossab8d1382023-07-14 17:23:41 +00001338 a.manifestsDepSet = manifestDepSetBuilder.Build()
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001339
Colin Cross312634e2023-11-21 15:13:56 -08001340 transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
1341 transitiveAaptResourcePackages = slices.DeleteFunc(transitiveAaptResourcePackages, func(p string) bool {
1342 return p == a.exportPackage.String()
1343 })
1344 transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
1345 android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
1346 a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
Colin Cross4eae06d2023-06-20 22:40:02 -07001347
Colin Cross9ffaf282024-08-12 13:50:09 -07001348 a.collectTransitiveHeaderJarsForR8(ctx)
Colin Cross9055e212024-03-23 04:43:41 +00001349
1350 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
1351
1352 var staticJars android.Paths
1353 var staticHeaderJars android.Paths
Colin Cross607bbd62024-04-12 13:44:45 -07001354 var staticResourceJars android.Paths
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001355 var transitiveStaticLibsHeaderJars []*android.DepSet[android.Path]
1356 var transitiveStaticLibsImplementationJars []*android.DepSet[android.Path]
1357 var transitiveStaticLibsResourceJars []*android.DepSet[android.Path]
1358
Colin Cross9055e212024-03-23 04:43:41 +00001359 ctx.VisitDirectDeps(func(module android.Module) {
1360 if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
1361 tag := ctx.OtherModuleDependencyTag(module)
1362 switch tag {
1363 case staticLibTag:
1364 staticJars = append(staticJars, dep.ImplementationJars...)
1365 staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
Colin Cross607bbd62024-04-12 13:44:45 -07001366 staticResourceJars = append(staticResourceJars, dep.ResourceJars...)
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001367 if dep.TransitiveStaticLibsHeaderJars != nil {
1368 transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
1369 }
1370 if dep.TransitiveStaticLibsImplementationJars != nil {
1371 transitiveStaticLibsImplementationJars = append(transitiveStaticLibsImplementationJars, dep.TransitiveStaticLibsImplementationJars)
1372 }
1373 if dep.TransitiveStaticLibsResourceJars != nil {
1374 transitiveStaticLibsResourceJars = append(transitiveStaticLibsResourceJars, dep.TransitiveStaticLibsResourceJars)
1375 }
Colin Cross9055e212024-03-23 04:43:41 +00001376 }
1377 }
1378 addCLCFromDep(ctx, module, a.classLoaderContexts)
Jiakai Zhang36937082024-04-15 11:15:50 +00001379 addMissingOptionalUsesLibsFromDep(ctx, module, &a.usesLibrary)
Colin Cross9055e212024-03-23 04:43:41 +00001380 })
1381
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001382 completeStaticLibsHeaderJars := android.NewDepSet(android.PREORDER, android.Paths{classpathFile}, transitiveStaticLibsHeaderJars)
1383 completeStaticLibsImplementationJars := android.NewDepSet(android.PREORDER, android.Paths{classpathFile}, transitiveStaticLibsImplementationJars)
1384 completeStaticLibsResourceJars := android.NewDepSet(android.PREORDER, nil, transitiveStaticLibsResourceJars)
1385
Colin Cross77965d92024-08-15 17:11:08 -07001386 var implementationJarFile android.Path
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001387 var combineJars android.Paths
1388 if ctx.Config().UseTransitiveJarsInClasspath() {
1389 combineJars = completeStaticLibsImplementationJars.ToList()
1390 } else {
1391 combineJars = append(android.Paths{classpathFile}, staticJars...)
1392 }
1393
1394 if len(combineJars) > 1 {
1395 implementationJarOutputPath := android.PathForModuleOut(ctx, "combined", jarName)
1396 TransformJarsToJar(ctx, implementationJarOutputPath, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
1397 implementationJarFile = implementationJarOutputPath
Colin Cross9055e212024-03-23 04:43:41 +00001398 } else {
Colin Cross28ac2ff2024-04-02 12:21:34 -07001399 implementationJarFile = classpathFile
Colin Cross9055e212024-03-23 04:43:41 +00001400 }
1401
Colin Cross607bbd62024-04-12 13:44:45 -07001402 var resourceJarFile android.Path
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001403 var resourceJars android.Paths
1404 if ctx.Config().UseTransitiveJarsInClasspath() {
1405 resourceJars = completeStaticLibsResourceJars.ToList()
1406 } else {
1407 resourceJars = staticResourceJars
1408 }
1409 if len(resourceJars) > 1 {
Colin Cross607bbd62024-04-12 13:44:45 -07001410 combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001411 TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
Colin Cross607bbd62024-04-12 13:44:45 -07001412 false, nil, nil)
1413 resourceJarFile = combinedJar
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001414 } else if len(resourceJars) == 1 {
1415 resourceJarFile = resourceJars[0]
Colin Cross607bbd62024-04-12 13:44:45 -07001416 }
1417
1418 // merge implementation jar with resources if necessary
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001419 var implementationAndResourcesJars android.Paths
1420 if ctx.Config().UseTransitiveJarsInClasspath() {
1421 implementationAndResourcesJars = append(slices.Clone(resourceJars), combineJars...)
1422 } else {
1423 implementationAndResourcesJars = android.PathsIfNonNil(resourceJarFile, implementationJarFile)
1424 }
1425 var implementationAndResourcesJar android.Path
1426 if len(implementationAndResourcesJars) > 1 {
Colin Cross77965d92024-08-15 17:11:08 -07001427 combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001428 TransformJarsToJar(ctx, combinedJar, "for resources", implementationAndResourcesJars, android.OptionalPath{},
Colin Cross607bbd62024-04-12 13:44:45 -07001429 false, nil, nil)
1430 implementationAndResourcesJar = combinedJar
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001431 } else {
1432 implementationAndResourcesJar = implementationAndResourcesJars[0]
Colin Cross607bbd62024-04-12 13:44:45 -07001433 }
1434
1435 a.implementationJarFile = implementationJarFile
Colin Cross28ac2ff2024-04-02 12:21:34 -07001436 // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
Colin Cross607bbd62024-04-12 13:44:45 -07001437 a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel()
Colin Cross28ac2ff2024-04-02 12:21:34 -07001438
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001439 var headerJars android.Paths
1440 if ctx.Config().UseTransitiveJarsInClasspath() {
1441 headerJars = completeStaticLibsHeaderJars.ToList()
1442 } else {
1443 headerJars = append(android.Paths{classpathFile}, staticHeaderJars...)
1444 }
1445 if len(headerJars) > 1 {
Colin Cross7707b242024-07-26 12:02:36 -07001446 headerJarFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001447 TransformJarsToJar(ctx, headerJarFile, "combine header jars", headerJars, android.OptionalPath{}, false, nil, nil)
Colin Cross7707b242024-07-26 12:02:36 -07001448 a.headerJarFile = headerJarFile
Colin Cross9055e212024-03-23 04:43:41 +00001449 } else {
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001450 a.headerJarFile = headerJars[0]
Colin Cross9055e212024-03-23 04:43:41 +00001451 }
1452
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001453 if ctx.Config().UseTransitiveJarsInClasspath() {
1454 ctx.CheckbuildFile(classpathFile)
1455 } else {
1456 ctx.CheckbuildFile(a.headerJarFile)
1457 ctx.CheckbuildFile(a.implementationJarFile)
1458 }
Colin Crossa6182ab2024-08-21 10:47:44 -07001459
Colin Cross7727c7f2024-07-18 15:36:32 -07001460 android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
Colin Crossc9b4f6b2024-07-26 15:25:46 -07001461 HeaderJars: android.PathsIfNonNil(a.headerJarFile),
1462 LocalHeaderJars: android.PathsIfNonNil(classpathFile),
1463 TransitiveStaticLibsHeaderJars: completeStaticLibsHeaderJars,
1464 TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
1465 TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars,
1466 ResourceJars: android.PathsIfNonNil(resourceJarFile),
1467 TransitiveLibsHeaderJarsForR8: a.transitiveLibsHeaderJarsForR8,
1468 TransitiveStaticLibsHeaderJarsForR8: a.transitiveStaticLibsHeaderJarsForR8,
1469 ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile),
1470 ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
1471 StubsLinkType: Implementation,
Joe Onorato6fe59eb2023-07-16 13:20:33 -07001472 // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
Colin Crossdcf71b22021-02-01 13:59:03 -08001473 })
Sam Delmerico82602492022-06-10 17:05:42 +00001474
1475 if proptools.Bool(a.properties.Extract_jni) {
1476 for _, t := range ctx.MultiTargets() {
1477 arch := t.Arch.Abi[0]
1478 path := android.PathForModuleOut(ctx, arch+"_jni.zip")
1479 a.jniPackages = append(a.jniPackages, path)
1480
1481 outDir := android.PathForModuleOut(ctx, "aarForJni")
1482 aarPath := android.PathForModuleSrc(ctx, a.properties.Aars[0])
1483 ctx.Build(pctx, android.BuildParams{
1484 Rule: extractJNI,
1485 Input: aarPath,
1486 Outputs: android.WritablePaths{path},
1487 Description: "extract JNI from AAR",
1488 Args: map[string]string{
1489 "outDir": outDir.String(),
1490 "archString": arch,
1491 },
1492 })
1493 }
Sam Delmerico82602492022-06-10 17:05:42 +00001494 }
Colin Crosse8eeec92023-12-14 14:50:05 -08001495
Colin Cross40213022023-12-13 15:19:49 -08001496 android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
Colin Crosse8eeec92023-12-14 14:50:05 -08001497 JniPackages: a.jniPackages,
1498 })
mrziwang68786d82024-07-09 10:41:55 -07001499
1500 ctx.SetOutputFiles([]android.Path{a.implementationAndResourcesJarFile}, "")
1501 ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar")
Colin Crossdcf71b22021-02-01 13:59:03 -08001502}
Colin Crossfabb6082018-02-20 17:22:23 -08001503
1504func (a *AARImport) HeaderJars() android.Paths {
Colin Cross9055e212024-03-23 04:43:41 +00001505 return android.Paths{a.headerJarFile}
Colin Crossfabb6082018-02-20 17:22:23 -08001506}
1507
Colin Cross331a1212018-08-15 20:40:52 -07001508func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
Colin Cross607bbd62024-04-12 13:44:45 -07001509 return android.Paths{a.implementationAndResourcesJarFile}
Colin Cross331a1212018-08-15 20:40:52 -07001510}
1511
Colin Cross9055e212024-03-23 04:43:41 +00001512func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
1513 return OptionalDexJarPath{}
Colin Crossf24a22a2019-01-31 14:12:44 -08001514}
1515
Ulya Trafimovich9f3052c2020-06-09 14:31:19 +01001516func (a *AARImport) DexJarInstallPath() android.Path {
1517 return nil
1518}
1519
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +01001520func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
Colin Cross9055e212024-03-23 04:43:41 +00001521 return a.classLoaderContexts
Jiyong Park1be96912018-05-28 18:02:19 +09001522}
1523
Colin Cross9055e212024-03-23 04:43:41 +00001524var _ UsesLibraryDependency = (*AARImport)(nil)
1525
Jiyong Park45bf82e2020-12-15 22:29:02 +09001526var _ android.ApexModule = (*AARImport)(nil)
1527
1528// Implements android.ApexModule
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001529func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1530 return a.depIsInSameApex(ctx, dep)
1531}
1532
Jiyong Park45bf82e2020-12-15 22:29:02 +09001533// Implements android.ApexModule
Colin Cross9055e212024-03-23 04:43:41 +00001534func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
Dan Albertc8060532020-07-22 22:32:17 -07001535 sdkVersion android.ApiLevel) error {
Jooyung Han749dc692020-04-15 11:03:39 +09001536 return nil
1537}
1538
Sam Delmericoaf8bb702022-07-25 15:39:32 -04001539var _ android.PrebuiltInterface = (*AARImport)(nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001540
Jiakai Zhangf98da192024-04-15 11:15:41 +00001541func (a *AARImport) UsesLibrary() *usesLibrary {
1542 return &a.usesLibrary
1543}
1544
1545var _ ModuleWithUsesLibrary = (*AARImport)(nil)
1546
Colin Cross1b16b0e2019-02-12 14:41:32 -08001547// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
1548//
1549// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
1550// an android_app module.
Colin Crossfabb6082018-02-20 17:22:23 -08001551func AARImportFactory() android.Module {
1552 module := &AARImport{}
1553
Colin Cross9055e212024-03-23 04:43:41 +00001554 module.AddProperties(
1555 &module.properties,
1556 &module.usesLibrary.usesLibraryProperties,
1557 )
Colin Crossfabb6082018-02-20 17:22:23 -08001558
1559 android.InitPrebuiltModule(module, &module.properties.Aars)
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001560 android.InitApexModule(module)
Sam Delmerico82602492022-06-10 17:05:42 +00001561 InitJavaModuleMultiTargets(module, android.DeviceSupported)
Colin Crossfabb6082018-02-20 17:22:23 -08001562 return module
1563}
Spandan Dasb08bf772024-08-07 21:55:42 +00001564
Cole Faustb36d31d2024-08-27 16:04:28 -07001565func (a *AARImport) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
Spandan Dasb08bf772024-08-07 21:55:42 +00001566 dpInfo.Jars = append(dpInfo.Jars, a.headerJarFile.String(), a.rJar.String())
1567}