blob: 511add6bf752c663ecedaf186f079c50bfd09c3d [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 Crossc20dc852020-11-10 12:27:45 -080020 "strconv"
Colin Crossa97c5d32018-03-28 14:58:31 -070021 "strings"
Colin Crossfabb6082018-02-20 17:22:23 -080022
Jaewoong Jung9befb0c2020-01-18 10:33:43 -080023 "android/soong/android"
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -050024 "android/soong/bazel"
Ulya Trafimovich31e444e2020-08-14 17:32:16 +010025 "android/soong/dexpreopt"
Jaewoong Jung9befb0c2020-01-18 10:33:43 -080026
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) {
48 ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
49 })
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
Colin Crossa97c5d32018-03-28 14:58:31 -070068 // list of directories relative to the Blueprints file containing assets.
Colin Cross0ddae7f2019-02-07 15:30:01 -080069 // Defaults to ["assets"] if a directory called assets exists. Set to []
70 // to disable the default.
Colin Crossa97c5d32018-03-28 14:58:31 -070071 Asset_dirs []string
72
73 // list of directories relative to the Blueprints file containing
Colin Cross0ddae7f2019-02-07 15:30:01 -080074 // Android resources. Defaults to ["res"] if a directory called res exists.
75 // Set to [] to disable the default.
Colin Crossa97c5d32018-03-28 14:58:31 -070076 Resource_dirs []string
77
Colin Crossa592e3e2019-02-19 16:59:53 -080078 // list of zip files containing Android resources.
Colin Cross27b922f2019-03-04 22:35:41 -080079 Resource_zips []string `android:"path"`
Colin Crossa592e3e2019-02-19 16:59:53 -080080
Colin Crossa97c5d32018-03-28 14:58:31 -070081 // path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml".
Colin Cross27b922f2019-03-04 22:35:41 -080082 Manifest *string `android:"path"`
changho.shinb5432b72019-08-08 18:37:17 +090083
84 // paths to additional manifest files to merge with main manifest.
85 Additional_manifests []string `android:"path"`
Sasha Smundak541056c2019-10-28 15:50:06 -070086
87 // do not include AndroidManifest from dependent libraries
88 Dont_merge_manifests *bool
Jaewoong Jungc779cd42020-10-06 18:56:10 -070089
Colin Cross4eae06d2023-06-20 22:40:02 -070090 // If use_resource_processor is set, use Bazel's resource processor instead of aapt2 to generate R.class files.
91 // The resource processor produces more optimal R.class files that only list resources in the package of the
92 // library that provided them, as opposed to aapt2 which produces R.java files for every package containing
93 // every resource. Using the resource processor can provide significant build time speedups, but requires
94 // fixing the module to use the correct package to reference each resource, and to avoid having any other
95 // libraries in the tree that use the same package name. Defaults to false, but will default to true in the
96 // future.
97 Use_resource_processor *bool
98
Jaewoong Jungc779cd42020-10-06 18:56:10 -070099 // true if RRO is enforced for any of the dependent modules
100 RROEnforcedForDependent bool `blueprint:"mutated"`
Colin Crossa97c5d32018-03-28 14:58:31 -0700101}
102
103type aapt struct {
Colin Cross4eae06d2023-06-20 22:40:02 -0700104 aaptSrcJar android.Path
105 transitiveAaptRJars android.Paths
106 transitiveAaptResourcePackages android.Paths
107 exportPackage android.Path
108 manifestPath android.Path
109 proguardOptionsFile android.Path
110 rTxt android.Path
111 rJar android.Path
112 extraAaptPackagesFile android.Path
113 mergedManifestFile android.Path
114 noticeFile android.OptionalPath
115 assetPackage android.OptionalPath
116 isLibrary bool
117 defaultManifestVersion string
118 useEmbeddedNativeLibs bool
119 useEmbeddedDex bool
120 usesNonSdkApis bool
121 hasNoCode bool
122 LoggingParent string
123 resourceFiles android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700124
Colin Crosse560c4a2019-03-19 16:03:11 -0700125 splitNames []string
126 splits []split
127
Colin Crossa97c5d32018-03-28 14:58:31 -0700128 aaptProperties aaptProperties
Colin Crossab8d1382023-07-14 17:23:41 +0000129
130 resourcesNodesDepSet *android.DepSet[*resourcesNode]
131 rroDirsDepSet *android.DepSet[rroDir]
132 manifestsDepSet *android.DepSet[android.Path]
Colin Crossa97c5d32018-03-28 14:58:31 -0700133}
134
Colin Crosse560c4a2019-03-19 16:03:11 -0700135type split struct {
136 name string
137 suffix string
138 path android.Path
139}
140
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700141// Propagate RRO enforcement flag to static lib dependencies transitively.
142func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
143 m := ctx.Module()
144 if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) {
145 ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
146 if a, ok := d.(AndroidLibraryDependency); ok {
147 a.SetRROEnforcedForDependent(true)
148 }
149 })
150 }
151}
152
Colin Cross4eae06d2023-06-20 22:40:02 -0700153func (a *aapt) useResourceProcessorBusyBox() bool {
154 return BoolDefault(a.aaptProperties.Use_resource_processor, false)
155}
156
Colin Crossa97c5d32018-03-28 14:58:31 -0700157func (a *aapt) ExportPackage() android.Path {
158 return a.exportPackage
159}
Colin Crossab8d1382023-07-14 17:23:41 +0000160func (a *aapt) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
161 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800162}
163
Colin Crossab8d1382023-07-14 17:23:41 +0000164func (a *aapt) RRODirsDepSet() *android.DepSet[rroDir] {
165 return a.rroDirsDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800166}
167
Colin Crossab8d1382023-07-14 17:23:41 +0000168func (a *aapt) ManifestsDepSet() *android.DepSet[android.Path] {
169 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800170}
171
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700172func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
173 a.aaptProperties.RROEnforcedForDependent = enforce
174}
175
176func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
177 // True if RRO is enforced for this module or...
178 return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
Jeongik Chacee5ba92021-02-19 12:11:51 +0900179 // if RRO is enforced for any of its dependents.
180 a.aaptProperties.RROEnforcedForDependent
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700181}
182
Jiyong Parkf1691d22021-03-29 20:11:58 +0900183func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkContext,
Colin Crossa0ba2f52019-06-22 12:59:27 -0700184 manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
185 resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700186
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800187 hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
188 hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
Colin Crossa97c5d32018-03-28 14:58:31 -0700189
Colin Crossa97c5d32018-03-28 14:58:31 -0700190 // Flags specified in Android.bp
191 linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
192
Colin Crossa97c5d32018-03-28 14:58:31 -0700193 // Find implicit or explicit asset and resource dirs
194 assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
195 resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
Colin Cross8a497952019-03-05 22:25:09 -0800196 resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
Colin Crossa97c5d32018-03-28 14:58:31 -0700197
Colin Crossa97c5d32018-03-28 14:58:31 -0700198 // Glob directories into lists of paths
199 for _, dir := range resourceDirs {
200 resDirs = append(resDirs, globbedResourceDir{
201 dir: dir,
202 files: androidResourceGlob(ctx, dir),
203 })
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700204 resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
Colin Crossa97c5d32018-03-28 14:58:31 -0700205 overlayDirs = append(overlayDirs, resOverlayDirs...)
206 rroDirs = append(rroDirs, resRRODirs...)
207 }
208
Colin Crossc20dc852020-11-10 12:27:45 -0800209 var assetDeps android.Paths
210 for i, dir := range assetDirs {
211 // Add a dependency on every file in the asset directory. This ensures the aapt2
212 // rule will be rerun if one of the files in the asset directory is modified.
213 assetDeps = append(assetDeps, androidResourceGlob(ctx, dir)...)
214
215 // Add a dependency on a file that contains a list of all the files in the asset directory.
216 // This ensures the aapt2 rule will be run if a file is removed from the asset directory,
217 // or a file is added whose timestamp is older than the output of aapt2.
218 assetFileListFile := android.PathForModuleOut(ctx, "asset_dir_globs", strconv.Itoa(i)+".glob")
219 androidResourceGlobList(ctx, dir, assetFileListFile)
220 assetDeps = append(assetDeps, assetFileListFile)
Colin Crossa97c5d32018-03-28 14:58:31 -0700221 }
222
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700223 assetDirStrings := assetDirs.Strings()
224 if a.noticeFile.Valid() {
225 assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
Colin Crossc20dc852020-11-10 12:27:45 -0800226 assetDeps = append(assetDeps, a.noticeFile.Path())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700227 }
228
Colin Crossa97c5d32018-03-28 14:58:31 -0700229 linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
230 linkDeps = append(linkDeps, manifestPath)
231
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700232 linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
Colin Crossc20dc852020-11-10 12:27:45 -0800233 linkDeps = append(linkDeps, assetDeps...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700234
Spandan Das50885c02023-02-23 21:31:33 +0000235 // Returns the effective version for {min|target}_sdk_version
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000236 effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.ApiLevel) string {
Spandan Das50885c02023-02-23 21:31:33 +0000237 // If {min|target}_sdk_version is current, use sdk_version to determine the effective level
238 // This is necessary for vendor modules.
239 // The effective version does not _only_ depend on {min|target}_sdk_version(level),
240 // but also on the sdk_version (kind+level)
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000241 if minSdkVersion.IsCurrent() {
Spandan Das50885c02023-02-23 21:31:33 +0000242 ret, err := sdkVersion.EffectiveVersionString(ctx)
243 if err != nil {
244 ctx.ModuleErrorf("invalid sdk_version: %s", err)
245 }
246 return ret
247 }
248 ret, err := minSdkVersion.EffectiveVersionString(ctx)
249 if err != nil {
250 ctx.ModuleErrorf("invalid min_sdk_version: %s", err)
251 }
252 return ret
Jiyong Park6a927c42020-01-21 02:03:43 +0900253 }
Spandan Das50885c02023-02-23 21:31:33 +0000254 // SDK version flags
255 sdkVersion := sdkContext.SdkVersion(ctx)
256 minSdkVersion := effectiveVersionString(sdkVersion, sdkContext.MinSdkVersion(ctx))
Colin Crossa97c5d32018-03-28 14:58:31 -0700257
Colin Cross83bb3162018-06-25 15:48:06 -0700258 linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
Spandan Das6450b552023-02-23 19:27:07 +0000259 // Use minSdkVersion for target-sdk-version, even if `target_sdk_version` is set
260 // This behavior has been copied from Make.
Colin Cross83bb3162018-06-25 15:48:06 -0700261 linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
Colin Crossa97c5d32018-03-28 14:58:31 -0700262
Colin Crossa97c5d32018-03-28 14:58:31 -0700263 // Version code
264 if !hasVersionCode {
Dan Albert4f378d72020-07-23 17:32:15 -0700265 linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
Colin Crossa97c5d32018-03-28 14:58:31 -0700266 }
267
268 if !hasVersionName {
Colin Cross402d5e02018-04-25 14:54:06 -0700269 var versionName string
270 if ctx.ModuleName() == "framework-res" {
271 // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
272 // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
Colin Crossbfd347d2018-05-09 11:11:35 -0700273 // if it contains the build number. Use the PlatformVersionName instead.
274 versionName = ctx.Config().PlatformVersionName()
Colin Cross402d5e02018-04-25 14:54:06 -0700275 } else {
276 versionName = ctx.Config().AppsDefaultVersionName()
277 }
Colin Cross0b9f31f2019-02-28 11:00:01 -0800278 versionName = proptools.NinjaEscape(versionName)
Colin Crossa97c5d32018-03-28 14:58:31 -0700279 linkFlags = append(linkFlags, "--version-name ", versionName)
280 }
281
Colin Crossa0ba2f52019-06-22 12:59:27 -0700282 linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
283
284 // Always set --pseudo-localize, it will be stripped out later for release
285 // builds that don't want it.
286 compileFlags = append(compileFlags, "--pseudo-localize")
287
288 return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
Colin Crossa97c5d32018-03-28 14:58:31 -0700289}
290
Paul Duffin250e6192019-06-07 10:44:37 +0100291func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
Colin Cross42308aa2018-11-14 21:44:17 -0800292 if sdkDep.frameworkResModule != "" {
293 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossa97c5d32018-03-28 14:58:31 -0700294 }
295}
296
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800297var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
298 blueprint.RuleParams{
299 Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
300 CommandDeps: []string{"${config.Zip2ZipCmd}"},
301 })
302
Jiyong Parkf1691d22021-03-29 20:11:58 +0900303func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
Paul Duffin06530572022-02-03 17:54:15 +0000304 classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000305 enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {
Colin Cross5446e882019-05-22 10:46:27 -0700306
Colin Crossab8d1382023-07-14 17:23:41 +0000307 staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedDeps, libFlags :=
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100308 aaptLibs(ctx, sdkContext, classLoaderContexts)
Ulya Trafimovich31e444e2020-08-14 17:32:16 +0100309
Paul Duffin06530572022-02-03 17:54:15 +0000310 // Exclude any libraries from the supplied list.
311 classLoaderContexts = classLoaderContexts.ExcludeLibs(excludedLibs)
312
Colin Cross31656952018-05-24 16:11:20 -0700313 // App manifest file
314 manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
315 manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
316
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000317 manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000318 SdkContext: sdkContext,
319 ClassLoaderContexts: classLoaderContexts,
320 IsLibrary: a.isLibrary,
321 DefaultManifestVersion: a.defaultManifestVersion,
322 UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
323 UsesNonSdkApis: a.usesNonSdkApis,
324 UseEmbeddedDex: a.useEmbeddedDex,
325 HasNoCode: a.hasNoCode,
326 LoggingParent: a.LoggingParent,
327 EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000328 })
Colin Cross90c25c62019-04-19 16:22:57 -0700329
Colin Crossab8d1382023-07-14 17:23:41 +0000330 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
331
Luca Stefanifd898822019-09-10 22:13:31 +0200332 // Add additional manifest files to transitive manifests.
333 additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
Colin Crossab8d1382023-07-14 17:23:41 +0000334 transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
335 // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
336 // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
337 // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
338 // android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of
339 // staticResourcesNodesDepSet.manifests()
340 transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
Colin Cross90c25c62019-04-19 16:22:57 -0700341
Colin Crossab8d1382023-07-14 17:23:41 +0000342 if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
343 a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], transitiveManifestPaths[1:], a.isLibrary)
Colin Cross90c25c62019-04-19 16:22:57 -0700344 if !a.isLibrary {
345 // Only use the merged manifest for applications. For libraries, the transitive closure of manifests
346 // will be propagated to the final application and merged there. The merged manifest for libraries is
347 // only passed to Make, which can't handle transitive dependencies.
348 manifestPath = a.mergedManifestFile
349 }
350 } else {
351 a.mergedManifestFile = manifestPath
352 }
Colin Cross31656952018-05-24 16:11:20 -0700353
Colin Crossa0ba2f52019-06-22 12:59:27 -0700354 compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath)
Colin Cross31656952018-05-24 16:11:20 -0700355
356 linkFlags = append(linkFlags, libFlags...)
Colin Crossab8d1382023-07-14 17:23:41 +0000357 linkDeps = append(linkDeps, sharedDeps...)
358 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700359 linkFlags = append(linkFlags, extraLinkFlags...)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700360 if a.isLibrary {
361 linkFlags = append(linkFlags, "--static-lib")
362 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700363
Colin Cross4eae06d2023-06-20 22:40:02 -0700364 if a.isLibrary && a.useResourceProcessorBusyBox() {
365 // When building an android_library using ResourceProcessorBusyBox the resources are merged into
366 // package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
367 // contains resources from this library.
368 linkFlags = append(linkFlags, "--merge-only")
369 } else {
370 // When building and app or when building an android_library without ResourceProcessorBusyBox
371 // --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
372 // is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
373 // sort resources into the right packages in R.class.
374 linkFlags = append(linkFlags, "--no-static-lib-packages")
375 }
376
Colin Crossa97c5d32018-03-28 14:58:31 -0700377 packageRes := android.PathForModuleOut(ctx, "package-res.apk")
Colin Crossa97c5d32018-03-28 14:58:31 -0700378 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
379 rTxt := android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -0700380 // This file isn't used by Soong, but is generated for exporting
381 extraPackages := android.PathForModuleOut(ctx, "extra_packages")
Colin Cross4eae06d2023-06-20 22:40:02 -0700382 var transitiveRJars android.Paths
Colin Crossf3b7bad2023-08-02 15:49:00 -0700383 var srcJar android.WritablePath
Colin Crossa97c5d32018-03-28 14:58:31 -0700384
Colin Cross4aaa84a2018-08-21 15:14:37 -0700385 var compiledResDirs []android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700386 for _, dir := range resDirs {
Colin Cross014489c2020-06-02 20:09:13 -0700387 a.resourceFiles = append(a.resourceFiles, dir.files...)
Colin Crossa0ba2f52019-06-22 12:59:27 -0700388 compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths())
Colin Crossa97c5d32018-03-28 14:58:31 -0700389 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700390
Colin Crossa592e3e2019-02-19 16:59:53 -0800391 for i, zip := range resZips {
392 flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
Colin Crossa0ba2f52019-06-22 12:59:27 -0700393 aapt2CompileZip(ctx, flata, zip, "", compileFlags)
Colin Crossa592e3e2019-02-19 16:59:53 -0800394 compiledResDirs = append(compiledResDirs, android.Paths{flata})
395 }
396
Colin Cross4aaa84a2018-08-21 15:14:37 -0700397 var compiledRes, compiledOverlay android.Paths
398
Colin Crossab8d1382023-07-14 17:23:41 +0000399 // AAPT2 overlays are in lowest to highest priority order, reverse the topological order
400 // of transitiveStaticLibs.
401 transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
402
Colin Cross4eae06d2023-06-20 22:40:02 -0700403 if a.isLibrary && a.useResourceProcessorBusyBox() {
404 // When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
405 // as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
406 // instead modules depending on this module will reference package-res.apk from all transitive static
407 // dependencies.
408 for _, staticDep := range staticDeps {
409 linkDeps = append(linkDeps, staticDep.resPackage)
410 linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
411 if staticDep.usedResourceProcessor {
412 transitiveRJars = append(transitiveRJars, staticDep.rJar)
413 }
414 }
415 } else {
416 // When building an app or building a library without ResourceProcessorBusyBox enabled all static
417 // dependencies are compiled into this module's package-res.apk as overlays.
418 compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
419 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700420
Colin Crossbec85302019-02-13 13:15:46 -0800421 if len(transitiveStaticLibs) > 0 {
Colin Cross4aaa84a2018-08-21 15:14:37 -0700422 // If we are using static android libraries, every source file becomes an overlay.
423 // This is to emulate old AAPT behavior which simulated library support.
424 for _, compiledResDir := range compiledResDirs {
425 compiledOverlay = append(compiledOverlay, compiledResDir...)
426 }
Colin Crossbec85302019-02-13 13:15:46 -0800427 } else if a.isLibrary {
428 // Otherwise, for a static library we treat all the resources equally with no overlay.
429 for _, compiledResDir := range compiledResDirs {
430 compiledRes = append(compiledRes, compiledResDir...)
431 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700432 } else if len(compiledResDirs) > 0 {
433 // Without static libraries, the first directory is our directory, which can then be
434 // overlaid by the rest.
435 compiledRes = append(compiledRes, compiledResDirs[0]...)
436 for _, compiledResDir := range compiledResDirs[1:] {
437 compiledOverlay = append(compiledOverlay, compiledResDir...)
438 }
439 }
440
Colin Crossa97c5d32018-03-28 14:58:31 -0700441 for _, dir := range overlayDirs {
Colin Crossa0ba2f52019-06-22 12:59:27 -0700442 compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700443 }
444
Colin Crosse560c4a2019-03-19 16:03:11 -0700445 var splitPackages android.WritablePaths
446 var splits []split
447
448 for _, s := range a.splitNames {
449 suffix := strings.Replace(s, ",", "_", -1)
450 path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
451 linkFlags = append(linkFlags, "--split", path.String()+":"+s)
452 splitPackages = append(splitPackages, path)
453 splits = append(splits, split{
454 name: s,
455 suffix: suffix,
456 path: path,
457 })
458 }
459
Colin Crossf3b7bad2023-08-02 15:49:00 -0700460 if !a.useResourceProcessorBusyBox() {
461 // the subdir "android" is required to be filtered by package names
462 srcJar = android.PathForModuleGen(ctx, "android", "R.srcjar")
463 }
464
Colin Crossab8d1382023-07-14 17:23:41 +0000465 // No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
466 // provided to the final app aapt2Link step.
467 var transitiveAssets android.Paths
468 if !a.isLibrary {
469 transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
470 }
Colin Crossf3b7bad2023-08-02 15:49:00 -0700471 aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
Colin Crossab8d1382023-07-14 17:23:41 +0000472 linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages)
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800473 // Extract assets from the resource package output so that they can be used later in aapt2link
474 // for modules that depend on this one.
Colin Crossab8d1382023-07-14 17:23:41 +0000475 if android.PrefixInList(linkFlags, "-A ") {
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800476 assets := android.PathForModuleOut(ctx, "assets.zip")
477 ctx.Build(pctx, android.BuildParams{
478 Rule: extractAssetsRule,
479 Input: packageRes,
480 Output: assets,
481 Description: "extract assets from built resource file",
482 })
483 a.assetPackage = android.OptionalPathForPath(assets)
484 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700485
Colin Cross4eae06d2023-06-20 22:40:02 -0700486 if a.useResourceProcessorBusyBox() {
487 rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
488 resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
Colin Crossf3b7bad2023-08-02 15:49:00 -0700489 aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700490 transitiveRJars = append(transitiveRJars, rJar)
491 a.rJar = rJar
Colin Crossf3b7bad2023-08-02 15:49:00 -0700492 } else {
493 aapt2ExtractExtraPackages(ctx, extraPackages, srcJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700494 }
495
Colin Crossa97c5d32018-03-28 14:58:31 -0700496 a.aaptSrcJar = srcJar
Colin Cross4eae06d2023-06-20 22:40:02 -0700497 a.transitiveAaptRJars = transitiveRJars
498 a.transitiveAaptResourcePackages = staticDeps.resPackages()
Colin Crossa97c5d32018-03-28 14:58:31 -0700499 a.exportPackage = packageRes
500 a.manifestPath = manifestPath
501 a.proguardOptionsFile = proguardOptionsFile
Colin Cross66f78822018-05-02 12:58:28 -0700502 a.extraAaptPackagesFile = extraPackages
Colin Crossa97c5d32018-03-28 14:58:31 -0700503 a.rTxt = rTxt
Colin Crosse560c4a2019-03-19 16:03:11 -0700504 a.splits = splits
Colin Crossab8d1382023-07-14 17:23:41 +0000505 a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL).
506 Direct(&resourcesNode{
507 resPackage: a.exportPackage,
508 manifest: a.manifestPath,
509 additionalManifests: additionalManifests,
Colin Cross4eae06d2023-06-20 22:40:02 -0700510 rTxt: a.rTxt,
511 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +0000512 assets: a.assetPackage,
Colin Cross4eae06d2023-06-20 22:40:02 -0700513
514 usedResourceProcessor: a.useResourceProcessorBusyBox(),
Colin Crossab8d1382023-07-14 17:23:41 +0000515 }).
516 Transitive(staticResourcesNodesDepSet).Build()
517 a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
518 Direct(rroDirs...).
519 Transitive(staticRRODirsDepSet).Build()
520 a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
521 Direct(a.manifestPath).
522 DirectSlice(additionalManifests).
523 Transitive(staticManifestsDepSet).Build()
524}
525
Colin Cross4eae06d2023-06-20 22:40:02 -0700526var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
527 blueprint.RuleParams{
528 Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
529 "com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
530 "if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
531 CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
532 Rspfile: "${out}.args",
533 RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
534 Restat: true,
535 }, "rTxt", "manifest", "args")
536
537// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
538// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
539// supports producing classes for static dependencies that only include resources from that dependency.
540func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
541 rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) {
542
543 var args []string
544 var deps android.Paths
545
546 if !isLibrary {
547 // When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
548 // to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
549 // package.
550 args, deps = transitiveDeps.resourceProcessorDeps()
551 } else {
552 // When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
553 // library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
554 // inlined into the library before the final IDs are assigned during app compilation.
555 args = append(args, "--finalFields=false")
556 }
557
558 deps = append(deps, rTxt, manifest)
559
560 ctx.Build(pctx, android.BuildParams{
561 Rule: resourceProcessorBusyBox,
562 Output: rJar,
563 Implicits: deps,
564 Description: "ResourceProcessorBusyBox",
565 Args: map[string]string{
566 "rTxt": rTxt.String(),
567 "manifest": manifest.String(),
568 "args": strings.Join(args, " "),
569 },
570 })
571}
572
Colin Crossab8d1382023-07-14 17:23:41 +0000573type resourcesNode struct {
574 resPackage android.Path
575 manifest android.Path
576 additionalManifests android.Paths
Colin Cross4eae06d2023-06-20 22:40:02 -0700577 rTxt android.Path
578 rJar android.Path
Colin Crossab8d1382023-07-14 17:23:41 +0000579 assets android.OptionalPath
Colin Cross4eae06d2023-06-20 22:40:02 -0700580
581 usedResourceProcessor bool
Colin Crossab8d1382023-07-14 17:23:41 +0000582}
583
584type transitiveAarDeps []*resourcesNode
585
586func (t transitiveAarDeps) resPackages() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700587 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000588 for _, dep := range t {
589 paths = append(paths, dep.resPackage)
590 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700591 return paths
Colin Crossab8d1382023-07-14 17:23:41 +0000592}
593
594func (t transitiveAarDeps) manifests() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700595 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000596 for _, dep := range t {
597 paths = append(paths, dep.manifest)
598 paths = append(paths, dep.additionalManifests...)
599 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700600 return paths
601}
602
603func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
604 for _, dep := range t {
605 args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
606 deps = append(deps, dep.rTxt, dep.manifest)
607 }
608 return args, deps
Colin Crossab8d1382023-07-14 17:23:41 +0000609}
610
611func (t transitiveAarDeps) assets() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700612 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000613 for _, dep := range t {
614 if dep.assets.Valid() {
615 paths = append(paths, dep.assets.Path())
616 }
617 }
618 return paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700619}
620
621// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
Jiyong Parkf1691d22021-03-29 20:11:58 +0900622func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
Colin Crossab8d1382023-07-14 17:23:41 +0000623 staticResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
624 staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700625
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100626 if classLoaderContexts == nil {
Ulya Trafimovich18554242020-11-03 15:55:11 +0000627 // Not all callers need to compute class loader context, those who don't just pass nil.
628 // Create a temporary class loader context here (it will be computed, but not used).
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100629 classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000630 }
631
Colin Cross83bb3162018-06-25 15:48:06 -0700632 sdkDep := decodeSdkDep(ctx, sdkContext)
Colin Crossa97c5d32018-03-28 14:58:31 -0700633 if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700634 sharedLibs = append(sharedLibs, sdkDep.jars...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700635 }
636
Colin Crossab8d1382023-07-14 17:23:41 +0000637 var resourcesNodeDepSets []*android.DepSet[*resourcesNode]
638 rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL)
639 manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL)
640
Colin Crossa97c5d32018-03-28 14:58:31 -0700641 ctx.VisitDirectDeps(func(module android.Module) {
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000642 depTag := ctx.OtherModuleDependencyTag(module)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000643
Colin Crossa97c5d32018-03-28 14:58:31 -0700644 var exportPackage android.Path
Colin Cross66f78822018-05-02 12:58:28 -0700645 aarDep, _ := module.(AndroidLibraryDependency)
646 if aarDep != nil {
Colin Crossa97c5d32018-03-28 14:58:31 -0700647 exportPackage = aarDep.ExportPackage()
648 }
649
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000650 switch depTag {
Colin Cross4b964c02018-10-15 16:18:06 -0700651 case instrumentationForTag:
652 // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
Liz Kammeref28a4c2022-09-23 16:50:56 -0400653 case sdkLibTag, libTag:
Colin Cross5446e882019-05-22 10:46:27 -0700654 if exportPackage != nil {
655 sharedLibs = append(sharedLibs, exportPackage)
656 }
Colin Cross5446e882019-05-22 10:46:27 -0700657 case frameworkResTag:
Colin Crossa97c5d32018-03-28 14:58:31 -0700658 if exportPackage != nil {
659 sharedLibs = append(sharedLibs, exportPackage)
660 }
661 case staticLibTag:
662 if exportPackage != nil {
Colin Crossab8d1382023-07-14 17:23:41 +0000663 resourcesNodeDepSets = append(resourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
664 rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
665 manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
Colin Crossa97c5d32018-03-28 14:58:31 -0700666 }
667 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000668
Ulya Trafimovich88bb6f62020-12-16 16:16:11 +0000669 addCLCFromDep(ctx, module, classLoaderContexts)
Colin Crossa97c5d32018-03-28 14:58:31 -0700670 })
671
Colin Crossab8d1382023-07-14 17:23:41 +0000672 // AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
673 // Reverse the dependency order now going into the depset so that it comes out in order after the second
674 // reverse later.
675 // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
676 // dependencies) the highest priority dependency is listed first, but for resources the highest priority
677 // dependency has to be listed last.
678 staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
679 android.ReverseSliceInPlace(resourcesNodeDepSets))
Colin Crossa97c5d32018-03-28 14:58:31 -0700680
Colin Crossab8d1382023-07-14 17:23:41 +0000681 staticRRODirs = rroDirsDepSetBuilder.Build()
682 staticManifests = manifestsDepSetBuilder.Build()
683
684 if len(staticResourcesNodes.ToList()) > 0 {
Colin Crossa97c5d32018-03-28 14:58:31 -0700685 flags = append(flags, "--auto-add-overlay")
686 }
687
688 for _, sharedLib := range sharedLibs {
689 flags = append(flags, "-I "+sharedLib.String())
690 }
691
Colin Crossab8d1382023-07-14 17:23:41 +0000692 return staticResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
Colin Crossa97c5d32018-03-28 14:58:31 -0700693}
694
695type AndroidLibrary struct {
696 Library
697 aapt
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500698 android.BazelModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700699
700 androidLibraryProperties androidLibraryProperties
701
702 aarFile android.WritablePath
Colin Cross89c31582018-04-30 15:55:11 -0700703}
704
Saeid Farivar Asanjan1fca3012021-09-14 18:40:19 +0000705var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
706
707// For OutputFileProducer interface
708func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
709 switch tag {
710 case ".aar":
711 return []android.Path{a.aarFile}, nil
712 default:
713 return a.Library.OutputFiles(tag)
714 }
715}
716
Colin Crossa97c5d32018-03-28 14:58:31 -0700717var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
718
719func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
720 a.Module.deps(ctx)
Jiyong Parkf1691d22021-03-29 20:11:58 +0900721 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Paul Duffin250e6192019-06-07 10:44:37 +0100722 if sdkDep.hasFrameworkLibs() {
723 a.aapt.deps(ctx, sdkDep)
Colin Crossa97c5d32018-03-28 14:58:31 -0700724 }
Colin Cross4a80a152022-12-21 21:51:52 -0800725 a.usesLibrary.deps(ctx, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700726}
727
728func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosse4246ab2019-02-05 21:55:21 -0800729 a.aapt.isLibrary = true
Ulya Trafimovich42c7f0d2021-08-17 16:20:29 +0100730 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000731 a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700732
Colin Cross56a83212020-09-15 18:30:11 -0700733 a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
734
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000735 a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
736
Colin Cross4eae06d2023-06-20 22:40:02 -0700737 ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
738 ctx.CheckbuildFile(a.aapt.exportPackage)
Colin Cross4eae06d2023-06-20 22:40:02 -0700739 if a.useResourceProcessorBusyBox() {
740 ctx.CheckbuildFile(a.aapt.rJar)
Colin Crossf3b7bad2023-08-02 15:49:00 -0700741 } else {
742 ctx.CheckbuildFile(a.aapt.aaptSrcJar)
Colin Cross4eae06d2023-06-20 22:40:02 -0700743 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700744
745 // apps manifests are handled by aapt, don't let Module see them
746 a.properties.Manifest = nil
747
Colin Cross014489c2020-06-02 20:09:13 -0700748 a.linter.mergedManifest = a.aapt.mergedManifestFile
749 a.linter.manifest = a.aapt.manifestPath
750 a.linter.resources = a.aapt.resourceFiles
751
Colin Crossa97c5d32018-03-28 14:58:31 -0700752 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
753 a.proguardOptionsFile)
754
Colin Cross4eae06d2023-06-20 22:40:02 -0700755 var extraSrcJars android.Paths
756 var extraCombinedJars android.Paths
757 var extraClasspathJars android.Paths
758 if a.useResourceProcessorBusyBox() {
759 // When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
760 // library and each of the transitive static android_library dependencies has already created an
761 // R.class file for the appropriate package. Add all of those R.class files to the classpath.
762 extraClasspathJars = a.transitiveAaptRJars
763 } else {
764 // When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
765 // R.java files for the library's package and the packages from all transitive static android_library
766 // dependencies. Compile the srcjar alongside the rest of the sources.
767 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
768 }
769
770 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
Colin Crossa97c5d32018-03-28 14:58:31 -0700771
Colin Crossf57c5782019-01-25 13:20:38 -0800772 a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
Colin Crossa97c5d32018-03-28 14:58:31 -0700773 var res android.Paths
774 if a.androidLibraryProperties.BuildAAR {
775 BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
776 ctx.CheckbuildFile(a.aarFile)
777 }
Colin Cross89c31582018-04-30 15:55:11 -0700778
Sam Delmerico95d70942023-08-02 18:00:35 -0400779 proguardSpecInfo := a.collectProguardSpecInfo(ctx)
780 ctx.SetProvider(ProguardSpecInfoProvider, proguardSpecInfo)
781 a.exportedProguardFlagFiles = proguardSpecInfo.ProguardFlagsFiles.ToList()
Sam Delmerico82602492022-06-10 17:05:42 +0000782
783 prebuiltJniPackages := android.Paths{}
784 ctx.VisitDirectDeps(func(module android.Module) {
785 if info, ok := ctx.OtherModuleProvider(module, JniPackageProvider).(JniPackageInfo); ok {
786 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
787 }
788 })
789 if len(prebuiltJniPackages) > 0 {
790 ctx.SetProvider(JniPackageProvider, JniPackageInfo{
791 JniPackages: prebuiltJniPackages,
792 })
793 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700794}
795
Colin Cross1b16b0e2019-02-12 14:41:32 -0800796// android_library builds and links sources into a `.jar` file for the device along with Android resources.
797//
798// An android_library has a single variant that produces a `.jar` file containing `.class` files that were
Sam Delmerico82602492022-06-10 17:05:42 +0000799// compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
Colin Cross1b16b0e2019-02-12 14:41:32 -0800800// with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
801// an android_app module.
Colin Crossa97c5d32018-03-28 14:58:31 -0700802func AndroidLibraryFactory() android.Module {
803 module := &AndroidLibrary{}
804
Colin Crossce6734e2020-06-15 16:09:53 -0700805 module.Module.addHostAndDeviceProperties()
Colin Crossa97c5d32018-03-28 14:58:31 -0700806 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -0700807 &module.aaptProperties,
808 &module.androidLibraryProperties)
809
810 module.androidLibraryProperties.BuildAAR = true
Colin Cross014489c2020-06-02 20:09:13 -0700811 module.Module.linter.library = true
Colin Crossa97c5d32018-03-28 14:58:31 -0700812
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900813 android.InitApexModule(module)
Colin Cross48de9a42018-10-02 13:53:33 -0700814 InitJavaModule(module, android.DeviceSupported)
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500815 android.InitBazelModule(module)
Colin Crossa97c5d32018-03-28 14:58:31 -0700816 return module
817}
818
Colin Crossfabb6082018-02-20 17:22:23 -0800819//
820// AAR (android library) prebuilts
821//
Colin Crossfabb6082018-02-20 17:22:23 -0800822
Vinh Trance0781f2022-04-13 01:30:44 +0000823// Properties for android_library_import
Colin Crossfabb6082018-02-20 17:22:23 -0800824type AARImportProperties struct {
Vinh Trance0781f2022-04-13 01:30:44 +0000825 // ARR (android library prebuilt) filepath. Exactly one ARR is required.
Colin Cross27b922f2019-03-04 22:35:41 -0800826 Aars []string `android:"path"`
Vinh Trance0781f2022-04-13 01:30:44 +0000827 // If not blank, set to the version of the sdk to compile against.
828 // Defaults to private.
829 // Values are of one of the following forms:
830 // 1) numerical API level, "current", "none", or "core_platform"
831 // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
832 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
833 // If the SDK kind is empty, it will be set to public
834 Sdk_version *string
835 // If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
836 // Defaults to sdk_version if not set. See sdk_version for possible values.
Colin Cross479884c2018-07-10 13:39:30 -0700837 Min_sdk_version *string
Vinh Trance0781f2022-04-13 01:30:44 +0000838 // List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
Colin Crossa97c5d32018-03-28 14:58:31 -0700839 Static_libs []string
Vinh Trance0781f2022-04-13 01:30:44 +0000840 // List of java libraries that the included ARR (android library prebuilts) has dependencies to.
841 Libs []string
842 // If set to true, run Jetifier against .aar file. Defaults to false.
Colin Cross1001a792019-03-21 22:21:39 -0700843 Jetifier *bool
Sam Delmerico82602492022-06-10 17:05:42 +0000844 // If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and
845 // will be passed transitively through android_libraries to an android_app.
846 //TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
847 Extract_jni *bool
Colin Crossfabb6082018-02-20 17:22:23 -0800848}
849
850type AARImport struct {
851 android.ModuleBase
Colin Cross48de9a42018-10-02 13:53:33 -0700852 android.DefaultableModuleBase
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900853 android.ApexModuleBase
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500854 android.BazelModuleBase
Colin Crossfabb6082018-02-20 17:22:23 -0800855 prebuilt android.Prebuilt
856
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900857 // Functionality common to Module and Import.
858 embeddableInModuleAndImport
859
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500860 providesTransitiveHeaderJars
861
Colin Crossfabb6082018-02-20 17:22:23 -0800862 properties AARImportProperties
863
Colin Cross4eae06d2023-06-20 22:40:02 -0700864 classpathFile android.WritablePath
865 proguardFlags android.WritablePath
866 exportPackage android.WritablePath
867 transitiveAaptResourcePackages android.Paths
868 extraAaptPackagesFile android.WritablePath
869 manifest android.WritablePath
870 assetsPackage android.WritablePath
871 rTxt android.WritablePath
872 rJar android.WritablePath
Colin Cross66f78822018-05-02 12:58:28 -0700873
Colin Crossab8d1382023-07-14 17:23:41 +0000874 resourcesNodesDepSet *android.DepSet[*resourcesNode]
875 manifestsDepSet *android.DepSet[android.Path]
Colin Cross56a83212020-09-15 18:30:11 -0700876
877 hideApexVariantFromMake bool
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +0000878
Sam Delmerico82602492022-06-10 17:05:42 +0000879 aarPath android.Path
880 jniPackages android.Paths
Jiyong Park92315372021-04-02 08:45:46 +0900881
882 sdkVersion android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000883 minSdkVersion android.ApiLevel
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +0000884}
885
886var _ android.OutputFileProducer = (*AARImport)(nil)
887
888// For OutputFileProducer interface
889func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
890 switch tag {
891 case ".aar":
892 return []android.Path{a.aarPath}, nil
893 case "":
894 return []android.Path{a.classpathFile}, nil
895 default:
896 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
897 }
Colin Crossfabb6082018-02-20 17:22:23 -0800898}
899
Jiyong Park92315372021-04-02 08:45:46 +0900900func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
901 return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700902}
903
Jiyong Parkf1691d22021-03-29 20:11:58 +0900904func (a *AARImport) SystemModules() string {
Paul Duffine25c6442019-10-11 13:50:28 +0100905 return ""
906}
907
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000908func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Colin Cross479884c2018-07-10 13:39:30 -0700909 if a.properties.Min_sdk_version != nil {
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000910 return android.ApiLevelFrom(ctx, *a.properties.Min_sdk_version)
Colin Cross479884c2018-07-10 13:39:30 -0700911 }
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000912 return a.SdkVersion(ctx).ApiLevel
Colin Cross83bb3162018-06-25 15:48:06 -0700913}
914
Spandan Dasa26eda72023-03-02 00:56:06 +0000915func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
916 return android.SdkSpecFrom(ctx, "").ApiLevel
William Loh5a082f92022-05-17 20:21:50 +0000917}
918
Spandan Dasca70fc42023-03-01 23:38:49 +0000919func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
920 return a.SdkVersion(ctx).ApiLevel
Dan Willemsen419290a2018-10-31 15:28:47 -0700921}
922
Colin Cross1e743852019-10-28 11:37:20 -0700923func (a *AARImport) javaVersion() string {
924 return ""
925}
926
Colin Crossa97c5d32018-03-28 14:58:31 -0700927var _ AndroidLibraryDependency = (*AARImport)(nil)
928
929func (a *AARImport) ExportPackage() android.Path {
930 return a.exportPackage
931}
Colin Crossab8d1382023-07-14 17:23:41 +0000932func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
933 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800934}
935
Colin Crossab8d1382023-07-14 17:23:41 +0000936func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] {
937 return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil)
Colin Cross66f78822018-05-02 12:58:28 -0700938}
939
Colin Crossab8d1382023-07-14 17:23:41 +0000940func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] {
941 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800942}
943
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700944// RRO enforcement is not available on aar_import since its RRO dirs are not
945// exported.
946func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
947}
948
949// RRO enforcement is not available on aar_import since its RRO dirs are not
950// exported.
951func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
952 return false
953}
954
Colin Crossfabb6082018-02-20 17:22:23 -0800955func (a *AARImport) Prebuilt() *android.Prebuilt {
956 return &a.prebuilt
957}
958
959func (a *AARImport) Name() string {
960 return a.prebuilt.Name(a.ModuleBase.Name())
961}
962
Jiyong Park618922e2020-01-08 13:35:43 +0900963func (a *AARImport) JacocoReportClassesFile() android.Path {
964 return nil
965}
966
Colin Crossfabb6082018-02-20 17:22:23 -0800967func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
Jeongik Cha816a23a2020-07-08 01:09:23 +0900968 if !ctx.Config().AlwaysUsePrebuiltSdks() {
Jiyong Parkf1691d22021-03-29 20:11:58 +0900969 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Colin Crossa97c5d32018-03-28 14:58:31 -0700970 if sdkDep.useModule && sdkDep.frameworkResModule != "" {
Colin Cross42d48b72018-08-29 14:10:52 -0700971 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossfabb6082018-02-20 17:22:23 -0800972 }
973 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700974
Colin Cross42d48b72018-08-29 14:10:52 -0700975 ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
976 ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
Colin Crossfabb6082018-02-20 17:22:23 -0800977}
978
Sam Delmerico82602492022-06-10 17:05:42 +0000979type JniPackageInfo struct {
980 // List of zip files containing JNI libraries
981 // Zip files should have directory structure jni/<arch>/*.so
982 JniPackages android.Paths
983}
984
985var JniPackageProvider = blueprint.NewProvider(JniPackageInfo{})
986
987// Unzip an AAR and extract the JNI libs for $archString.
988var extractJNI = pctx.AndroidStaticRule("extractJNI",
989 blueprint.RuleParams{
990 Command: `rm -rf $out $outDir && touch $out && ` +
991 `unzip -qoDD -d $outDir $in "jni/${archString}/*" && ` +
992 `jni_files=$$(find $outDir/jni -type f) && ` +
993 // print error message if there are no JNI libs for this arch
994 `[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` +
995 `${config.SoongZipCmd} -o $out -P 'lib/${archString}' ` +
996 `-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`,
997 CommandDeps: []string{"${config.SoongZipCmd}"},
998 },
999 "outDir", "archString")
1000
Colin Crossfabb6082018-02-20 17:22:23 -08001001// 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 -07001002// 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 -08001003var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
1004 blueprint.RuleParams{
Dan Willemsen304cfec2019-05-28 14:49:06 -07001005 Command: `rm -rf $outDir && mkdir -p $outDir && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001006 `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001007 `${config.Zip2ZipCmd} -i $in -o $assetsPackage 'assets/**/*' && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001008 `${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001009 CommandDeps: []string{"${config.MergeZipsCmd}", "${config.Zip2ZipCmd}"},
Colin Crossfabb6082018-02-20 17:22:23 -08001010 },
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001011 "outDir", "combinedClassesJar", "assetsPackage")
Colin Crossfabb6082018-02-20 17:22:23 -08001012
1013func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1014 if len(a.properties.Aars) != 1 {
1015 ctx.PropertyErrorf("aars", "exactly one aar is required")
1016 return
1017 }
1018
Jiyong Park92315372021-04-02 08:45:46 +09001019 a.sdkVersion = a.SdkVersion(ctx)
1020 a.minSdkVersion = a.MinSdkVersion(ctx)
1021
Colin Cross56a83212020-09-15 18:30:11 -07001022 a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
1023
Nan Zhang4c819fb2018-08-27 18:31:46 -07001024 aarName := ctx.ModuleName() + ".aar"
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001025 a.aarPath = android.PathForModuleSrc(ctx, a.properties.Aars[0])
1026
Colin Cross1001a792019-03-21 22:21:39 -07001027 if Bool(a.properties.Jetifier) {
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001028 inputFile := a.aarPath
1029 a.aarPath = android.PathForModuleOut(ctx, "jetifier", aarName)
1030 TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile)
Nan Zhang4c819fb2018-08-27 18:31:46 -07001031 }
Colin Crossfabb6082018-02-20 17:22:23 -08001032
1033 extractedAARDir := android.PathForModuleOut(ctx, "aar")
Colin Cross205e9112020-08-06 13:20:17 -07001034 a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
Colin Cross10f7c4a2018-05-23 10:59:28 -07001035 a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
Colin Cross4eae06d2023-06-20 22:40:02 -07001036 aarRTxt := extractedAARDir.Join(ctx, "R.txt")
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001037 a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
Sam Delmerico95d70942023-08-02 18:00:35 -04001038 a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
1039 ctx.SetProvider(ProguardSpecInfoProvider, ProguardSpecInfo{
1040 ProguardFlagsFiles: android.NewDepSet[android.Path](
1041 android.POSTORDER,
1042 android.Paths{a.proguardFlags},
1043 nil,
1044 ),
1045 })
Colin Crossfabb6082018-02-20 17:22:23 -08001046
1047 ctx.Build(pctx, android.BuildParams{
1048 Rule: unzipAAR,
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001049 Input: a.aarPath,
Colin Cross4eae06d2023-06-20 22:40:02 -07001050 Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt},
Colin Crossfabb6082018-02-20 17:22:23 -08001051 Description: "unzip AAR",
1052 Args: map[string]string{
Colin Cross205e9112020-08-06 13:20:17 -07001053 "outDir": extractedAARDir.String(),
1054 "combinedClassesJar": a.classpathFile.String(),
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001055 "assetsPackage": a.assetsPackage.String(),
Colin Crossfabb6082018-02-20 17:22:23 -08001056 },
1057 })
1058
Colin Crossa0ba2f52019-06-22 12:59:27 -07001059 // Always set --pseudo-localize, it will be stripped out later for release
1060 // builds that don't want it.
1061 compileFlags := []string{"--pseudo-localize"}
Colin Crossfabb6082018-02-20 17:22:23 -08001062 compiledResDir := android.PathForModuleOut(ctx, "flat-res")
Colin Crossfabb6082018-02-20 17:22:23 -08001063 flata := compiledResDir.Join(ctx, "gen_res.flata")
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001064 aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
Colin Crossfabb6082018-02-20 17:22:23 -08001065
1066 a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
Colin Crossfabb6082018-02-20 17:22:23 -08001067 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
Colin Cross4eae06d2023-06-20 22:40:02 -07001068 a.rTxt = android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -07001069 a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
Colin Crossfabb6082018-02-20 17:22:23 -08001070
1071 var linkDeps android.Paths
1072
1073 linkFlags := []string{
1074 "--static-lib",
Colin Cross4eae06d2023-06-20 22:40:02 -07001075 "--merge-only",
Colin Crossfabb6082018-02-20 17:22:23 -08001076 "--auto-add-overlay",
1077 }
1078
Colin Cross10f7c4a2018-05-23 10:59:28 -07001079 linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
1080 linkDeps = append(linkDeps, a.manifest)
Colin Crossfabb6082018-02-20 17:22:23 -08001081
Colin Crossab8d1382023-07-14 17:23:41 +00001082 staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
Jiyong Parkf1691d22021-03-29 20:11:58 +09001083 aaptLibs(ctx, android.SdkContext(a), nil)
Colin Cross31656952018-05-24 16:11:20 -07001084
Colin Crossab8d1382023-07-14 17:23:41 +00001085 _ = staticRRODirsDepSet
1086 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
Colin Crossfabb6082018-02-20 17:22:23 -08001087
Colin Crossab8d1382023-07-14 17:23:41 +00001088 linkDeps = append(linkDeps, sharedLibs...)
Colin Cross4eae06d2023-06-20 22:40:02 -07001089 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -07001090 linkFlags = append(linkFlags, libFlags...)
Colin Crossfabb6082018-02-20 17:22:23 -08001091
Colin Cross4eae06d2023-06-20 22:40:02 -07001092 overlayRes := android.Paths{flata}
1093
1094 // Treat static library dependencies of static libraries as imports.
1095 transitiveStaticLibs := staticDeps.resPackages()
1096 linkDeps = append(linkDeps, transitiveStaticLibs...)
1097 for _, staticLib := range transitiveStaticLibs {
1098 linkFlags = append(linkFlags, "-I "+staticLib.String())
1099 }
Colin Crossfabb6082018-02-20 17:22:23 -08001100
Colin Crossab8d1382023-07-14 17:23:41 +00001101 transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
Colin Crossf3b7bad2023-08-02 15:49:00 -07001102 aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, a.rTxt,
Jaewoong Jung6431ca72020-01-15 14:15:10 -08001103 linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001104
Colin Cross4eae06d2023-06-20 22:40:02 -07001105 a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
1106 resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
1107
Colin Crossf3b7bad2023-08-02 15:49:00 -07001108 aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
1109
Colin Crossab8d1382023-07-14 17:23:41 +00001110 resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
1111 resourcesNodesDepSetBuilder.Direct(&resourcesNode{
1112 resPackage: a.exportPackage,
1113 manifest: a.manifest,
Colin Cross4eae06d2023-06-20 22:40:02 -07001114 rTxt: a.rTxt,
1115 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +00001116 assets: android.OptionalPathForPath(a.assetsPackage),
Colin Cross4eae06d2023-06-20 22:40:02 -07001117
1118 usedResourceProcessor: true,
Colin Crossab8d1382023-07-14 17:23:41 +00001119 })
1120 resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
1121 a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
1122
1123 manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
1124 // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
1125 // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
1126 // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
1127 // android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped
1128 // completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest
1129 //manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests)
1130 _ = staticManifestsDepSet
1131 a.manifestsDepSet = manifestDepSetBuilder.Build()
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001132
Colin Cross4eae06d2023-06-20 22:40:02 -07001133 a.transitiveAaptResourcePackages = staticDeps.resPackages()
1134
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001135 a.collectTransitiveHeaderJars(ctx)
Colin Crossdcf71b22021-02-01 13:59:03 -08001136 ctx.SetProvider(JavaInfoProvider, JavaInfo{
1137 HeaderJars: android.PathsIfNonNil(a.classpathFile),
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001138 TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
1139 TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
Colin Crossdcf71b22021-02-01 13:59:03 -08001140 ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
1141 ImplementationJars: android.PathsIfNonNil(a.classpathFile),
Joe Onorato6fe59eb2023-07-16 13:20:33 -07001142 // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
Colin Crossdcf71b22021-02-01 13:59:03 -08001143 })
Sam Delmerico82602492022-06-10 17:05:42 +00001144
1145 if proptools.Bool(a.properties.Extract_jni) {
1146 for _, t := range ctx.MultiTargets() {
1147 arch := t.Arch.Abi[0]
1148 path := android.PathForModuleOut(ctx, arch+"_jni.zip")
1149 a.jniPackages = append(a.jniPackages, path)
1150
1151 outDir := android.PathForModuleOut(ctx, "aarForJni")
1152 aarPath := android.PathForModuleSrc(ctx, a.properties.Aars[0])
1153 ctx.Build(pctx, android.BuildParams{
1154 Rule: extractJNI,
1155 Input: aarPath,
1156 Outputs: android.WritablePaths{path},
1157 Description: "extract JNI from AAR",
1158 Args: map[string]string{
1159 "outDir": outDir.String(),
1160 "archString": arch,
1161 },
1162 })
1163 }
1164
1165 ctx.SetProvider(JniPackageProvider, JniPackageInfo{
1166 JniPackages: a.jniPackages,
1167 })
1168 }
Colin Crossdcf71b22021-02-01 13:59:03 -08001169}
Colin Crossfabb6082018-02-20 17:22:23 -08001170
1171func (a *AARImport) HeaderJars() android.Paths {
1172 return android.Paths{a.classpathFile}
1173}
1174
Colin Cross331a1212018-08-15 20:40:52 -07001175func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
1176 return android.Paths{a.classpathFile}
1177}
1178
Ulyana Trafimovich5539e7b2020-06-04 14:08:17 +00001179func (a *AARImport) DexJarBuildPath() android.Path {
Colin Crossf24a22a2019-01-31 14:12:44 -08001180 return nil
1181}
1182
Ulya Trafimovich9f3052c2020-06-09 14:31:19 +01001183func (a *AARImport) DexJarInstallPath() android.Path {
1184 return nil
1185}
1186
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +01001187func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
Jiyong Park1be96912018-05-28 18:02:19 +09001188 return nil
1189}
1190
Jiyong Park45bf82e2020-12-15 22:29:02 +09001191var _ android.ApexModule = (*AARImport)(nil)
1192
1193// Implements android.ApexModule
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001194func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1195 return a.depIsInSameApex(ctx, dep)
1196}
1197
Jiyong Park45bf82e2020-12-15 22:29:02 +09001198// Implements android.ApexModule
Dan Albertc8060532020-07-22 22:32:17 -07001199func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
1200 sdkVersion android.ApiLevel) error {
Jooyung Han749dc692020-04-15 11:03:39 +09001201 return nil
1202}
1203
Sam Delmericoaf8bb702022-07-25 15:39:32 -04001204var _ android.PrebuiltInterface = (*AARImport)(nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001205
Colin Cross1b16b0e2019-02-12 14:41:32 -08001206// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
1207//
1208// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
1209// an android_app module.
Colin Crossfabb6082018-02-20 17:22:23 -08001210func AARImportFactory() android.Module {
1211 module := &AARImport{}
1212
1213 module.AddProperties(&module.properties)
1214
1215 android.InitPrebuiltModule(module, &module.properties.Aars)
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001216 android.InitApexModule(module)
Sam Delmerico82602492022-06-10 17:05:42 +00001217 InitJavaModuleMultiTargets(module, android.DeviceSupported)
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001218 android.InitBazelModule(module)
Colin Crossfabb6082018-02-20 17:22:23 -08001219 return module
1220}
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001221
1222type bazelAapt struct {
1223 Manifest bazel.Label
1224 Resource_files bazel.LabelListAttribute
1225}
1226
1227type bazelAndroidLibrary struct {
1228 *javaLibraryAttributes
1229 *bazelAapt
1230}
1231
1232type bazelAndroidLibraryImport struct {
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001233 Aar bazel.Label
1234 Deps bazel.LabelListAttribute
1235 Exports bazel.LabelListAttribute
1236 Sdk_version bazel.StringAttribute
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001237}
1238
1239func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt {
1240 manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
1241
1242 resourceFiles := bazel.LabelList{
1243 Includes: []bazel.Label{},
1244 }
1245 for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
1246 files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
1247 resourceFiles.Includes = append(resourceFiles.Includes, files...)
1248 }
1249 return &bazelAapt{
1250 android.BazelLabelForModuleSrcSingle(ctx, manifest),
1251 bazel.MakeLabelListAttribute(resourceFiles),
1252 }
1253}
1254
1255func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
1256 aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{})
1257 exportableStaticLibs := []string{}
1258 // TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel.
1259 for _, depName := range a.properties.Static_libs {
1260 if dep, ok := ctx.ModuleFromName(depName); ok {
1261 switch dep.(type) {
1262 case *AARImport, *Import:
1263 exportableStaticLibs = append(exportableStaticLibs, depName)
1264 }
1265 }
1266 }
1267 name := android.RemoveOptionalPrebuiltPrefix(a.Name())
1268 deps := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(append(a.properties.Static_libs, a.properties.Libs...))))
1269 exports := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(exportableStaticLibs))
1270
1271 ctx.CreateBazelTargetModule(
1272 bazel.BazelTargetModuleProperties{
1273 Rule_class: "aar_import",
Alixa381cd12023-05-10 14:49:38 +00001274 Bzl_load_location: "//build/bazel/rules/android:aar_import.bzl",
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001275 },
1276 android.CommonAttributes{Name: name},
1277 &bazelAndroidLibraryImport{
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001278 Aar: aars.Includes[0],
1279 Deps: bazel.MakeLabelListAttribute(deps),
1280 Exports: bazel.MakeLabelListAttribute(exports),
1281 Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version},
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001282 },
1283 )
1284
Alix14101de2023-01-06 03:42:07 +00001285 neverlink := true
1286 ctx.CreateBazelTargetModule(
Alix32540022023-03-16 21:06:13 +00001287 AndroidLibraryBazelTargetModuleProperties(),
Alix14101de2023-01-06 03:42:07 +00001288 android.CommonAttributes{Name: name + "-neverlink"},
1289 &bazelAndroidLibrary{
1290 javaLibraryAttributes: &javaLibraryAttributes{
1291 Neverlink: bazel.BoolAttribute{Value: &neverlink},
1292 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}),
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001293 javaCommonAttributes: &javaCommonAttributes{
1294 Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version},
1295 },
Alix14101de2023-01-06 03:42:07 +00001296 },
1297 },
1298 )
1299
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001300}
Alix32540022023-03-16 21:06:13 +00001301func AndroidLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties {
1302 return bazel.BazelTargetModuleProperties{
1303 Rule_class: "android_library",
Alixa381cd12023-05-10 14:49:38 +00001304 Bzl_load_location: "//build/bazel/rules/android:android_library.bzl",
Alix32540022023-03-16 21:06:13 +00001305 }
1306}
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001307
1308func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Liz Kammer7f375862023-08-04 16:37:42 -04001309 commonAttrs, bp2buildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
1310 if !supported {
1311 return
1312 }
1313
Alix8062f4d2022-11-14 21:38:07 +00001314 depLabels := bp2buildInfo.DepLabels
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001315
1316 deps := depLabels.Deps
1317 if !commonAttrs.Srcs.IsEmpty() {
1318 deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
1319 } else if !depLabels.Deps.IsEmpty() {
1320 ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
1321 }
Alix82fb94e2022-10-26 20:40:18 +00001322 name := a.Name()
Alix32540022023-03-16 21:06:13 +00001323 props := AndroidLibraryBazelTargetModuleProperties()
Alix82fb94e2022-10-26 20:40:18 +00001324
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001325 ctx.CreateBazelTargetModule(
Alix82fb94e2022-10-26 20:40:18 +00001326 props,
1327 android.CommonAttributes{Name: name},
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001328 &bazelAndroidLibrary{
1329 &javaLibraryAttributes{
1330 javaCommonAttributes: commonAttrs,
1331 Deps: deps,
1332 Exports: depLabels.StaticDeps,
1333 },
1334 a.convertAaptAttrsWithBp2Build(ctx),
1335 },
1336 )
Alix82fb94e2022-10-26 20:40:18 +00001337
1338 neverlink := true
1339 ctx.CreateBazelTargetModule(
1340 props,
1341 android.CommonAttributes{Name: name + "-neverlink"},
1342 &bazelAndroidLibrary{
1343 javaLibraryAttributes: &javaLibraryAttributes{
1344 Neverlink: bazel.BoolAttribute{Value: &neverlink},
1345 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}),
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001346 javaCommonAttributes: &javaCommonAttributes{
1347 Sdk_version: bazel.StringAttribute{Value: a.deviceProperties.Sdk_version},
1348 Java_version: bazel.StringAttribute{Value: a.properties.Java_version},
1349 },
Alix82fb94e2022-10-26 20:40:18 +00001350 },
1351 },
1352 )
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001353}