blob: 21e25e97aa4b6e98ac6b748882288709322ec148 [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 {
Jared Duke5979b302022-12-19 21:08:39 +000032 LibraryDependency
Colin Crossa97c5d32018-03-28 14:58:31 -070033 ExportPackage() android.Path
Colin Crossab8d1382023-07-14 17:23:41 +000034 ResourcesNodeDepSet() *android.DepSet[*resourcesNode]
35 RRODirsDepSet() *android.DepSet[rroDir]
36 ManifestsDepSet() *android.DepSet[android.Path]
Jaewoong Jungc779cd42020-10-06 18:56:10 -070037 SetRROEnforcedForDependent(enforce bool)
38 IsRROEnforced(ctx android.BaseModuleContext) bool
Colin Crossa97c5d32018-03-28 14:58:31 -070039}
40
41func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000042 RegisterAARBuildComponents(android.InitRegistrationContext)
43}
44
45func RegisterAARBuildComponents(ctx android.RegistrationContext) {
46 ctx.RegisterModuleType("android_library_import", AARImportFactory)
47 ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
Paul Duffin04ba70d2021-03-22 13:56:43 +000048 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
49 ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
50 })
Colin Crossa97c5d32018-03-28 14:58:31 -070051}
52
53//
54// AAR (android library)
55//
56
57type androidLibraryProperties struct {
58 BuildAAR bool `blueprint:"mutated"`
59}
60
61type aaptProperties struct {
62 // flags passed to aapt when creating the apk
63 Aaptflags []string
64
Dan Willemsen72be5902018-10-24 20:24:57 -070065 // include all resource configurations, not just the product-configured
66 // ones.
67 Aapt_include_all_resources *bool
68
Colin Crossa97c5d32018-03-28 14:58:31 -070069 // list of directories relative to the Blueprints file containing assets.
Colin Cross0ddae7f2019-02-07 15:30:01 -080070 // Defaults to ["assets"] if a directory called assets exists. Set to []
71 // to disable the default.
Colin Crossa97c5d32018-03-28 14:58:31 -070072 Asset_dirs []string
73
74 // list of directories relative to the Blueprints file containing
Colin Cross0ddae7f2019-02-07 15:30:01 -080075 // Android resources. Defaults to ["res"] if a directory called res exists.
76 // Set to [] to disable the default.
Colin Crossa97c5d32018-03-28 14:58:31 -070077 Resource_dirs []string
78
Colin Crossa592e3e2019-02-19 16:59:53 -080079 // list of zip files containing Android resources.
Colin Cross27b922f2019-03-04 22:35:41 -080080 Resource_zips []string `android:"path"`
Colin Crossa592e3e2019-02-19 16:59:53 -080081
Colin Crossa97c5d32018-03-28 14:58:31 -070082 // path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml".
Colin Cross27b922f2019-03-04 22:35:41 -080083 Manifest *string `android:"path"`
changho.shinb5432b72019-08-08 18:37:17 +090084
85 // paths to additional manifest files to merge with main manifest.
86 Additional_manifests []string `android:"path"`
Sasha Smundak541056c2019-10-28 15:50:06 -070087
88 // do not include AndroidManifest from dependent libraries
89 Dont_merge_manifests *bool
Jaewoong Jungc779cd42020-10-06 18:56:10 -070090
Colin Cross039d8df2023-06-20 22:40:02 -070091 // If use_resource_processor is set, use Bazel's resource processor instead of aapt2 to generate R.class files.
92 // The resource processor produces more optimal R.class files that only list resources in the package of the
93 // library that provided them, as opposed to aapt2 which produces R.java files for every package containing
94 // every resource. Using the resource processor can provide significant build time speedups, but requires
95 // fixing the module to use the correct package to reference each resource, and to avoid having any other
96 // libraries in the tree that use the same package name. Defaults to false, but will default to true in the
97 // future.
98 Use_resource_processor *bool
99
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700100 // true if RRO is enforced for any of the dependent modules
101 RROEnforcedForDependent bool `blueprint:"mutated"`
Colin Crossa97c5d32018-03-28 14:58:31 -0700102}
103
104type aapt struct {
Colin Cross039d8df2023-06-20 22:40:02 -0700105 aaptSrcJar android.Path
106 transitiveAaptRJars android.Paths
107 transitiveAaptResourcePackages android.Paths
108 exportPackage android.Path
109 manifestPath android.Path
110 proguardOptionsFile android.Path
111 rTxt android.Path
112 rJar android.Path
113 extraAaptPackagesFile android.Path
114 mergedManifestFile android.Path
115 noticeFile android.OptionalPath
116 assetPackage android.OptionalPath
117 isLibrary bool
118 defaultManifestVersion string
119 useEmbeddedNativeLibs bool
120 useEmbeddedDex bool
121 usesNonSdkApis bool
122 hasNoCode bool
123 LoggingParent string
124 resourceFiles android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700125
Colin Crosse560c4a2019-03-19 16:03:11 -0700126 splitNames []string
127 splits []split
128
Colin Crossa97c5d32018-03-28 14:58:31 -0700129 aaptProperties aaptProperties
Colin Crossab8d1382023-07-14 17:23:41 +0000130
131 resourcesNodesDepSet *android.DepSet[*resourcesNode]
132 rroDirsDepSet *android.DepSet[rroDir]
133 manifestsDepSet *android.DepSet[android.Path]
Colin Crossa97c5d32018-03-28 14:58:31 -0700134}
135
Colin Crosse560c4a2019-03-19 16:03:11 -0700136type split struct {
137 name string
138 suffix string
139 path android.Path
140}
141
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700142// Propagate RRO enforcement flag to static lib dependencies transitively.
143func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
144 m := ctx.Module()
145 if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) {
146 ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
147 if a, ok := d.(AndroidLibraryDependency); ok {
148 a.SetRROEnforcedForDependent(true)
149 }
150 })
151 }
152}
153
Colin Cross039d8df2023-06-20 22:40:02 -0700154func (a *aapt) useResourceProcessorBusyBox() bool {
155 return BoolDefault(a.aaptProperties.Use_resource_processor, false)
156}
157
Colin Crossa97c5d32018-03-28 14:58:31 -0700158func (a *aapt) ExportPackage() android.Path {
159 return a.exportPackage
160}
Colin Crossab8d1382023-07-14 17:23:41 +0000161func (a *aapt) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
162 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800163}
164
Colin Crossab8d1382023-07-14 17:23:41 +0000165func (a *aapt) RRODirsDepSet() *android.DepSet[rroDir] {
166 return a.rroDirsDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800167}
168
Colin Crossab8d1382023-07-14 17:23:41 +0000169func (a *aapt) ManifestsDepSet() *android.DepSet[android.Path] {
170 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800171}
172
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700173func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
174 a.aaptProperties.RROEnforcedForDependent = enforce
175}
176
177func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
178 // True if RRO is enforced for this module or...
179 return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
Jeongik Chacee5ba92021-02-19 12:11:51 +0900180 // if RRO is enforced for any of its dependents.
181 a.aaptProperties.RROEnforcedForDependent
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700182}
183
Jiyong Parkf1691d22021-03-29 20:11:58 +0900184func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkContext,
Colin Crossa0ba2f52019-06-22 12:59:27 -0700185 manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
186 resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700187
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800188 hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
189 hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
Colin Crossa97c5d32018-03-28 14:58:31 -0700190
Colin Crossa97c5d32018-03-28 14:58:31 -0700191 // Flags specified in Android.bp
192 linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
193
Eric Miao40eab202023-03-30 16:57:17 +0000194 linkFlags = append(linkFlags, "--enable-compact-entries")
Colin Crossa97c5d32018-03-28 14:58:31 -0700195
196 // Find implicit or explicit asset and resource dirs
197 assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
198 resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
Colin Cross8a497952019-03-05 22:25:09 -0800199 resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
Colin Crossa97c5d32018-03-28 14:58:31 -0700200
Colin Crossa97c5d32018-03-28 14:58:31 -0700201 // Glob directories into lists of paths
202 for _, dir := range resourceDirs {
203 resDirs = append(resDirs, globbedResourceDir{
204 dir: dir,
205 files: androidResourceGlob(ctx, dir),
206 })
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700207 resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
Colin Crossa97c5d32018-03-28 14:58:31 -0700208 overlayDirs = append(overlayDirs, resOverlayDirs...)
209 rroDirs = append(rroDirs, resRRODirs...)
210 }
211
Colin Crossc20dc852020-11-10 12:27:45 -0800212 var assetDeps android.Paths
213 for i, dir := range assetDirs {
214 // Add a dependency on every file in the asset directory. This ensures the aapt2
215 // rule will be rerun if one of the files in the asset directory is modified.
216 assetDeps = append(assetDeps, androidResourceGlob(ctx, dir)...)
217
218 // Add a dependency on a file that contains a list of all the files in the asset directory.
219 // This ensures the aapt2 rule will be run if a file is removed from the asset directory,
220 // or a file is added whose timestamp is older than the output of aapt2.
221 assetFileListFile := android.PathForModuleOut(ctx, "asset_dir_globs", strconv.Itoa(i)+".glob")
222 androidResourceGlobList(ctx, dir, assetFileListFile)
223 assetDeps = append(assetDeps, assetFileListFile)
Colin Crossa97c5d32018-03-28 14:58:31 -0700224 }
225
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700226 assetDirStrings := assetDirs.Strings()
227 if a.noticeFile.Valid() {
228 assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
Colin Crossc20dc852020-11-10 12:27:45 -0800229 assetDeps = append(assetDeps, a.noticeFile.Path())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700230 }
231
Colin Crossa97c5d32018-03-28 14:58:31 -0700232 linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
233 linkDeps = append(linkDeps, manifestPath)
234
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700235 linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
Colin Crossc20dc852020-11-10 12:27:45 -0800236 linkDeps = append(linkDeps, assetDeps...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700237
Spandan Das50885c02023-02-23 21:31:33 +0000238 // Returns the effective version for {min|target}_sdk_version
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000239 effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.ApiLevel) string {
Spandan Das50885c02023-02-23 21:31:33 +0000240 // If {min|target}_sdk_version is current, use sdk_version to determine the effective level
241 // This is necessary for vendor modules.
242 // The effective version does not _only_ depend on {min|target}_sdk_version(level),
243 // but also on the sdk_version (kind+level)
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000244 if minSdkVersion.IsCurrent() {
Spandan Das50885c02023-02-23 21:31:33 +0000245 ret, err := sdkVersion.EffectiveVersionString(ctx)
246 if err != nil {
247 ctx.ModuleErrorf("invalid sdk_version: %s", err)
248 }
249 return ret
250 }
251 ret, err := minSdkVersion.EffectiveVersionString(ctx)
252 if err != nil {
253 ctx.ModuleErrorf("invalid min_sdk_version: %s", err)
254 }
255 return ret
Jiyong Park6a927c42020-01-21 02:03:43 +0900256 }
Spandan Das50885c02023-02-23 21:31:33 +0000257 // SDK version flags
258 sdkVersion := sdkContext.SdkVersion(ctx)
259 minSdkVersion := effectiveVersionString(sdkVersion, sdkContext.MinSdkVersion(ctx))
Colin Crossa97c5d32018-03-28 14:58:31 -0700260
Colin Cross83bb3162018-06-25 15:48:06 -0700261 linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
Spandan Das6450b552023-02-23 19:27:07 +0000262 // Use minSdkVersion for target-sdk-version, even if `target_sdk_version` is set
263 // This behavior has been copied from Make.
Colin Cross83bb3162018-06-25 15:48:06 -0700264 linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
Colin Crossa97c5d32018-03-28 14:58:31 -0700265
Colin Crossa97c5d32018-03-28 14:58:31 -0700266 // Version code
267 if !hasVersionCode {
Dan Albert4f378d72020-07-23 17:32:15 -0700268 linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
Colin Crossa97c5d32018-03-28 14:58:31 -0700269 }
270
271 if !hasVersionName {
Colin Cross402d5e02018-04-25 14:54:06 -0700272 var versionName string
273 if ctx.ModuleName() == "framework-res" {
274 // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
275 // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
Colin Crossbfd347d2018-05-09 11:11:35 -0700276 // if it contains the build number. Use the PlatformVersionName instead.
277 versionName = ctx.Config().PlatformVersionName()
Colin Cross402d5e02018-04-25 14:54:06 -0700278 } else {
279 versionName = ctx.Config().AppsDefaultVersionName()
280 }
Colin Cross0b9f31f2019-02-28 11:00:01 -0800281 versionName = proptools.NinjaEscape(versionName)
Colin Crossa97c5d32018-03-28 14:58:31 -0700282 linkFlags = append(linkFlags, "--version-name ", versionName)
283 }
284
Colin Crossa0ba2f52019-06-22 12:59:27 -0700285 linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
286
287 // Always set --pseudo-localize, it will be stripped out later for release
288 // builds that don't want it.
289 compileFlags = append(compileFlags, "--pseudo-localize")
290
291 return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
Colin Crossa97c5d32018-03-28 14:58:31 -0700292}
293
Paul Duffin250e6192019-06-07 10:44:37 +0100294func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
Colin Cross42308aa2018-11-14 21:44:17 -0800295 if sdkDep.frameworkResModule != "" {
296 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossa97c5d32018-03-28 14:58:31 -0700297 }
298}
299
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800300var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
301 blueprint.RuleParams{
302 Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
303 CommandDeps: []string{"${config.Zip2ZipCmd}"},
304 })
305
Jiyong Parkf1691d22021-03-29 20:11:58 +0900306func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
Paul Duffin06530572022-02-03 17:54:15 +0000307 classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000308 enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {
Colin Cross5446e882019-05-22 10:46:27 -0700309
Colin Crossab8d1382023-07-14 17:23:41 +0000310 staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedDeps, libFlags :=
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100311 aaptLibs(ctx, sdkContext, classLoaderContexts)
Ulya Trafimovich31e444e2020-08-14 17:32:16 +0100312
Paul Duffin06530572022-02-03 17:54:15 +0000313 // Exclude any libraries from the supplied list.
314 classLoaderContexts = classLoaderContexts.ExcludeLibs(excludedLibs)
315
Colin Cross31656952018-05-24 16:11:20 -0700316 // App manifest file
317 manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
318 manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
319
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000320 manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000321 SdkContext: sdkContext,
322 ClassLoaderContexts: classLoaderContexts,
323 IsLibrary: a.isLibrary,
324 DefaultManifestVersion: a.defaultManifestVersion,
325 UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
326 UsesNonSdkApis: a.usesNonSdkApis,
327 UseEmbeddedDex: a.useEmbeddedDex,
328 HasNoCode: a.hasNoCode,
329 LoggingParent: a.LoggingParent,
330 EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000331 })
Colin Cross90c25c62019-04-19 16:22:57 -0700332
Colin Crossab8d1382023-07-14 17:23:41 +0000333 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
334
Luca Stefanifd898822019-09-10 22:13:31 +0200335 // Add additional manifest files to transitive manifests.
336 additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
Colin Crossab8d1382023-07-14 17:23:41 +0000337 transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
338 // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
339 // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
340 // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
341 // android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of
342 // staticResourcesNodesDepSet.manifests()
343 transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
Colin Cross90c25c62019-04-19 16:22:57 -0700344
Colin Crossab8d1382023-07-14 17:23:41 +0000345 if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
346 a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], transitiveManifestPaths[1:], a.isLibrary)
Colin Cross90c25c62019-04-19 16:22:57 -0700347 if !a.isLibrary {
348 // Only use the merged manifest for applications. For libraries, the transitive closure of manifests
349 // will be propagated to the final application and merged there. The merged manifest for libraries is
350 // only passed to Make, which can't handle transitive dependencies.
351 manifestPath = a.mergedManifestFile
352 }
353 } else {
354 a.mergedManifestFile = manifestPath
355 }
Colin Cross31656952018-05-24 16:11:20 -0700356
Colin Crossa0ba2f52019-06-22 12:59:27 -0700357 compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath)
Colin Cross31656952018-05-24 16:11:20 -0700358
359 linkFlags = append(linkFlags, libFlags...)
Colin Crossab8d1382023-07-14 17:23:41 +0000360 linkDeps = append(linkDeps, sharedDeps...)
361 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700362 linkFlags = append(linkFlags, extraLinkFlags...)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700363 if a.isLibrary {
364 linkFlags = append(linkFlags, "--static-lib")
365 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700366
Colin Cross039d8df2023-06-20 22:40:02 -0700367 if a.isLibrary && a.useResourceProcessorBusyBox() {
368 // When building an android_library using ResourceProcessorBusyBox the resources are merged into
369 // package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
370 // contains resources from this library.
371 linkFlags = append(linkFlags, "--merge-only")
372 } else {
373 // When building and app or when building an android_library without ResourceProcessorBusyBox
374 // --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
375 // is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
376 // sort resources into the right packages in R.class.
377 linkFlags = append(linkFlags, "--no-static-lib-packages")
378 }
379
Colin Crossa97c5d32018-03-28 14:58:31 -0700380 packageRes := android.PathForModuleOut(ctx, "package-res.apk")
Jiyong Parkb7c639e2019-08-19 14:56:02 +0900381 // the subdir "android" is required to be filtered by package names
382 srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
Colin Crossa97c5d32018-03-28 14:58:31 -0700383 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
384 rTxt := android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -0700385 // This file isn't used by Soong, but is generated for exporting
386 extraPackages := android.PathForModuleOut(ctx, "extra_packages")
Colin Cross039d8df2023-06-20 22:40:02 -0700387 var transitiveRJars android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700388
Colin Cross4aaa84a2018-08-21 15:14:37 -0700389 var compiledResDirs []android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700390 for _, dir := range resDirs {
Colin Cross014489c2020-06-02 20:09:13 -0700391 a.resourceFiles = append(a.resourceFiles, dir.files...)
Colin Crossa0ba2f52019-06-22 12:59:27 -0700392 compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths())
Colin Crossa97c5d32018-03-28 14:58:31 -0700393 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700394
Colin Crossa592e3e2019-02-19 16:59:53 -0800395 for i, zip := range resZips {
396 flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
Colin Crossa0ba2f52019-06-22 12:59:27 -0700397 aapt2CompileZip(ctx, flata, zip, "", compileFlags)
Colin Crossa592e3e2019-02-19 16:59:53 -0800398 compiledResDirs = append(compiledResDirs, android.Paths{flata})
399 }
400
Colin Cross4aaa84a2018-08-21 15:14:37 -0700401 var compiledRes, compiledOverlay android.Paths
402
Colin Crossab8d1382023-07-14 17:23:41 +0000403 // AAPT2 overlays are in lowest to highest priority order, reverse the topological order
404 // of transitiveStaticLibs.
405 transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
406
Colin Cross039d8df2023-06-20 22:40:02 -0700407 if a.isLibrary && a.useResourceProcessorBusyBox() {
408 // When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
409 // as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
410 // instead modules depending on this module will reference package-res.apk from all transitive static
411 // dependencies.
412 for _, staticDep := range staticDeps {
413 linkDeps = append(linkDeps, staticDep.resPackage)
414 linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
415 if staticDep.usedResourceProcessor {
416 transitiveRJars = append(transitiveRJars, staticDep.rJar)
417 }
418 }
419 } else {
420 // When building an app or building a library without ResourceProcessorBusyBox enabled all static
421 // dependencies are compiled into this module's package-res.apk as overlays.
422 compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
423 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700424
Colin Crossbec85302019-02-13 13:15:46 -0800425 if len(transitiveStaticLibs) > 0 {
Colin Cross4aaa84a2018-08-21 15:14:37 -0700426 // If we are using static android libraries, every source file becomes an overlay.
427 // This is to emulate old AAPT behavior which simulated library support.
428 for _, compiledResDir := range compiledResDirs {
429 compiledOverlay = append(compiledOverlay, compiledResDir...)
430 }
Colin Crossbec85302019-02-13 13:15:46 -0800431 } else if a.isLibrary {
432 // Otherwise, for a static library we treat all the resources equally with no overlay.
433 for _, compiledResDir := range compiledResDirs {
434 compiledRes = append(compiledRes, compiledResDir...)
435 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700436 } else if len(compiledResDirs) > 0 {
437 // Without static libraries, the first directory is our directory, which can then be
438 // overlaid by the rest.
439 compiledRes = append(compiledRes, compiledResDirs[0]...)
440 for _, compiledResDir := range compiledResDirs[1:] {
441 compiledOverlay = append(compiledOverlay, compiledResDir...)
442 }
443 }
444
Colin Crossa97c5d32018-03-28 14:58:31 -0700445 for _, dir := range overlayDirs {
Colin Crossa0ba2f52019-06-22 12:59:27 -0700446 compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700447 }
448
Colin Crosse560c4a2019-03-19 16:03:11 -0700449 var splitPackages android.WritablePaths
450 var splits []split
451
452 for _, s := range a.splitNames {
453 suffix := strings.Replace(s, ",", "_", -1)
454 path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
455 linkFlags = append(linkFlags, "--split", path.String()+":"+s)
456 splitPackages = append(splitPackages, path)
457 splits = append(splits, split{
458 name: s,
459 suffix: suffix,
460 path: path,
461 })
462 }
463
Colin Crossab8d1382023-07-14 17:23:41 +0000464 // No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
465 // provided to the final app aapt2Link step.
466 var transitiveAssets android.Paths
467 if !a.isLibrary {
468 transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
469 }
Colin Cross66f78822018-05-02 12:58:28 -0700470 aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
Colin Crossab8d1382023-07-14 17:23:41 +0000471 linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages)
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800472
473 // 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 Cross039d8df2023-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)
489 transitiveRJars = append(transitiveRJars, rJar)
490 a.rJar = rJar
491 }
492
Colin Crossa97c5d32018-03-28 14:58:31 -0700493 a.aaptSrcJar = srcJar
Colin Cross039d8df2023-06-20 22:40:02 -0700494 a.transitiveAaptRJars = transitiveRJars
495 a.transitiveAaptResourcePackages = staticDeps.resPackages()
Colin Crossa97c5d32018-03-28 14:58:31 -0700496 a.exportPackage = packageRes
497 a.manifestPath = manifestPath
498 a.proguardOptionsFile = proguardOptionsFile
Colin Cross66f78822018-05-02 12:58:28 -0700499 a.extraAaptPackagesFile = extraPackages
Colin Crossa97c5d32018-03-28 14:58:31 -0700500 a.rTxt = rTxt
Colin Crosse560c4a2019-03-19 16:03:11 -0700501 a.splits = splits
Colin Crossab8d1382023-07-14 17:23:41 +0000502 a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL).
503 Direct(&resourcesNode{
504 resPackage: a.exportPackage,
505 manifest: a.manifestPath,
506 additionalManifests: additionalManifests,
Colin Cross039d8df2023-06-20 22:40:02 -0700507 rTxt: a.rTxt,
508 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +0000509 assets: a.assetPackage,
Colin Cross039d8df2023-06-20 22:40:02 -0700510
511 usedResourceProcessor: a.useResourceProcessorBusyBox(),
Colin Crossab8d1382023-07-14 17:23:41 +0000512 }).
513 Transitive(staticResourcesNodesDepSet).Build()
514 a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
515 Direct(rroDirs...).
516 Transitive(staticRRODirsDepSet).Build()
517 a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
518 Direct(a.manifestPath).
519 DirectSlice(additionalManifests).
520 Transitive(staticManifestsDepSet).Build()
521}
522
Colin Cross039d8df2023-06-20 22:40:02 -0700523var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
524 blueprint.RuleParams{
525 Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
526 "com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
527 "if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
528 CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
529 Rspfile: "${out}.args",
530 RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
531 Restat: true,
532 }, "rTxt", "manifest", "args")
533
534// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
535// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
536// supports producing classes for static dependencies that only include resources from that dependency.
537func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
538 rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) {
539
540 var args []string
541 var deps android.Paths
542
543 if !isLibrary {
544 // When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
545 // to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
546 // package.
547 args, deps = transitiveDeps.resourceProcessorDeps()
548 } else {
549 // When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
550 // library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
551 // inlined into the library before the final IDs are assigned during app compilation.
552 args = append(args, "--finalFields=false")
553 }
554
555 deps = append(deps, rTxt, manifest)
556
557 ctx.Build(pctx, android.BuildParams{
558 Rule: resourceProcessorBusyBox,
559 Output: rJar,
560 Implicits: deps,
561 Description: "ResourceProcessorBusyBox",
562 Args: map[string]string{
563 "rTxt": rTxt.String(),
564 "manifest": manifest.String(),
565 "args": strings.Join(args, " "),
566 },
567 })
568}
569
Colin Crossab8d1382023-07-14 17:23:41 +0000570type resourcesNode struct {
571 resPackage android.Path
572 manifest android.Path
573 additionalManifests android.Paths
Colin Cross039d8df2023-06-20 22:40:02 -0700574 rTxt android.Path
575 rJar android.Path
Colin Crossab8d1382023-07-14 17:23:41 +0000576 assets android.OptionalPath
Colin Cross039d8df2023-06-20 22:40:02 -0700577
578 usedResourceProcessor bool
Colin Crossab8d1382023-07-14 17:23:41 +0000579}
580
581type transitiveAarDeps []*resourcesNode
582
583func (t transitiveAarDeps) resPackages() android.Paths {
Colin Cross039d8df2023-06-20 22:40:02 -0700584 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000585 for _, dep := range t {
586 paths = append(paths, dep.resPackage)
587 }
Colin Cross039d8df2023-06-20 22:40:02 -0700588 return paths
Colin Crossab8d1382023-07-14 17:23:41 +0000589}
590
591func (t transitiveAarDeps) manifests() android.Paths {
Colin Cross039d8df2023-06-20 22:40:02 -0700592 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000593 for _, dep := range t {
594 paths = append(paths, dep.manifest)
595 paths = append(paths, dep.additionalManifests...)
596 }
Colin Cross039d8df2023-06-20 22:40:02 -0700597 return paths
598}
599
600func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
601 for _, dep := range t {
602 args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
603 deps = append(deps, dep.rTxt, dep.manifest)
604 }
605 return args, deps
Colin Crossab8d1382023-07-14 17:23:41 +0000606}
607
608func (t transitiveAarDeps) assets() android.Paths {
Colin Cross039d8df2023-06-20 22:40:02 -0700609 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000610 for _, dep := range t {
611 if dep.assets.Valid() {
612 paths = append(paths, dep.assets.Path())
613 }
614 }
615 return paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700616}
617
618// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
Jiyong Parkf1691d22021-03-29 20:11:58 +0900619func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
Colin Crossab8d1382023-07-14 17:23:41 +0000620 staticResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
621 staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700622
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100623 if classLoaderContexts == nil {
Ulya Trafimovich18554242020-11-03 15:55:11 +0000624 // Not all callers need to compute class loader context, those who don't just pass nil.
625 // Create a temporary class loader context here (it will be computed, but not used).
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100626 classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000627 }
628
Colin Cross83bb3162018-06-25 15:48:06 -0700629 sdkDep := decodeSdkDep(ctx, sdkContext)
Colin Crossa97c5d32018-03-28 14:58:31 -0700630 if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700631 sharedLibs = append(sharedLibs, sdkDep.jars...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700632 }
633
Colin Crossab8d1382023-07-14 17:23:41 +0000634 var resourcesNodeDepSets []*android.DepSet[*resourcesNode]
635 rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL)
636 manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL)
637
Colin Crossa97c5d32018-03-28 14:58:31 -0700638 ctx.VisitDirectDeps(func(module android.Module) {
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000639 depTag := ctx.OtherModuleDependencyTag(module)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000640
Colin Crossa97c5d32018-03-28 14:58:31 -0700641 var exportPackage android.Path
Colin Cross66f78822018-05-02 12:58:28 -0700642 aarDep, _ := module.(AndroidLibraryDependency)
643 if aarDep != nil {
Colin Crossa97c5d32018-03-28 14:58:31 -0700644 exportPackage = aarDep.ExportPackage()
645 }
646
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000647 switch depTag {
Colin Cross4b964c02018-10-15 16:18:06 -0700648 case instrumentationForTag:
649 // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
Liz Kammeref28a4c2022-09-23 16:50:56 -0400650 case sdkLibTag, libTag:
Colin Cross5446e882019-05-22 10:46:27 -0700651 if exportPackage != nil {
652 sharedLibs = append(sharedLibs, exportPackage)
653 }
Colin Cross5446e882019-05-22 10:46:27 -0700654 case frameworkResTag:
Colin Crossa97c5d32018-03-28 14:58:31 -0700655 if exportPackage != nil {
656 sharedLibs = append(sharedLibs, exportPackage)
657 }
658 case staticLibTag:
659 if exportPackage != nil {
Colin Crossab8d1382023-07-14 17:23:41 +0000660 resourcesNodeDepSets = append(resourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
661 rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
662 manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
Colin Crossa97c5d32018-03-28 14:58:31 -0700663 }
664 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000665
Ulya Trafimovich88bb6f62020-12-16 16:16:11 +0000666 addCLCFromDep(ctx, module, classLoaderContexts)
Colin Crossa97c5d32018-03-28 14:58:31 -0700667 })
668
Colin Crossab8d1382023-07-14 17:23:41 +0000669 // AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
670 // Reverse the dependency order now going into the depset so that it comes out in order after the second
671 // reverse later.
672 // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
673 // dependencies) the highest priority dependency is listed first, but for resources the highest priority
674 // dependency has to be listed last.
675 staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
676 android.ReverseSliceInPlace(resourcesNodeDepSets))
Colin Crossa97c5d32018-03-28 14:58:31 -0700677
Colin Crossab8d1382023-07-14 17:23:41 +0000678 staticRRODirs = rroDirsDepSetBuilder.Build()
679 staticManifests = manifestsDepSetBuilder.Build()
680
681 if len(staticResourcesNodes.ToList()) > 0 {
Colin Crossa97c5d32018-03-28 14:58:31 -0700682 flags = append(flags, "--auto-add-overlay")
683 }
684
685 for _, sharedLib := range sharedLibs {
686 flags = append(flags, "-I "+sharedLib.String())
687 }
688
Colin Crossab8d1382023-07-14 17:23:41 +0000689 return staticResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
Colin Crossa97c5d32018-03-28 14:58:31 -0700690}
691
692type AndroidLibrary struct {
693 Library
694 aapt
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500695 android.BazelModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700696
697 androidLibraryProperties androidLibraryProperties
698
699 aarFile android.WritablePath
Colin Cross89c31582018-04-30 15:55:11 -0700700}
701
Saeid Farivar Asanjan1fca3012021-09-14 18:40:19 +0000702var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
703
704// For OutputFileProducer interface
705func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
706 switch tag {
707 case ".aar":
708 return []android.Path{a.aarFile}, nil
709 default:
710 return a.Library.OutputFiles(tag)
711 }
712}
713
Colin Crossa97c5d32018-03-28 14:58:31 -0700714var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
715
716func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
717 a.Module.deps(ctx)
Jiyong Parkf1691d22021-03-29 20:11:58 +0900718 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Paul Duffin250e6192019-06-07 10:44:37 +0100719 if sdkDep.hasFrameworkLibs() {
720 a.aapt.deps(ctx, sdkDep)
Colin Crossa97c5d32018-03-28 14:58:31 -0700721 }
Colin Cross4a80a152022-12-21 21:51:52 -0800722 a.usesLibrary.deps(ctx, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700723}
724
725func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosse4246ab2019-02-05 21:55:21 -0800726 a.aapt.isLibrary = true
Ulya Trafimovich42c7f0d2021-08-17 16:20:29 +0100727 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000728 a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700729
Colin Cross56a83212020-09-15 18:30:11 -0700730 a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
731
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000732 a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
733
Colin Cross039d8df2023-06-20 22:40:02 -0700734 ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
735 ctx.CheckbuildFile(a.aapt.exportPackage)
736 ctx.CheckbuildFile(a.aapt.aaptSrcJar)
737 if a.useResourceProcessorBusyBox() {
738 ctx.CheckbuildFile(a.aapt.rJar)
739 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700740
741 // apps manifests are handled by aapt, don't let Module see them
742 a.properties.Manifest = nil
743
Colin Cross014489c2020-06-02 20:09:13 -0700744 a.linter.mergedManifest = a.aapt.mergedManifestFile
745 a.linter.manifest = a.aapt.manifestPath
746 a.linter.resources = a.aapt.resourceFiles
747
Colin Crossa97c5d32018-03-28 14:58:31 -0700748 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
749 a.proguardOptionsFile)
750
Colin Cross039d8df2023-06-20 22:40:02 -0700751 var extraSrcJars android.Paths
752 var extraCombinedJars android.Paths
753 var extraClasspathJars android.Paths
754 if a.useResourceProcessorBusyBox() {
755 // When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
756 // library and each of the transitive static android_library dependencies has already created an
757 // R.class file for the appropriate package. Add all of those R.class files to the classpath.
758 extraClasspathJars = a.transitiveAaptRJars
759 } else {
760 // When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
761 // R.java files for the library's package and the packages from all transitive static android_library
762 // dependencies. Compile the srcjar alongside the rest of the sources.
763 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
764 }
765
766 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
Colin Crossa97c5d32018-03-28 14:58:31 -0700767
Colin Crossf57c5782019-01-25 13:20:38 -0800768 a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
Colin Crossa97c5d32018-03-28 14:58:31 -0700769 var res android.Paths
770 if a.androidLibraryProperties.BuildAAR {
771 BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
772 ctx.CheckbuildFile(a.aarFile)
773 }
Colin Cross89c31582018-04-30 15:55:11 -0700774
Cole Faust9a631312020-10-22 21:05:24 +0000775 a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles,
776 android.PathsForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files)...)
Colin Crossab8d1382023-07-14 17:23:41 +0000777
Colin Cross89c31582018-04-30 15:55:11 -0700778 ctx.VisitDirectDeps(func(m android.Module) {
Jared Duke5979b302022-12-19 21:08:39 +0000779 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
780 if lib, ok := m.(LibraryDependency); ok {
781 a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
782 }
Colin Cross89c31582018-04-30 15:55:11 -0700783 }
784 })
Colin Cross89c31582018-04-30 15:55:11 -0700785 a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles)
Sam Delmerico82602492022-06-10 17:05:42 +0000786
787 prebuiltJniPackages := android.Paths{}
788 ctx.VisitDirectDeps(func(module android.Module) {
789 if info, ok := ctx.OtherModuleProvider(module, JniPackageProvider).(JniPackageInfo); ok {
790 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
791 }
792 })
793 if len(prebuiltJniPackages) > 0 {
794 ctx.SetProvider(JniPackageProvider, JniPackageInfo{
795 JniPackages: prebuiltJniPackages,
796 })
797 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700798}
799
Colin Cross1b16b0e2019-02-12 14:41:32 -0800800// android_library builds and links sources into a `.jar` file for the device along with Android resources.
801//
802// An android_library has a single variant that produces a `.jar` file containing `.class` files that were
Sam Delmerico82602492022-06-10 17:05:42 +0000803// compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
Colin Cross1b16b0e2019-02-12 14:41:32 -0800804// with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
805// an android_app module.
Colin Crossa97c5d32018-03-28 14:58:31 -0700806func AndroidLibraryFactory() android.Module {
807 module := &AndroidLibrary{}
808
Colin Crossce6734e2020-06-15 16:09:53 -0700809 module.Module.addHostAndDeviceProperties()
Colin Crossa97c5d32018-03-28 14:58:31 -0700810 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -0700811 &module.aaptProperties,
812 &module.androidLibraryProperties)
813
814 module.androidLibraryProperties.BuildAAR = true
Colin Cross014489c2020-06-02 20:09:13 -0700815 module.Module.linter.library = true
Colin Crossa97c5d32018-03-28 14:58:31 -0700816
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900817 android.InitApexModule(module)
Colin Cross48de9a42018-10-02 13:53:33 -0700818 InitJavaModule(module, android.DeviceSupported)
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500819 android.InitBazelModule(module)
Colin Crossa97c5d32018-03-28 14:58:31 -0700820 return module
821}
822
Colin Crossfabb6082018-02-20 17:22:23 -0800823//
824// AAR (android library) prebuilts
825//
Colin Crossfabb6082018-02-20 17:22:23 -0800826
Vinh Trance0781f2022-04-13 01:30:44 +0000827// Properties for android_library_import
Colin Crossfabb6082018-02-20 17:22:23 -0800828type AARImportProperties struct {
Vinh Trance0781f2022-04-13 01:30:44 +0000829 // ARR (android library prebuilt) filepath. Exactly one ARR is required.
Colin Cross27b922f2019-03-04 22:35:41 -0800830 Aars []string `android:"path"`
Vinh Trance0781f2022-04-13 01:30:44 +0000831 // If not blank, set to the version of the sdk to compile against.
832 // Defaults to private.
833 // Values are of one of the following forms:
834 // 1) numerical API level, "current", "none", or "core_platform"
835 // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
836 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
837 // If the SDK kind is empty, it will be set to public
838 Sdk_version *string
839 // If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
840 // Defaults to sdk_version if not set. See sdk_version for possible values.
Colin Cross479884c2018-07-10 13:39:30 -0700841 Min_sdk_version *string
Vinh Trance0781f2022-04-13 01:30:44 +0000842 // List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
Colin Crossa97c5d32018-03-28 14:58:31 -0700843 Static_libs []string
Vinh Trance0781f2022-04-13 01:30:44 +0000844 // List of java libraries that the included ARR (android library prebuilts) has dependencies to.
845 Libs []string
846 // If set to true, run Jetifier against .aar file. Defaults to false.
Colin Cross1001a792019-03-21 22:21:39 -0700847 Jetifier *bool
Sam Delmerico82602492022-06-10 17:05:42 +0000848 // If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and
849 // will be passed transitively through android_libraries to an android_app.
850 //TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
851 Extract_jni *bool
Colin Crossfabb6082018-02-20 17:22:23 -0800852}
853
854type AARImport struct {
855 android.ModuleBase
Colin Cross48de9a42018-10-02 13:53:33 -0700856 android.DefaultableModuleBase
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900857 android.ApexModuleBase
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500858 android.BazelModuleBase
Colin Crossfabb6082018-02-20 17:22:23 -0800859 prebuilt android.Prebuilt
860
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900861 // Functionality common to Module and Import.
862 embeddableInModuleAndImport
863
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500864 providesTransitiveHeaderJars
865
Colin Crossfabb6082018-02-20 17:22:23 -0800866 properties AARImportProperties
867
Colin Cross039d8df2023-06-20 22:40:02 -0700868 classpathFile android.WritablePath
869 proguardFlags android.WritablePath
870 exportPackage android.WritablePath
871 transitiveAaptResourcePackages android.Paths
872 extraAaptPackagesFile android.WritablePath
873 manifest android.WritablePath
874 assetsPackage android.WritablePath
875 rTxt android.WritablePath
876 rJar android.WritablePath
Colin Cross66f78822018-05-02 12:58:28 -0700877
Colin Crossab8d1382023-07-14 17:23:41 +0000878 resourcesNodesDepSet *android.DepSet[*resourcesNode]
879 manifestsDepSet *android.DepSet[android.Path]
Colin Cross56a83212020-09-15 18:30:11 -0700880
881 hideApexVariantFromMake bool
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +0000882
Sam Delmerico82602492022-06-10 17:05:42 +0000883 aarPath android.Path
884 jniPackages android.Paths
Jiyong Park92315372021-04-02 08:45:46 +0900885
886 sdkVersion android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000887 minSdkVersion android.ApiLevel
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +0000888}
889
890var _ android.OutputFileProducer = (*AARImport)(nil)
891
892// For OutputFileProducer interface
893func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
894 switch tag {
895 case ".aar":
896 return []android.Path{a.aarPath}, nil
897 case "":
898 return []android.Path{a.classpathFile}, nil
899 default:
900 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
901 }
Colin Crossfabb6082018-02-20 17:22:23 -0800902}
903
Jiyong Park92315372021-04-02 08:45:46 +0900904func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
905 return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700906}
907
Jiyong Parkf1691d22021-03-29 20:11:58 +0900908func (a *AARImport) SystemModules() string {
Paul Duffine25c6442019-10-11 13:50:28 +0100909 return ""
910}
911
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000912func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Colin Cross479884c2018-07-10 13:39:30 -0700913 if a.properties.Min_sdk_version != nil {
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000914 return android.ApiLevelFrom(ctx, *a.properties.Min_sdk_version)
Colin Cross479884c2018-07-10 13:39:30 -0700915 }
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000916 return a.SdkVersion(ctx).ApiLevel
Colin Cross83bb3162018-06-25 15:48:06 -0700917}
918
Spandan Dasa26eda72023-03-02 00:56:06 +0000919func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
920 return android.SdkSpecFrom(ctx, "").ApiLevel
William Loh5a082f92022-05-17 20:21:50 +0000921}
922
Spandan Dasca70fc42023-03-01 23:38:49 +0000923func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
924 return a.SdkVersion(ctx).ApiLevel
Dan Willemsen419290a2018-10-31 15:28:47 -0700925}
926
Colin Cross1e743852019-10-28 11:37:20 -0700927func (a *AARImport) javaVersion() string {
928 return ""
929}
930
Colin Crossa97c5d32018-03-28 14:58:31 -0700931var _ AndroidLibraryDependency = (*AARImport)(nil)
932
933func (a *AARImport) ExportPackage() android.Path {
934 return a.exportPackage
935}
Colin Cross89c31582018-04-30 15:55:11 -0700936func (a *AARImport) ExportedProguardFlagFiles() android.Paths {
937 return android.Paths{a.proguardFlags}
938}
939
Colin Crossab8d1382023-07-14 17:23:41 +0000940func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
941 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800942}
943
Colin Crossab8d1382023-07-14 17:23:41 +0000944func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] {
945 return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil)
Colin Cross66f78822018-05-02 12:58:28 -0700946}
947
Colin Crossab8d1382023-07-14 17:23:41 +0000948func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] {
949 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800950}
951
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700952// RRO enforcement is not available on aar_import since its RRO dirs are not
953// exported.
954func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
955}
956
957// RRO enforcement is not available on aar_import since its RRO dirs are not
958// exported.
959func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
960 return false
961}
962
Colin Crossfabb6082018-02-20 17:22:23 -0800963func (a *AARImport) Prebuilt() *android.Prebuilt {
964 return &a.prebuilt
965}
966
967func (a *AARImport) Name() string {
968 return a.prebuilt.Name(a.ModuleBase.Name())
969}
970
Jiyong Park618922e2020-01-08 13:35:43 +0900971func (a *AARImport) JacocoReportClassesFile() android.Path {
972 return nil
973}
974
Colin Crossfabb6082018-02-20 17:22:23 -0800975func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
Jeongik Cha816a23a2020-07-08 01:09:23 +0900976 if !ctx.Config().AlwaysUsePrebuiltSdks() {
Jiyong Parkf1691d22021-03-29 20:11:58 +0900977 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Colin Crossa97c5d32018-03-28 14:58:31 -0700978 if sdkDep.useModule && sdkDep.frameworkResModule != "" {
Colin Cross42d48b72018-08-29 14:10:52 -0700979 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossfabb6082018-02-20 17:22:23 -0800980 }
981 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700982
Colin Cross42d48b72018-08-29 14:10:52 -0700983 ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
984 ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
Colin Crossfabb6082018-02-20 17:22:23 -0800985}
986
Sam Delmerico82602492022-06-10 17:05:42 +0000987type JniPackageInfo struct {
988 // List of zip files containing JNI libraries
989 // Zip files should have directory structure jni/<arch>/*.so
990 JniPackages android.Paths
991}
992
993var JniPackageProvider = blueprint.NewProvider(JniPackageInfo{})
994
995// Unzip an AAR and extract the JNI libs for $archString.
996var extractJNI = pctx.AndroidStaticRule("extractJNI",
997 blueprint.RuleParams{
998 Command: `rm -rf $out $outDir && touch $out && ` +
999 `unzip -qoDD -d $outDir $in "jni/${archString}/*" && ` +
1000 `jni_files=$$(find $outDir/jni -type f) && ` +
1001 // print error message if there are no JNI libs for this arch
1002 `[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` +
1003 `${config.SoongZipCmd} -o $out -P 'lib/${archString}' ` +
1004 `-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`,
1005 CommandDeps: []string{"${config.SoongZipCmd}"},
1006 },
1007 "outDir", "archString")
1008
Colin Crossfabb6082018-02-20 17:22:23 -08001009// 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 -07001010// 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 -08001011var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
1012 blueprint.RuleParams{
Dan Willemsen304cfec2019-05-28 14:49:06 -07001013 Command: `rm -rf $outDir && mkdir -p $outDir && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001014 `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001015 `${config.Zip2ZipCmd} -i $in -o $assetsPackage 'assets/**/*' && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001016 `${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001017 CommandDeps: []string{"${config.MergeZipsCmd}", "${config.Zip2ZipCmd}"},
Colin Crossfabb6082018-02-20 17:22:23 -08001018 },
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001019 "outDir", "combinedClassesJar", "assetsPackage")
Colin Crossfabb6082018-02-20 17:22:23 -08001020
1021func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1022 if len(a.properties.Aars) != 1 {
1023 ctx.PropertyErrorf("aars", "exactly one aar is required")
1024 return
1025 }
1026
Jiyong Park92315372021-04-02 08:45:46 +09001027 a.sdkVersion = a.SdkVersion(ctx)
1028 a.minSdkVersion = a.MinSdkVersion(ctx)
1029
Colin Cross56a83212020-09-15 18:30:11 -07001030 a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
1031
Nan Zhang4c819fb2018-08-27 18:31:46 -07001032 aarName := ctx.ModuleName() + ".aar"
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001033 a.aarPath = android.PathForModuleSrc(ctx, a.properties.Aars[0])
1034
Colin Cross1001a792019-03-21 22:21:39 -07001035 if Bool(a.properties.Jetifier) {
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001036 inputFile := a.aarPath
1037 a.aarPath = android.PathForModuleOut(ctx, "jetifier", aarName)
1038 TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile)
Nan Zhang4c819fb2018-08-27 18:31:46 -07001039 }
Colin Crossfabb6082018-02-20 17:22:23 -08001040
1041 extractedAARDir := android.PathForModuleOut(ctx, "aar")
Colin Cross205e9112020-08-06 13:20:17 -07001042 a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
Colin Crossfabb6082018-02-20 17:22:23 -08001043 a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
Colin Cross10f7c4a2018-05-23 10:59:28 -07001044 a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
Colin Cross039d8df2023-06-20 22:40:02 -07001045 aarRTxt := extractedAARDir.Join(ctx, "R.txt")
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001046 a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
Colin Crossfabb6082018-02-20 17:22:23 -08001047
1048 ctx.Build(pctx, android.BuildParams{
1049 Rule: unzipAAR,
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001050 Input: a.aarPath,
Colin Cross039d8df2023-06-20 22:40:02 -07001051 Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt},
Colin Crossfabb6082018-02-20 17:22:23 -08001052 Description: "unzip AAR",
1053 Args: map[string]string{
Colin Cross205e9112020-08-06 13:20:17 -07001054 "outDir": extractedAARDir.String(),
1055 "combinedClassesJar": a.classpathFile.String(),
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001056 "assetsPackage": a.assetsPackage.String(),
Colin Crossfabb6082018-02-20 17:22:23 -08001057 },
1058 })
1059
Colin Crossa0ba2f52019-06-22 12:59:27 -07001060 // Always set --pseudo-localize, it will be stripped out later for release
1061 // builds that don't want it.
1062 compileFlags := []string{"--pseudo-localize"}
Colin Crossfabb6082018-02-20 17:22:23 -08001063 compiledResDir := android.PathForModuleOut(ctx, "flat-res")
Colin Crossfabb6082018-02-20 17:22:23 -08001064 flata := compiledResDir.Join(ctx, "gen_res.flata")
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001065 aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
Colin Crossfabb6082018-02-20 17:22:23 -08001066
1067 a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
Jiyong Parkb7c639e2019-08-19 14:56:02 +09001068 // the subdir "android" is required to be filtered by package names
1069 srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
Colin Crossfabb6082018-02-20 17:22:23 -08001070 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
Colin Cross039d8df2023-06-20 22:40:02 -07001071 a.rTxt = android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -07001072 a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
Colin Crossfabb6082018-02-20 17:22:23 -08001073
1074 var linkDeps android.Paths
1075
1076 linkFlags := []string{
1077 "--static-lib",
Colin Cross039d8df2023-06-20 22:40:02 -07001078 "--merge-only",
Colin Crossfabb6082018-02-20 17:22:23 -08001079 "--auto-add-overlay",
1080 }
1081
Colin Cross10f7c4a2018-05-23 10:59:28 -07001082 linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
1083 linkDeps = append(linkDeps, a.manifest)
Colin Crossfabb6082018-02-20 17:22:23 -08001084
Colin Crossab8d1382023-07-14 17:23:41 +00001085 staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
Jiyong Parkf1691d22021-03-29 20:11:58 +09001086 aaptLibs(ctx, android.SdkContext(a), nil)
Colin Cross31656952018-05-24 16:11:20 -07001087
Colin Crossab8d1382023-07-14 17:23:41 +00001088 _ = staticRRODirsDepSet
1089 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
Colin Crossfabb6082018-02-20 17:22:23 -08001090
Colin Crossab8d1382023-07-14 17:23:41 +00001091 linkDeps = append(linkDeps, sharedLibs...)
Colin Cross039d8df2023-06-20 22:40:02 -07001092 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -07001093 linkFlags = append(linkFlags, libFlags...)
Colin Crossfabb6082018-02-20 17:22:23 -08001094
Colin Cross039d8df2023-06-20 22:40:02 -07001095 overlayRes := android.Paths{flata}
1096
1097 // Treat static library dependencies of static libraries as imports.
1098 transitiveStaticLibs := staticDeps.resPackages()
1099 linkDeps = append(linkDeps, transitiveStaticLibs...)
1100 for _, staticLib := range transitiveStaticLibs {
1101 linkFlags = append(linkFlags, "-I "+staticLib.String())
1102 }
Colin Crossfabb6082018-02-20 17:22:23 -08001103
Colin Crossab8d1382023-07-14 17:23:41 +00001104 transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
Colin Cross039d8df2023-06-20 22:40:02 -07001105 aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile,
Jaewoong Jung6431ca72020-01-15 14:15:10 -08001106 linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001107
Colin Cross039d8df2023-06-20 22:40:02 -07001108 a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
1109 resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
1110
Colin Crossab8d1382023-07-14 17:23:41 +00001111 resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
1112 resourcesNodesDepSetBuilder.Direct(&resourcesNode{
1113 resPackage: a.exportPackage,
1114 manifest: a.manifest,
Colin Cross039d8df2023-06-20 22:40:02 -07001115 rTxt: a.rTxt,
1116 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +00001117 assets: android.OptionalPathForPath(a.assetsPackage),
Colin Cross039d8df2023-06-20 22:40:02 -07001118
1119 usedResourceProcessor: true,
Colin Crossab8d1382023-07-14 17:23:41 +00001120 })
1121 resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
1122 a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
1123
1124 manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
1125 // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
1126 // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
1127 // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
1128 // android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped
1129 // completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest
1130 //manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests)
1131 _ = staticManifestsDepSet
1132 a.manifestsDepSet = manifestDepSetBuilder.Build()
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001133
Colin Cross039d8df2023-06-20 22:40:02 -07001134 a.transitiveAaptResourcePackages = staticDeps.resPackages()
1135
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001136 a.collectTransitiveHeaderJars(ctx)
Colin Crossdcf71b22021-02-01 13:59:03 -08001137 ctx.SetProvider(JavaInfoProvider, JavaInfo{
1138 HeaderJars: android.PathsIfNonNil(a.classpathFile),
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001139 TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
1140 TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
Colin Crossdcf71b22021-02-01 13:59:03 -08001141 ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
1142 ImplementationJars: android.PathsIfNonNil(a.classpathFile),
Joe Onorato6fe59eb2023-07-16 13:20:33 -07001143 // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
Colin Crossdcf71b22021-02-01 13:59:03 -08001144 })
Sam Delmerico82602492022-06-10 17:05:42 +00001145
1146 if proptools.Bool(a.properties.Extract_jni) {
1147 for _, t := range ctx.MultiTargets() {
1148 arch := t.Arch.Abi[0]
1149 path := android.PathForModuleOut(ctx, arch+"_jni.zip")
1150 a.jniPackages = append(a.jniPackages, path)
1151
1152 outDir := android.PathForModuleOut(ctx, "aarForJni")
1153 aarPath := android.PathForModuleSrc(ctx, a.properties.Aars[0])
1154 ctx.Build(pctx, android.BuildParams{
1155 Rule: extractJNI,
1156 Input: aarPath,
1157 Outputs: android.WritablePaths{path},
1158 Description: "extract JNI from AAR",
1159 Args: map[string]string{
1160 "outDir": outDir.String(),
1161 "archString": arch,
1162 },
1163 })
1164 }
1165
1166 ctx.SetProvider(JniPackageProvider, JniPackageInfo{
1167 JniPackages: a.jniPackages,
1168 })
1169 }
Colin Crossdcf71b22021-02-01 13:59:03 -08001170}
Colin Crossfabb6082018-02-20 17:22:23 -08001171
1172func (a *AARImport) HeaderJars() android.Paths {
1173 return android.Paths{a.classpathFile}
1174}
1175
Colin Cross331a1212018-08-15 20:40:52 -07001176func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
1177 return android.Paths{a.classpathFile}
1178}
1179
Ulyana Trafimovich5539e7b2020-06-04 14:08:17 +00001180func (a *AARImport) DexJarBuildPath() android.Path {
Colin Crossf24a22a2019-01-31 14:12:44 -08001181 return nil
1182}
1183
Ulya Trafimovich9f3052c2020-06-09 14:31:19 +01001184func (a *AARImport) DexJarInstallPath() android.Path {
1185 return nil
1186}
1187
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +01001188func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
Jiyong Park1be96912018-05-28 18:02:19 +09001189 return nil
1190}
1191
Jiyong Park45bf82e2020-12-15 22:29:02 +09001192var _ android.ApexModule = (*AARImport)(nil)
1193
1194// Implements android.ApexModule
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001195func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1196 return a.depIsInSameApex(ctx, dep)
1197}
1198
Jiyong Park45bf82e2020-12-15 22:29:02 +09001199// Implements android.ApexModule
Dan Albertc8060532020-07-22 22:32:17 -07001200func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
1201 sdkVersion android.ApiLevel) error {
Jooyung Han749dc692020-04-15 11:03:39 +09001202 return nil
1203}
1204
Sam Delmericoaf8bb702022-07-25 15:39:32 -04001205var _ android.PrebuiltInterface = (*AARImport)(nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001206
Colin Cross1b16b0e2019-02-12 14:41:32 -08001207// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
1208//
1209// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
1210// an android_app module.
Colin Crossfabb6082018-02-20 17:22:23 -08001211func AARImportFactory() android.Module {
1212 module := &AARImport{}
1213
1214 module.AddProperties(&module.properties)
1215
1216 android.InitPrebuiltModule(module, &module.properties.Aars)
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001217 android.InitApexModule(module)
Sam Delmerico82602492022-06-10 17:05:42 +00001218 InitJavaModuleMultiTargets(module, android.DeviceSupported)
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001219 android.InitBazelModule(module)
Colin Crossfabb6082018-02-20 17:22:23 -08001220 return module
1221}
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001222
1223type bazelAapt struct {
1224 Manifest bazel.Label
1225 Resource_files bazel.LabelListAttribute
1226}
1227
1228type bazelAndroidLibrary struct {
1229 *javaLibraryAttributes
1230 *bazelAapt
1231}
1232
1233type bazelAndroidLibraryImport struct {
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001234 Aar bazel.Label
1235 Deps bazel.LabelListAttribute
1236 Exports bazel.LabelListAttribute
1237 Sdk_version bazel.StringAttribute
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001238}
1239
1240func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt {
1241 manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
1242
1243 resourceFiles := bazel.LabelList{
1244 Includes: []bazel.Label{},
1245 }
1246 for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
1247 files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
1248 resourceFiles.Includes = append(resourceFiles.Includes, files...)
1249 }
1250 return &bazelAapt{
1251 android.BazelLabelForModuleSrcSingle(ctx, manifest),
1252 bazel.MakeLabelListAttribute(resourceFiles),
1253 }
1254}
1255
1256func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
1257 aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{})
1258 exportableStaticLibs := []string{}
1259 // TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel.
1260 for _, depName := range a.properties.Static_libs {
1261 if dep, ok := ctx.ModuleFromName(depName); ok {
1262 switch dep.(type) {
1263 case *AARImport, *Import:
1264 exportableStaticLibs = append(exportableStaticLibs, depName)
1265 }
1266 }
1267 }
1268 name := android.RemoveOptionalPrebuiltPrefix(a.Name())
1269 deps := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(append(a.properties.Static_libs, a.properties.Libs...))))
1270 exports := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(exportableStaticLibs))
1271
1272 ctx.CreateBazelTargetModule(
1273 bazel.BazelTargetModuleProperties{
1274 Rule_class: "aar_import",
Alixa381cd12023-05-10 14:49:38 +00001275 Bzl_load_location: "//build/bazel/rules/android:aar_import.bzl",
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001276 },
1277 android.CommonAttributes{Name: name},
1278 &bazelAndroidLibraryImport{
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001279 Aar: aars.Includes[0],
1280 Deps: bazel.MakeLabelListAttribute(deps),
1281 Exports: bazel.MakeLabelListAttribute(exports),
1282 Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version},
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001283 },
1284 )
1285
Alix14101de2023-01-06 03:42:07 +00001286 neverlink := true
1287 ctx.CreateBazelTargetModule(
Alix32540022023-03-16 21:06:13 +00001288 AndroidLibraryBazelTargetModuleProperties(),
Alix14101de2023-01-06 03:42:07 +00001289 android.CommonAttributes{Name: name + "-neverlink"},
1290 &bazelAndroidLibrary{
1291 javaLibraryAttributes: &javaLibraryAttributes{
1292 Neverlink: bazel.BoolAttribute{Value: &neverlink},
1293 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}),
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001294 javaCommonAttributes: &javaCommonAttributes{
1295 Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version},
1296 },
Alix14101de2023-01-06 03:42:07 +00001297 },
1298 },
1299 )
1300
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001301}
Alix32540022023-03-16 21:06:13 +00001302func AndroidLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties {
1303 return bazel.BazelTargetModuleProperties{
1304 Rule_class: "android_library",
Alixa381cd12023-05-10 14:49:38 +00001305 Bzl_load_location: "//build/bazel/rules/android:android_library.bzl",
Alix32540022023-03-16 21:06:13 +00001306 }
1307}
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001308
1309func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Alix8062f4d2022-11-14 21:38:07 +00001310 commonAttrs, bp2buildInfo := a.convertLibraryAttrsBp2Build(ctx)
1311 depLabels := bp2buildInfo.DepLabels
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001312
1313 deps := depLabels.Deps
1314 if !commonAttrs.Srcs.IsEmpty() {
1315 deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
1316 } else if !depLabels.Deps.IsEmpty() {
1317 ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
1318 }
Alix82fb94e2022-10-26 20:40:18 +00001319 name := a.Name()
Alix32540022023-03-16 21:06:13 +00001320 props := AndroidLibraryBazelTargetModuleProperties()
Alix82fb94e2022-10-26 20:40:18 +00001321
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001322 ctx.CreateBazelTargetModule(
Alix82fb94e2022-10-26 20:40:18 +00001323 props,
1324 android.CommonAttributes{Name: name},
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001325 &bazelAndroidLibrary{
1326 &javaLibraryAttributes{
1327 javaCommonAttributes: commonAttrs,
1328 Deps: deps,
1329 Exports: depLabels.StaticDeps,
1330 },
1331 a.convertAaptAttrsWithBp2Build(ctx),
1332 },
1333 )
Alix82fb94e2022-10-26 20:40:18 +00001334
1335 neverlink := true
1336 ctx.CreateBazelTargetModule(
1337 props,
1338 android.CommonAttributes{Name: name + "-neverlink"},
1339 &bazelAndroidLibrary{
1340 javaLibraryAttributes: &javaLibraryAttributes{
1341 Neverlink: bazel.BoolAttribute{Value: &neverlink},
1342 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}),
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001343 javaCommonAttributes: &javaCommonAttributes{
1344 Sdk_version: bazel.StringAttribute{Value: a.deviceProperties.Sdk_version},
1345 Java_version: bazel.StringAttribute{Value: a.properties.Java_version},
1346 },
Alix82fb94e2022-10-26 20:40:18 +00001347 },
1348 },
1349 )
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001350}