blob: 20972b2d8561e101eeb8dd8065b8c89e1abd2f17 [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 Cross4eae06d2023-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 Cross4eae06d2023-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 Cross4eae06d2023-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
Colin Crossa97c5d32018-03-28 14:58:31 -0700194 // Find implicit or explicit asset and resource dirs
195 assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
196 resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
Colin Cross8a497952019-03-05 22:25:09 -0800197 resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
Colin Crossa97c5d32018-03-28 14:58:31 -0700198
Colin Crossa97c5d32018-03-28 14:58:31 -0700199 // Glob directories into lists of paths
200 for _, dir := range resourceDirs {
201 resDirs = append(resDirs, globbedResourceDir{
202 dir: dir,
203 files: androidResourceGlob(ctx, dir),
204 })
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700205 resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
Colin Crossa97c5d32018-03-28 14:58:31 -0700206 overlayDirs = append(overlayDirs, resOverlayDirs...)
207 rroDirs = append(rroDirs, resRRODirs...)
208 }
209
Colin Crossc20dc852020-11-10 12:27:45 -0800210 var assetDeps android.Paths
211 for i, dir := range assetDirs {
212 // Add a dependency on every file in the asset directory. This ensures the aapt2
213 // rule will be rerun if one of the files in the asset directory is modified.
214 assetDeps = append(assetDeps, androidResourceGlob(ctx, dir)...)
215
216 // Add a dependency on a file that contains a list of all the files in the asset directory.
217 // This ensures the aapt2 rule will be run if a file is removed from the asset directory,
218 // or a file is added whose timestamp is older than the output of aapt2.
219 assetFileListFile := android.PathForModuleOut(ctx, "asset_dir_globs", strconv.Itoa(i)+".glob")
220 androidResourceGlobList(ctx, dir, assetFileListFile)
221 assetDeps = append(assetDeps, assetFileListFile)
Colin Crossa97c5d32018-03-28 14:58:31 -0700222 }
223
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700224 assetDirStrings := assetDirs.Strings()
225 if a.noticeFile.Valid() {
226 assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
Colin Crossc20dc852020-11-10 12:27:45 -0800227 assetDeps = append(assetDeps, a.noticeFile.Path())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700228 }
229
Colin Crossa97c5d32018-03-28 14:58:31 -0700230 linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
231 linkDeps = append(linkDeps, manifestPath)
232
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700233 linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
Colin Crossc20dc852020-11-10 12:27:45 -0800234 linkDeps = append(linkDeps, assetDeps...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700235
Spandan Das50885c02023-02-23 21:31:33 +0000236 // Returns the effective version for {min|target}_sdk_version
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000237 effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.ApiLevel) string {
Spandan Das50885c02023-02-23 21:31:33 +0000238 // If {min|target}_sdk_version is current, use sdk_version to determine the effective level
239 // This is necessary for vendor modules.
240 // The effective version does not _only_ depend on {min|target}_sdk_version(level),
241 // but also on the sdk_version (kind+level)
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000242 if minSdkVersion.IsCurrent() {
Spandan Das50885c02023-02-23 21:31:33 +0000243 ret, err := sdkVersion.EffectiveVersionString(ctx)
244 if err != nil {
245 ctx.ModuleErrorf("invalid sdk_version: %s", err)
246 }
247 return ret
248 }
249 ret, err := minSdkVersion.EffectiveVersionString(ctx)
250 if err != nil {
251 ctx.ModuleErrorf("invalid min_sdk_version: %s", err)
252 }
253 return ret
Jiyong Park6a927c42020-01-21 02:03:43 +0900254 }
Spandan Das50885c02023-02-23 21:31:33 +0000255 // SDK version flags
256 sdkVersion := sdkContext.SdkVersion(ctx)
257 minSdkVersion := effectiveVersionString(sdkVersion, sdkContext.MinSdkVersion(ctx))
Colin Crossa97c5d32018-03-28 14:58:31 -0700258
Colin Cross83bb3162018-06-25 15:48:06 -0700259 linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
Spandan Das6450b552023-02-23 19:27:07 +0000260 // Use minSdkVersion for target-sdk-version, even if `target_sdk_version` is set
261 // This behavior has been copied from Make.
Colin Cross83bb3162018-06-25 15:48:06 -0700262 linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
Colin Crossa97c5d32018-03-28 14:58:31 -0700263
Colin Crossa97c5d32018-03-28 14:58:31 -0700264 // Version code
265 if !hasVersionCode {
Dan Albert4f378d72020-07-23 17:32:15 -0700266 linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
Colin Crossa97c5d32018-03-28 14:58:31 -0700267 }
268
269 if !hasVersionName {
Colin Cross402d5e02018-04-25 14:54:06 -0700270 var versionName string
271 if ctx.ModuleName() == "framework-res" {
272 // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
273 // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
Colin Crossbfd347d2018-05-09 11:11:35 -0700274 // if it contains the build number. Use the PlatformVersionName instead.
275 versionName = ctx.Config().PlatformVersionName()
Colin Cross402d5e02018-04-25 14:54:06 -0700276 } else {
277 versionName = ctx.Config().AppsDefaultVersionName()
278 }
Colin Cross0b9f31f2019-02-28 11:00:01 -0800279 versionName = proptools.NinjaEscape(versionName)
Colin Crossa97c5d32018-03-28 14:58:31 -0700280 linkFlags = append(linkFlags, "--version-name ", versionName)
281 }
282
Colin Crossa0ba2f52019-06-22 12:59:27 -0700283 linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
284
285 // Always set --pseudo-localize, it will be stripped out later for release
286 // builds that don't want it.
287 compileFlags = append(compileFlags, "--pseudo-localize")
288
289 return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
Colin Crossa97c5d32018-03-28 14:58:31 -0700290}
291
Paul Duffin250e6192019-06-07 10:44:37 +0100292func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
Colin Cross42308aa2018-11-14 21:44:17 -0800293 if sdkDep.frameworkResModule != "" {
294 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossa97c5d32018-03-28 14:58:31 -0700295 }
296}
297
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800298var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
299 blueprint.RuleParams{
300 Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
301 CommandDeps: []string{"${config.Zip2ZipCmd}"},
302 })
303
Jiyong Parkf1691d22021-03-29 20:11:58 +0900304func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
Paul Duffin06530572022-02-03 17:54:15 +0000305 classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000306 enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {
Colin Cross5446e882019-05-22 10:46:27 -0700307
Colin Crossab8d1382023-07-14 17:23:41 +0000308 staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedDeps, libFlags :=
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100309 aaptLibs(ctx, sdkContext, classLoaderContexts)
Ulya Trafimovich31e444e2020-08-14 17:32:16 +0100310
Paul Duffin06530572022-02-03 17:54:15 +0000311 // Exclude any libraries from the supplied list.
312 classLoaderContexts = classLoaderContexts.ExcludeLibs(excludedLibs)
313
Colin Cross31656952018-05-24 16:11:20 -0700314 // App manifest file
315 manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
316 manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
317
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000318 manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000319 SdkContext: sdkContext,
320 ClassLoaderContexts: classLoaderContexts,
321 IsLibrary: a.isLibrary,
322 DefaultManifestVersion: a.defaultManifestVersion,
323 UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
324 UsesNonSdkApis: a.usesNonSdkApis,
325 UseEmbeddedDex: a.useEmbeddedDex,
326 HasNoCode: a.hasNoCode,
327 LoggingParent: a.LoggingParent,
328 EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000329 })
Colin Cross90c25c62019-04-19 16:22:57 -0700330
Colin Crossab8d1382023-07-14 17:23:41 +0000331 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
332
Luca Stefanifd898822019-09-10 22:13:31 +0200333 // Add additional manifest files to transitive manifests.
334 additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
Colin Crossab8d1382023-07-14 17:23:41 +0000335 transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
336 // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
337 // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
338 // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
339 // android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of
340 // staticResourcesNodesDepSet.manifests()
341 transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
Colin Cross90c25c62019-04-19 16:22:57 -0700342
Colin Crossab8d1382023-07-14 17:23:41 +0000343 if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
344 a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], transitiveManifestPaths[1:], a.isLibrary)
Colin Cross90c25c62019-04-19 16:22:57 -0700345 if !a.isLibrary {
346 // Only use the merged manifest for applications. For libraries, the transitive closure of manifests
347 // will be propagated to the final application and merged there. The merged manifest for libraries is
348 // only passed to Make, which can't handle transitive dependencies.
349 manifestPath = a.mergedManifestFile
350 }
351 } else {
352 a.mergedManifestFile = manifestPath
353 }
Colin Cross31656952018-05-24 16:11:20 -0700354
Colin Crossa0ba2f52019-06-22 12:59:27 -0700355 compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath)
Colin Cross31656952018-05-24 16:11:20 -0700356
357 linkFlags = append(linkFlags, libFlags...)
Colin Crossab8d1382023-07-14 17:23:41 +0000358 linkDeps = append(linkDeps, sharedDeps...)
359 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700360 linkFlags = append(linkFlags, extraLinkFlags...)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700361 if a.isLibrary {
362 linkFlags = append(linkFlags, "--static-lib")
363 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700364
Colin Cross4eae06d2023-06-20 22:40:02 -0700365 if a.isLibrary && a.useResourceProcessorBusyBox() {
366 // When building an android_library using ResourceProcessorBusyBox the resources are merged into
367 // package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
368 // contains resources from this library.
369 linkFlags = append(linkFlags, "--merge-only")
370 } else {
371 // When building and app or when building an android_library without ResourceProcessorBusyBox
372 // --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
373 // is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
374 // sort resources into the right packages in R.class.
375 linkFlags = append(linkFlags, "--no-static-lib-packages")
376 }
377
Colin Crossa97c5d32018-03-28 14:58:31 -0700378 packageRes := android.PathForModuleOut(ctx, "package-res.apk")
Jiyong Parkb7c639e2019-08-19 14:56:02 +0900379 // the subdir "android" is required to be filtered by package names
380 srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
Colin Crossa97c5d32018-03-28 14:58:31 -0700381 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
382 rTxt := android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -0700383 // This file isn't used by Soong, but is generated for exporting
384 extraPackages := android.PathForModuleOut(ctx, "extra_packages")
Colin Cross4eae06d2023-06-20 22:40:02 -0700385 var transitiveRJars android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700386
Colin Cross4aaa84a2018-08-21 15:14:37 -0700387 var compiledResDirs []android.Paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700388 for _, dir := range resDirs {
Colin Cross014489c2020-06-02 20:09:13 -0700389 a.resourceFiles = append(a.resourceFiles, dir.files...)
Colin Crossa0ba2f52019-06-22 12:59:27 -0700390 compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths())
Colin Crossa97c5d32018-03-28 14:58:31 -0700391 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700392
Colin Crossa592e3e2019-02-19 16:59:53 -0800393 for i, zip := range resZips {
394 flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
Colin Crossa0ba2f52019-06-22 12:59:27 -0700395 aapt2CompileZip(ctx, flata, zip, "", compileFlags)
Colin Crossa592e3e2019-02-19 16:59:53 -0800396 compiledResDirs = append(compiledResDirs, android.Paths{flata})
397 }
398
Colin Cross4aaa84a2018-08-21 15:14:37 -0700399 var compiledRes, compiledOverlay android.Paths
400
Colin Crossab8d1382023-07-14 17:23:41 +0000401 // AAPT2 overlays are in lowest to highest priority order, reverse the topological order
402 // of transitiveStaticLibs.
403 transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
404
Colin Cross4eae06d2023-06-20 22:40:02 -0700405 if a.isLibrary && a.useResourceProcessorBusyBox() {
406 // When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
407 // as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
408 // instead modules depending on this module will reference package-res.apk from all transitive static
409 // dependencies.
410 for _, staticDep := range staticDeps {
411 linkDeps = append(linkDeps, staticDep.resPackage)
412 linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
413 if staticDep.usedResourceProcessor {
414 transitiveRJars = append(transitiveRJars, staticDep.rJar)
415 }
416 }
417 } else {
418 // When building an app or building a library without ResourceProcessorBusyBox enabled all static
419 // dependencies are compiled into this module's package-res.apk as overlays.
420 compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
421 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700422
Colin Crossbec85302019-02-13 13:15:46 -0800423 if len(transitiveStaticLibs) > 0 {
Colin Cross4aaa84a2018-08-21 15:14:37 -0700424 // If we are using static android libraries, every source file becomes an overlay.
425 // This is to emulate old AAPT behavior which simulated library support.
426 for _, compiledResDir := range compiledResDirs {
427 compiledOverlay = append(compiledOverlay, compiledResDir...)
428 }
Colin Crossbec85302019-02-13 13:15:46 -0800429 } else if a.isLibrary {
430 // Otherwise, for a static library we treat all the resources equally with no overlay.
431 for _, compiledResDir := range compiledResDirs {
432 compiledRes = append(compiledRes, compiledResDir...)
433 }
Colin Cross4aaa84a2018-08-21 15:14:37 -0700434 } else if len(compiledResDirs) > 0 {
435 // Without static libraries, the first directory is our directory, which can then be
436 // overlaid by the rest.
437 compiledRes = append(compiledRes, compiledResDirs[0]...)
438 for _, compiledResDir := range compiledResDirs[1:] {
439 compiledOverlay = append(compiledOverlay, compiledResDir...)
440 }
441 }
442
Colin Crossa97c5d32018-03-28 14:58:31 -0700443 for _, dir := range overlayDirs {
Colin Crossa0ba2f52019-06-22 12:59:27 -0700444 compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700445 }
446
Colin Crosse560c4a2019-03-19 16:03:11 -0700447 var splitPackages android.WritablePaths
448 var splits []split
449
450 for _, s := range a.splitNames {
451 suffix := strings.Replace(s, ",", "_", -1)
452 path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
453 linkFlags = append(linkFlags, "--split", path.String()+":"+s)
454 splitPackages = append(splitPackages, path)
455 splits = append(splits, split{
456 name: s,
457 suffix: suffix,
458 path: path,
459 })
460 }
461
Colin Crossab8d1382023-07-14 17:23:41 +0000462 // No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
463 // provided to the final app aapt2Link step.
464 var transitiveAssets android.Paths
465 if !a.isLibrary {
466 transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
467 }
Colin Cross66f78822018-05-02 12:58:28 -0700468 aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
Colin Crossab8d1382023-07-14 17:23:41 +0000469 linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages)
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800470
471 // Extract assets from the resource package output so that they can be used later in aapt2link
472 // for modules that depend on this one.
Colin Crossab8d1382023-07-14 17:23:41 +0000473 if android.PrefixInList(linkFlags, "-A ") {
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800474 assets := android.PathForModuleOut(ctx, "assets.zip")
475 ctx.Build(pctx, android.BuildParams{
476 Rule: extractAssetsRule,
477 Input: packageRes,
478 Output: assets,
479 Description: "extract assets from built resource file",
480 })
481 a.assetPackage = android.OptionalPathForPath(assets)
482 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700483
Colin Cross4eae06d2023-06-20 22:40:02 -0700484 if a.useResourceProcessorBusyBox() {
485 rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
486 resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
487 transitiveRJars = append(transitiveRJars, rJar)
488 a.rJar = rJar
489 }
490
Colin Crossa97c5d32018-03-28 14:58:31 -0700491 a.aaptSrcJar = srcJar
Colin Cross4eae06d2023-06-20 22:40:02 -0700492 a.transitiveAaptRJars = transitiveRJars
493 a.transitiveAaptResourcePackages = staticDeps.resPackages()
Colin Crossa97c5d32018-03-28 14:58:31 -0700494 a.exportPackage = packageRes
495 a.manifestPath = manifestPath
496 a.proguardOptionsFile = proguardOptionsFile
Colin Cross66f78822018-05-02 12:58:28 -0700497 a.extraAaptPackagesFile = extraPackages
Colin Crossa97c5d32018-03-28 14:58:31 -0700498 a.rTxt = rTxt
Colin Crosse560c4a2019-03-19 16:03:11 -0700499 a.splits = splits
Colin Crossab8d1382023-07-14 17:23:41 +0000500 a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL).
501 Direct(&resourcesNode{
502 resPackage: a.exportPackage,
503 manifest: a.manifestPath,
504 additionalManifests: additionalManifests,
Colin Cross4eae06d2023-06-20 22:40:02 -0700505 rTxt: a.rTxt,
506 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +0000507 assets: a.assetPackage,
Colin Cross4eae06d2023-06-20 22:40:02 -0700508
509 usedResourceProcessor: a.useResourceProcessorBusyBox(),
Colin Crossab8d1382023-07-14 17:23:41 +0000510 }).
511 Transitive(staticResourcesNodesDepSet).Build()
512 a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
513 Direct(rroDirs...).
514 Transitive(staticRRODirsDepSet).Build()
515 a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
516 Direct(a.manifestPath).
517 DirectSlice(additionalManifests).
518 Transitive(staticManifestsDepSet).Build()
519}
520
Colin Cross4eae06d2023-06-20 22:40:02 -0700521var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
522 blueprint.RuleParams{
523 Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
524 "com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
525 "if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
526 CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
527 Rspfile: "${out}.args",
528 RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
529 Restat: true,
530 }, "rTxt", "manifest", "args")
531
532// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
533// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
534// supports producing classes for static dependencies that only include resources from that dependency.
535func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
536 rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) {
537
538 var args []string
539 var deps android.Paths
540
541 if !isLibrary {
542 // When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
543 // to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
544 // package.
545 args, deps = transitiveDeps.resourceProcessorDeps()
546 } else {
547 // When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
548 // library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
549 // inlined into the library before the final IDs are assigned during app compilation.
550 args = append(args, "--finalFields=false")
551 }
552
553 deps = append(deps, rTxt, manifest)
554
555 ctx.Build(pctx, android.BuildParams{
556 Rule: resourceProcessorBusyBox,
557 Output: rJar,
558 Implicits: deps,
559 Description: "ResourceProcessorBusyBox",
560 Args: map[string]string{
561 "rTxt": rTxt.String(),
562 "manifest": manifest.String(),
563 "args": strings.Join(args, " "),
564 },
565 })
566}
567
Colin Crossab8d1382023-07-14 17:23:41 +0000568type resourcesNode struct {
569 resPackage android.Path
570 manifest android.Path
571 additionalManifests android.Paths
Colin Cross4eae06d2023-06-20 22:40:02 -0700572 rTxt android.Path
573 rJar android.Path
Colin Crossab8d1382023-07-14 17:23:41 +0000574 assets android.OptionalPath
Colin Cross4eae06d2023-06-20 22:40:02 -0700575
576 usedResourceProcessor bool
Colin Crossab8d1382023-07-14 17:23:41 +0000577}
578
579type transitiveAarDeps []*resourcesNode
580
581func (t transitiveAarDeps) resPackages() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700582 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000583 for _, dep := range t {
584 paths = append(paths, dep.resPackage)
585 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700586 return paths
Colin Crossab8d1382023-07-14 17:23:41 +0000587}
588
589func (t transitiveAarDeps) manifests() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700590 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000591 for _, dep := range t {
592 paths = append(paths, dep.manifest)
593 paths = append(paths, dep.additionalManifests...)
594 }
Colin Cross4eae06d2023-06-20 22:40:02 -0700595 return paths
596}
597
598func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
599 for _, dep := range t {
600 args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
601 deps = append(deps, dep.rTxt, dep.manifest)
602 }
603 return args, deps
Colin Crossab8d1382023-07-14 17:23:41 +0000604}
605
606func (t transitiveAarDeps) assets() android.Paths {
Colin Cross4eae06d2023-06-20 22:40:02 -0700607 paths := make(android.Paths, 0, len(t))
Colin Crossab8d1382023-07-14 17:23:41 +0000608 for _, dep := range t {
609 if dep.assets.Valid() {
610 paths = append(paths, dep.assets.Path())
611 }
612 }
613 return paths
Colin Crossa97c5d32018-03-28 14:58:31 -0700614}
615
616// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
Jiyong Parkf1691d22021-03-29 20:11:58 +0900617func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
Colin Crossab8d1382023-07-14 17:23:41 +0000618 staticResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
619 staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
Colin Crossa97c5d32018-03-28 14:58:31 -0700620
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100621 if classLoaderContexts == nil {
Ulya Trafimovich18554242020-11-03 15:55:11 +0000622 // Not all callers need to compute class loader context, those who don't just pass nil.
623 // Create a temporary class loader context here (it will be computed, but not used).
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100624 classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000625 }
626
Colin Cross83bb3162018-06-25 15:48:06 -0700627 sdkDep := decodeSdkDep(ctx, sdkContext)
Colin Crossa97c5d32018-03-28 14:58:31 -0700628 if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700629 sharedLibs = append(sharedLibs, sdkDep.jars...)
Colin Crossa97c5d32018-03-28 14:58:31 -0700630 }
631
Colin Crossab8d1382023-07-14 17:23:41 +0000632 var resourcesNodeDepSets []*android.DepSet[*resourcesNode]
633 rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL)
634 manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL)
635
Colin Crossa97c5d32018-03-28 14:58:31 -0700636 ctx.VisitDirectDeps(func(module android.Module) {
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000637 depTag := ctx.OtherModuleDependencyTag(module)
Ulya Trafimovich18554242020-11-03 15:55:11 +0000638
Colin Crossa97c5d32018-03-28 14:58:31 -0700639 var exportPackage android.Path
Colin Cross66f78822018-05-02 12:58:28 -0700640 aarDep, _ := module.(AndroidLibraryDependency)
641 if aarDep != nil {
Colin Crossa97c5d32018-03-28 14:58:31 -0700642 exportPackage = aarDep.ExportPackage()
643 }
644
Ulya Trafimovich65b03192020-12-03 16:50:22 +0000645 switch depTag {
Colin Cross4b964c02018-10-15 16:18:06 -0700646 case instrumentationForTag:
647 // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
Liz Kammeref28a4c2022-09-23 16:50:56 -0400648 case sdkLibTag, libTag:
Colin Cross5446e882019-05-22 10:46:27 -0700649 if exportPackage != nil {
650 sharedLibs = append(sharedLibs, exportPackage)
651 }
Colin Cross5446e882019-05-22 10:46:27 -0700652 case frameworkResTag:
Colin Crossa97c5d32018-03-28 14:58:31 -0700653 if exportPackage != nil {
654 sharedLibs = append(sharedLibs, exportPackage)
655 }
656 case staticLibTag:
657 if exportPackage != nil {
Colin Crossab8d1382023-07-14 17:23:41 +0000658 resourcesNodeDepSets = append(resourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
659 rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
660 manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
Colin Crossa97c5d32018-03-28 14:58:31 -0700661 }
662 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000663
Ulya Trafimovich88bb6f62020-12-16 16:16:11 +0000664 addCLCFromDep(ctx, module, classLoaderContexts)
Colin Crossa97c5d32018-03-28 14:58:31 -0700665 })
666
Colin Crossab8d1382023-07-14 17:23:41 +0000667 // AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
668 // Reverse the dependency order now going into the depset so that it comes out in order after the second
669 // reverse later.
670 // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
671 // dependencies) the highest priority dependency is listed first, but for resources the highest priority
672 // dependency has to be listed last.
673 staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
674 android.ReverseSliceInPlace(resourcesNodeDepSets))
Colin Crossa97c5d32018-03-28 14:58:31 -0700675
Colin Crossab8d1382023-07-14 17:23:41 +0000676 staticRRODirs = rroDirsDepSetBuilder.Build()
677 staticManifests = manifestsDepSetBuilder.Build()
678
679 if len(staticResourcesNodes.ToList()) > 0 {
Colin Crossa97c5d32018-03-28 14:58:31 -0700680 flags = append(flags, "--auto-add-overlay")
681 }
682
683 for _, sharedLib := range sharedLibs {
684 flags = append(flags, "-I "+sharedLib.String())
685 }
686
Colin Crossab8d1382023-07-14 17:23:41 +0000687 return staticResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
Colin Crossa97c5d32018-03-28 14:58:31 -0700688}
689
690type AndroidLibrary struct {
691 Library
692 aapt
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500693 android.BazelModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700694
695 androidLibraryProperties androidLibraryProperties
696
697 aarFile android.WritablePath
Colin Cross89c31582018-04-30 15:55:11 -0700698}
699
Saeid Farivar Asanjan1fca3012021-09-14 18:40:19 +0000700var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
701
702// For OutputFileProducer interface
703func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
704 switch tag {
705 case ".aar":
706 return []android.Path{a.aarFile}, nil
707 default:
708 return a.Library.OutputFiles(tag)
709 }
710}
711
Colin Crossa97c5d32018-03-28 14:58:31 -0700712var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
713
714func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
715 a.Module.deps(ctx)
Jiyong Parkf1691d22021-03-29 20:11:58 +0900716 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Paul Duffin250e6192019-06-07 10:44:37 +0100717 if sdkDep.hasFrameworkLibs() {
718 a.aapt.deps(ctx, sdkDep)
Colin Crossa97c5d32018-03-28 14:58:31 -0700719 }
Colin Cross4a80a152022-12-21 21:51:52 -0800720 a.usesLibrary.deps(ctx, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700721}
722
723func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosse4246ab2019-02-05 21:55:21 -0800724 a.aapt.isLibrary = true
Ulya Trafimovich42c7f0d2021-08-17 16:20:29 +0100725 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000726 a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil, false)
Colin Crossa97c5d32018-03-28 14:58:31 -0700727
Colin Cross56a83212020-09-15 18:30:11 -0700728 a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
729
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000730 a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
731
Colin Cross4eae06d2023-06-20 22:40:02 -0700732 ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
733 ctx.CheckbuildFile(a.aapt.exportPackage)
734 ctx.CheckbuildFile(a.aapt.aaptSrcJar)
735 if a.useResourceProcessorBusyBox() {
736 ctx.CheckbuildFile(a.aapt.rJar)
737 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700738
739 // apps manifests are handled by aapt, don't let Module see them
740 a.properties.Manifest = nil
741
Colin Cross014489c2020-06-02 20:09:13 -0700742 a.linter.mergedManifest = a.aapt.mergedManifestFile
743 a.linter.manifest = a.aapt.manifestPath
744 a.linter.resources = a.aapt.resourceFiles
745
Colin Crossa97c5d32018-03-28 14:58:31 -0700746 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
747 a.proguardOptionsFile)
748
Colin Cross4eae06d2023-06-20 22:40:02 -0700749 var extraSrcJars android.Paths
750 var extraCombinedJars android.Paths
751 var extraClasspathJars android.Paths
752 if a.useResourceProcessorBusyBox() {
753 // When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
754 // library and each of the transitive static android_library dependencies has already created an
755 // R.class file for the appropriate package. Add all of those R.class files to the classpath.
756 extraClasspathJars = a.transitiveAaptRJars
757 } else {
758 // When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
759 // R.java files for the library's package and the packages from all transitive static android_library
760 // dependencies. Compile the srcjar alongside the rest of the sources.
761 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
762 }
763
764 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
Colin Crossa97c5d32018-03-28 14:58:31 -0700765
Colin Crossf57c5782019-01-25 13:20:38 -0800766 a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
Colin Crossa97c5d32018-03-28 14:58:31 -0700767 var res android.Paths
768 if a.androidLibraryProperties.BuildAAR {
769 BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
770 ctx.CheckbuildFile(a.aarFile)
771 }
Colin Cross89c31582018-04-30 15:55:11 -0700772
Cole Faust9a631312020-10-22 21:05:24 +0000773 a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles,
774 android.PathsForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files)...)
Colin Crossab8d1382023-07-14 17:23:41 +0000775
Colin Cross89c31582018-04-30 15:55:11 -0700776 ctx.VisitDirectDeps(func(m android.Module) {
Jared Duke5979b302022-12-19 21:08:39 +0000777 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
778 if lib, ok := m.(LibraryDependency); ok {
779 a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
780 }
Colin Cross89c31582018-04-30 15:55:11 -0700781 }
782 })
Colin Cross89c31582018-04-30 15:55:11 -0700783 a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles)
Sam Delmerico82602492022-06-10 17:05:42 +0000784
785 prebuiltJniPackages := android.Paths{}
786 ctx.VisitDirectDeps(func(module android.Module) {
787 if info, ok := ctx.OtherModuleProvider(module, JniPackageProvider).(JniPackageInfo); ok {
788 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
789 }
790 })
791 if len(prebuiltJniPackages) > 0 {
792 ctx.SetProvider(JniPackageProvider, JniPackageInfo{
793 JniPackages: prebuiltJniPackages,
794 })
795 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700796}
797
Colin Cross1b16b0e2019-02-12 14:41:32 -0800798// android_library builds and links sources into a `.jar` file for the device along with Android resources.
799//
800// An android_library has a single variant that produces a `.jar` file containing `.class` files that were
Sam Delmerico82602492022-06-10 17:05:42 +0000801// compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
Colin Cross1b16b0e2019-02-12 14:41:32 -0800802// with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
803// an android_app module.
Colin Crossa97c5d32018-03-28 14:58:31 -0700804func AndroidLibraryFactory() android.Module {
805 module := &AndroidLibrary{}
806
Colin Crossce6734e2020-06-15 16:09:53 -0700807 module.Module.addHostAndDeviceProperties()
Colin Crossa97c5d32018-03-28 14:58:31 -0700808 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -0700809 &module.aaptProperties,
810 &module.androidLibraryProperties)
811
812 module.androidLibraryProperties.BuildAAR = true
Colin Cross014489c2020-06-02 20:09:13 -0700813 module.Module.linter.library = true
Colin Crossa97c5d32018-03-28 14:58:31 -0700814
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900815 android.InitApexModule(module)
Colin Cross48de9a42018-10-02 13:53:33 -0700816 InitJavaModule(module, android.DeviceSupported)
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500817 android.InitBazelModule(module)
Colin Crossa97c5d32018-03-28 14:58:31 -0700818 return module
819}
820
Colin Crossfabb6082018-02-20 17:22:23 -0800821//
822// AAR (android library) prebuilts
823//
Colin Crossfabb6082018-02-20 17:22:23 -0800824
Vinh Trance0781f2022-04-13 01:30:44 +0000825// Properties for android_library_import
Colin Crossfabb6082018-02-20 17:22:23 -0800826type AARImportProperties struct {
Vinh Trance0781f2022-04-13 01:30:44 +0000827 // ARR (android library prebuilt) filepath. Exactly one ARR is required.
Colin Cross27b922f2019-03-04 22:35:41 -0800828 Aars []string `android:"path"`
Vinh Trance0781f2022-04-13 01:30:44 +0000829 // If not blank, set to the version of the sdk to compile against.
830 // Defaults to private.
831 // Values are of one of the following forms:
832 // 1) numerical API level, "current", "none", or "core_platform"
833 // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
834 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
835 // If the SDK kind is empty, it will be set to public
836 Sdk_version *string
837 // If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
838 // Defaults to sdk_version if not set. See sdk_version for possible values.
Colin Cross479884c2018-07-10 13:39:30 -0700839 Min_sdk_version *string
Vinh Trance0781f2022-04-13 01:30:44 +0000840 // List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
Colin Crossa97c5d32018-03-28 14:58:31 -0700841 Static_libs []string
Vinh Trance0781f2022-04-13 01:30:44 +0000842 // List of java libraries that the included ARR (android library prebuilts) has dependencies to.
843 Libs []string
844 // If set to true, run Jetifier against .aar file. Defaults to false.
Colin Cross1001a792019-03-21 22:21:39 -0700845 Jetifier *bool
Sam Delmerico82602492022-06-10 17:05:42 +0000846 // If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and
847 // will be passed transitively through android_libraries to an android_app.
848 //TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
849 Extract_jni *bool
Colin Crossfabb6082018-02-20 17:22:23 -0800850}
851
852type AARImport struct {
853 android.ModuleBase
Colin Cross48de9a42018-10-02 13:53:33 -0700854 android.DefaultableModuleBase
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900855 android.ApexModuleBase
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -0500856 android.BazelModuleBase
Colin Crossfabb6082018-02-20 17:22:23 -0800857 prebuilt android.Prebuilt
858
Jooyung Hanacc7bbe2020-05-20 09:06:00 +0900859 // Functionality common to Module and Import.
860 embeddableInModuleAndImport
861
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500862 providesTransitiveHeaderJars
863
Colin Crossfabb6082018-02-20 17:22:23 -0800864 properties AARImportProperties
865
Colin Cross4eae06d2023-06-20 22:40:02 -0700866 classpathFile android.WritablePath
867 proguardFlags android.WritablePath
868 exportPackage android.WritablePath
869 transitiveAaptResourcePackages android.Paths
870 extraAaptPackagesFile android.WritablePath
871 manifest android.WritablePath
872 assetsPackage android.WritablePath
873 rTxt android.WritablePath
874 rJar android.WritablePath
Colin Cross66f78822018-05-02 12:58:28 -0700875
Colin Crossab8d1382023-07-14 17:23:41 +0000876 resourcesNodesDepSet *android.DepSet[*resourcesNode]
877 manifestsDepSet *android.DepSet[android.Path]
Colin Cross56a83212020-09-15 18:30:11 -0700878
879 hideApexVariantFromMake bool
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +0000880
Sam Delmerico82602492022-06-10 17:05:42 +0000881 aarPath android.Path
882 jniPackages android.Paths
Jiyong Park92315372021-04-02 08:45:46 +0900883
884 sdkVersion android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000885 minSdkVersion android.ApiLevel
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +0000886}
887
888var _ android.OutputFileProducer = (*AARImport)(nil)
889
890// For OutputFileProducer interface
891func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
892 switch tag {
893 case ".aar":
894 return []android.Path{a.aarPath}, nil
895 case "":
896 return []android.Path{a.classpathFile}, nil
897 default:
898 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
899 }
Colin Crossfabb6082018-02-20 17:22:23 -0800900}
901
Jiyong Park92315372021-04-02 08:45:46 +0900902func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
903 return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700904}
905
Jiyong Parkf1691d22021-03-29 20:11:58 +0900906func (a *AARImport) SystemModules() string {
Paul Duffine25c6442019-10-11 13:50:28 +0100907 return ""
908}
909
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000910func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
Colin Cross479884c2018-07-10 13:39:30 -0700911 if a.properties.Min_sdk_version != nil {
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000912 return android.ApiLevelFrom(ctx, *a.properties.Min_sdk_version)
Colin Cross479884c2018-07-10 13:39:30 -0700913 }
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000914 return a.SdkVersion(ctx).ApiLevel
Colin Cross83bb3162018-06-25 15:48:06 -0700915}
916
Spandan Dasa26eda72023-03-02 00:56:06 +0000917func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
918 return android.SdkSpecFrom(ctx, "").ApiLevel
William Loh5a082f92022-05-17 20:21:50 +0000919}
920
Spandan Dasca70fc42023-03-01 23:38:49 +0000921func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
922 return a.SdkVersion(ctx).ApiLevel
Dan Willemsen419290a2018-10-31 15:28:47 -0700923}
924
Colin Cross1e743852019-10-28 11:37:20 -0700925func (a *AARImport) javaVersion() string {
926 return ""
927}
928
Colin Crossa97c5d32018-03-28 14:58:31 -0700929var _ AndroidLibraryDependency = (*AARImport)(nil)
930
931func (a *AARImport) ExportPackage() android.Path {
932 return a.exportPackage
933}
Colin Cross89c31582018-04-30 15:55:11 -0700934func (a *AARImport) ExportedProguardFlagFiles() android.Paths {
935 return android.Paths{a.proguardFlags}
936}
937
Colin Crossab8d1382023-07-14 17:23:41 +0000938func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
939 return a.resourcesNodesDepSet
Colin Crossc1c37552019-01-31 11:42:41 -0800940}
941
Colin Crossab8d1382023-07-14 17:23:41 +0000942func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] {
943 return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil)
Colin Cross66f78822018-05-02 12:58:28 -0700944}
945
Colin Crossab8d1382023-07-14 17:23:41 +0000946func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] {
947 return a.manifestsDepSet
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800948}
949
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700950// RRO enforcement is not available on aar_import since its RRO dirs are not
951// exported.
952func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
953}
954
955// RRO enforcement is not available on aar_import since its RRO dirs are not
956// exported.
957func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
958 return false
959}
960
Colin Crossfabb6082018-02-20 17:22:23 -0800961func (a *AARImport) Prebuilt() *android.Prebuilt {
962 return &a.prebuilt
963}
964
965func (a *AARImport) Name() string {
966 return a.prebuilt.Name(a.ModuleBase.Name())
967}
968
Jiyong Park618922e2020-01-08 13:35:43 +0900969func (a *AARImport) JacocoReportClassesFile() android.Path {
970 return nil
971}
972
Colin Crossfabb6082018-02-20 17:22:23 -0800973func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
Jeongik Cha816a23a2020-07-08 01:09:23 +0900974 if !ctx.Config().AlwaysUsePrebuiltSdks() {
Jiyong Parkf1691d22021-03-29 20:11:58 +0900975 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Colin Crossa97c5d32018-03-28 14:58:31 -0700976 if sdkDep.useModule && sdkDep.frameworkResModule != "" {
Colin Cross42d48b72018-08-29 14:10:52 -0700977 ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
Colin Crossfabb6082018-02-20 17:22:23 -0800978 }
979 }
Colin Crossa97c5d32018-03-28 14:58:31 -0700980
Colin Cross42d48b72018-08-29 14:10:52 -0700981 ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
982 ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
Colin Crossfabb6082018-02-20 17:22:23 -0800983}
984
Sam Delmerico82602492022-06-10 17:05:42 +0000985type JniPackageInfo struct {
986 // List of zip files containing JNI libraries
987 // Zip files should have directory structure jni/<arch>/*.so
988 JniPackages android.Paths
989}
990
991var JniPackageProvider = blueprint.NewProvider(JniPackageInfo{})
992
993// Unzip an AAR and extract the JNI libs for $archString.
994var extractJNI = pctx.AndroidStaticRule("extractJNI",
995 blueprint.RuleParams{
996 Command: `rm -rf $out $outDir && touch $out && ` +
997 `unzip -qoDD -d $outDir $in "jni/${archString}/*" && ` +
998 `jni_files=$$(find $outDir/jni -type f) && ` +
999 // print error message if there are no JNI libs for this arch
1000 `[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` +
1001 `${config.SoongZipCmd} -o $out -P 'lib/${archString}' ` +
1002 `-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`,
1003 CommandDeps: []string{"${config.SoongZipCmd}"},
1004 },
1005 "outDir", "archString")
1006
Colin Crossfabb6082018-02-20 17:22:23 -08001007// 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 -07001008// 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 -08001009var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
1010 blueprint.RuleParams{
Dan Willemsen304cfec2019-05-28 14:49:06 -07001011 Command: `rm -rf $outDir && mkdir -p $outDir && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001012 `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001013 `${config.Zip2ZipCmd} -i $in -o $assetsPackage 'assets/**/*' && ` +
Colin Cross205e9112020-08-06 13:20:17 -07001014 `${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001015 CommandDeps: []string{"${config.MergeZipsCmd}", "${config.Zip2ZipCmd}"},
Colin Crossfabb6082018-02-20 17:22:23 -08001016 },
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001017 "outDir", "combinedClassesJar", "assetsPackage")
Colin Crossfabb6082018-02-20 17:22:23 -08001018
1019func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1020 if len(a.properties.Aars) != 1 {
1021 ctx.PropertyErrorf("aars", "exactly one aar is required")
1022 return
1023 }
1024
Jiyong Park92315372021-04-02 08:45:46 +09001025 a.sdkVersion = a.SdkVersion(ctx)
1026 a.minSdkVersion = a.MinSdkVersion(ctx)
1027
Colin Cross56a83212020-09-15 18:30:11 -07001028 a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
1029
Nan Zhang4c819fb2018-08-27 18:31:46 -07001030 aarName := ctx.ModuleName() + ".aar"
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001031 a.aarPath = android.PathForModuleSrc(ctx, a.properties.Aars[0])
1032
Colin Cross1001a792019-03-21 22:21:39 -07001033 if Bool(a.properties.Jetifier) {
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001034 inputFile := a.aarPath
1035 a.aarPath = android.PathForModuleOut(ctx, "jetifier", aarName)
1036 TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile)
Nan Zhang4c819fb2018-08-27 18:31:46 -07001037 }
Colin Crossfabb6082018-02-20 17:22:23 -08001038
1039 extractedAARDir := android.PathForModuleOut(ctx, "aar")
Colin Cross205e9112020-08-06 13:20:17 -07001040 a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
Colin Crossfabb6082018-02-20 17:22:23 -08001041 a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
Colin Cross10f7c4a2018-05-23 10:59:28 -07001042 a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
Colin Cross4eae06d2023-06-20 22:40:02 -07001043 aarRTxt := extractedAARDir.Join(ctx, "R.txt")
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001044 a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
Colin Crossfabb6082018-02-20 17:22:23 -08001045
1046 ctx.Build(pctx, android.BuildParams{
1047 Rule: unzipAAR,
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001048 Input: a.aarPath,
Colin Cross4eae06d2023-06-20 22:40:02 -07001049 Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt},
Colin Crossfabb6082018-02-20 17:22:23 -08001050 Description: "unzip AAR",
1051 Args: map[string]string{
Colin Cross205e9112020-08-06 13:20:17 -07001052 "outDir": extractedAARDir.String(),
1053 "combinedClassesJar": a.classpathFile.String(),
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001054 "assetsPackage": a.assetsPackage.String(),
Colin Crossfabb6082018-02-20 17:22:23 -08001055 },
1056 })
1057
Colin Crossa0ba2f52019-06-22 12:59:27 -07001058 // Always set --pseudo-localize, it will be stripped out later for release
1059 // builds that don't want it.
1060 compileFlags := []string{"--pseudo-localize"}
Colin Crossfabb6082018-02-20 17:22:23 -08001061 compiledResDir := android.PathForModuleOut(ctx, "flat-res")
Colin Crossfabb6082018-02-20 17:22:23 -08001062 flata := compiledResDir.Join(ctx, "gen_res.flata")
Saeid Farivar Asanjanf0436962020-10-05 19:09:09 +00001063 aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
Colin Crossfabb6082018-02-20 17:22:23 -08001064
1065 a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
Jiyong Parkb7c639e2019-08-19 14:56:02 +09001066 // the subdir "android" is required to be filtered by package names
1067 srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
Colin Crossfabb6082018-02-20 17:22:23 -08001068 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
Colin Cross4eae06d2023-06-20 22:40:02 -07001069 a.rTxt = android.PathForModuleOut(ctx, "R.txt")
Colin Cross66f78822018-05-02 12:58:28 -07001070 a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
Colin Crossfabb6082018-02-20 17:22:23 -08001071
1072 var linkDeps android.Paths
1073
1074 linkFlags := []string{
1075 "--static-lib",
Colin Cross4eae06d2023-06-20 22:40:02 -07001076 "--merge-only",
Colin Crossfabb6082018-02-20 17:22:23 -08001077 "--auto-add-overlay",
1078 }
1079
Colin Cross10f7c4a2018-05-23 10:59:28 -07001080 linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
1081 linkDeps = append(linkDeps, a.manifest)
Colin Crossfabb6082018-02-20 17:22:23 -08001082
Colin Crossab8d1382023-07-14 17:23:41 +00001083 staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
Jiyong Parkf1691d22021-03-29 20:11:58 +09001084 aaptLibs(ctx, android.SdkContext(a), nil)
Colin Cross31656952018-05-24 16:11:20 -07001085
Colin Crossab8d1382023-07-14 17:23:41 +00001086 _ = staticRRODirsDepSet
1087 staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
Colin Crossfabb6082018-02-20 17:22:23 -08001088
Colin Crossab8d1382023-07-14 17:23:41 +00001089 linkDeps = append(linkDeps, sharedLibs...)
Colin Cross4eae06d2023-06-20 22:40:02 -07001090 linkDeps = append(linkDeps, staticDeps.resPackages()...)
Colin Crossa97c5d32018-03-28 14:58:31 -07001091 linkFlags = append(linkFlags, libFlags...)
Colin Crossfabb6082018-02-20 17:22:23 -08001092
Colin Cross4eae06d2023-06-20 22:40:02 -07001093 overlayRes := android.Paths{flata}
1094
1095 // Treat static library dependencies of static libraries as imports.
1096 transitiveStaticLibs := staticDeps.resPackages()
1097 linkDeps = append(linkDeps, transitiveStaticLibs...)
1098 for _, staticLib := range transitiveStaticLibs {
1099 linkFlags = append(linkFlags, "-I "+staticLib.String())
1100 }
Colin Crossfabb6082018-02-20 17:22:23 -08001101
Colin Crossab8d1382023-07-14 17:23:41 +00001102 transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
Colin Cross4eae06d2023-06-20 22:40:02 -07001103 aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile,
Jaewoong Jung6431ca72020-01-15 14:15:10 -08001104 linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001105
Colin Cross4eae06d2023-06-20 22:40:02 -07001106 a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
1107 resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
1108
Colin Crossab8d1382023-07-14 17:23:41 +00001109 resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
1110 resourcesNodesDepSetBuilder.Direct(&resourcesNode{
1111 resPackage: a.exportPackage,
1112 manifest: a.manifest,
Colin Cross4eae06d2023-06-20 22:40:02 -07001113 rTxt: a.rTxt,
1114 rJar: a.rJar,
Colin Crossab8d1382023-07-14 17:23:41 +00001115 assets: android.OptionalPathForPath(a.assetsPackage),
Colin Cross4eae06d2023-06-20 22:40:02 -07001116
1117 usedResourceProcessor: true,
Colin Crossab8d1382023-07-14 17:23:41 +00001118 })
1119 resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
1120 a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
1121
1122 manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
1123 // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
1124 // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
1125 // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
1126 // android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped
1127 // completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest
1128 //manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests)
1129 _ = staticManifestsDepSet
1130 a.manifestsDepSet = manifestDepSetBuilder.Build()
Michael Rosenfeld5ad15572021-12-03 13:25:10 -08001131
Colin Cross4eae06d2023-06-20 22:40:02 -07001132 a.transitiveAaptResourcePackages = staticDeps.resPackages()
1133
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001134 a.collectTransitiveHeaderJars(ctx)
Colin Crossdcf71b22021-02-01 13:59:03 -08001135 ctx.SetProvider(JavaInfoProvider, JavaInfo{
1136 HeaderJars: android.PathsIfNonNil(a.classpathFile),
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001137 TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
1138 TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
Colin Crossdcf71b22021-02-01 13:59:03 -08001139 ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
1140 ImplementationJars: android.PathsIfNonNil(a.classpathFile),
Joe Onorato6fe59eb2023-07-16 13:20:33 -07001141 // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
Colin Crossdcf71b22021-02-01 13:59:03 -08001142 })
Sam Delmerico82602492022-06-10 17:05:42 +00001143
1144 if proptools.Bool(a.properties.Extract_jni) {
1145 for _, t := range ctx.MultiTargets() {
1146 arch := t.Arch.Abi[0]
1147 path := android.PathForModuleOut(ctx, arch+"_jni.zip")
1148 a.jniPackages = append(a.jniPackages, path)
1149
1150 outDir := android.PathForModuleOut(ctx, "aarForJni")
1151 aarPath := android.PathForModuleSrc(ctx, a.properties.Aars[0])
1152 ctx.Build(pctx, android.BuildParams{
1153 Rule: extractJNI,
1154 Input: aarPath,
1155 Outputs: android.WritablePaths{path},
1156 Description: "extract JNI from AAR",
1157 Args: map[string]string{
1158 "outDir": outDir.String(),
1159 "archString": arch,
1160 },
1161 })
1162 }
1163
1164 ctx.SetProvider(JniPackageProvider, JniPackageInfo{
1165 JniPackages: a.jniPackages,
1166 })
1167 }
Colin Crossdcf71b22021-02-01 13:59:03 -08001168}
Colin Crossfabb6082018-02-20 17:22:23 -08001169
1170func (a *AARImport) HeaderJars() android.Paths {
1171 return android.Paths{a.classpathFile}
1172}
1173
Colin Cross331a1212018-08-15 20:40:52 -07001174func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
1175 return android.Paths{a.classpathFile}
1176}
1177
Ulyana Trafimovich5539e7b2020-06-04 14:08:17 +00001178func (a *AARImport) DexJarBuildPath() android.Path {
Colin Crossf24a22a2019-01-31 14:12:44 -08001179 return nil
1180}
1181
Ulya Trafimovich9f3052c2020-06-09 14:31:19 +01001182func (a *AARImport) DexJarInstallPath() android.Path {
1183 return nil
1184}
1185
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +01001186func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
Jiyong Park1be96912018-05-28 18:02:19 +09001187 return nil
1188}
1189
Jiyong Park45bf82e2020-12-15 22:29:02 +09001190var _ android.ApexModule = (*AARImport)(nil)
1191
1192// Implements android.ApexModule
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001193func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1194 return a.depIsInSameApex(ctx, dep)
1195}
1196
Jiyong Park45bf82e2020-12-15 22:29:02 +09001197// Implements android.ApexModule
Dan Albertc8060532020-07-22 22:32:17 -07001198func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
1199 sdkVersion android.ApiLevel) error {
Jooyung Han749dc692020-04-15 11:03:39 +09001200 return nil
1201}
1202
Sam Delmericoaf8bb702022-07-25 15:39:32 -04001203var _ android.PrebuiltInterface = (*AARImport)(nil)
Colin Crossfabb6082018-02-20 17:22:23 -08001204
Colin Cross1b16b0e2019-02-12 14:41:32 -08001205// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
1206//
1207// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
1208// an android_app module.
Colin Crossfabb6082018-02-20 17:22:23 -08001209func AARImportFactory() android.Module {
1210 module := &AARImport{}
1211
1212 module.AddProperties(&module.properties)
1213
1214 android.InitPrebuiltModule(module, &module.properties.Aars)
Jooyung Hanacc7bbe2020-05-20 09:06:00 +09001215 android.InitApexModule(module)
Sam Delmerico82602492022-06-10 17:05:42 +00001216 InitJavaModuleMultiTargets(module, android.DeviceSupported)
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001217 android.InitBazelModule(module)
Colin Crossfabb6082018-02-20 17:22:23 -08001218 return module
1219}
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001220
1221type bazelAapt struct {
1222 Manifest bazel.Label
1223 Resource_files bazel.LabelListAttribute
1224}
1225
1226type bazelAndroidLibrary struct {
1227 *javaLibraryAttributes
1228 *bazelAapt
1229}
1230
1231type bazelAndroidLibraryImport struct {
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001232 Aar bazel.Label
1233 Deps bazel.LabelListAttribute
1234 Exports bazel.LabelListAttribute
1235 Sdk_version bazel.StringAttribute
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001236}
1237
1238func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt {
1239 manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
1240
1241 resourceFiles := bazel.LabelList{
1242 Includes: []bazel.Label{},
1243 }
1244 for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
1245 files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
1246 resourceFiles.Includes = append(resourceFiles.Includes, files...)
1247 }
1248 return &bazelAapt{
1249 android.BazelLabelForModuleSrcSingle(ctx, manifest),
1250 bazel.MakeLabelListAttribute(resourceFiles),
1251 }
1252}
1253
1254func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
1255 aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{})
1256 exportableStaticLibs := []string{}
1257 // TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel.
1258 for _, depName := range a.properties.Static_libs {
1259 if dep, ok := ctx.ModuleFromName(depName); ok {
1260 switch dep.(type) {
1261 case *AARImport, *Import:
1262 exportableStaticLibs = append(exportableStaticLibs, depName)
1263 }
1264 }
1265 }
1266 name := android.RemoveOptionalPrebuiltPrefix(a.Name())
1267 deps := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(append(a.properties.Static_libs, a.properties.Libs...))))
1268 exports := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(exportableStaticLibs))
1269
1270 ctx.CreateBazelTargetModule(
1271 bazel.BazelTargetModuleProperties{
1272 Rule_class: "aar_import",
Alixa381cd12023-05-10 14:49:38 +00001273 Bzl_load_location: "//build/bazel/rules/android:aar_import.bzl",
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001274 },
1275 android.CommonAttributes{Name: name},
1276 &bazelAndroidLibraryImport{
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001277 Aar: aars.Includes[0],
1278 Deps: bazel.MakeLabelListAttribute(deps),
1279 Exports: bazel.MakeLabelListAttribute(exports),
1280 Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version},
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001281 },
1282 )
1283
Alix14101de2023-01-06 03:42:07 +00001284 neverlink := true
1285 ctx.CreateBazelTargetModule(
Alix32540022023-03-16 21:06:13 +00001286 AndroidLibraryBazelTargetModuleProperties(),
Alix14101de2023-01-06 03:42:07 +00001287 android.CommonAttributes{Name: name + "-neverlink"},
1288 &bazelAndroidLibrary{
1289 javaLibraryAttributes: &javaLibraryAttributes{
1290 Neverlink: bazel.BoolAttribute{Value: &neverlink},
1291 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}),
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001292 javaCommonAttributes: &javaCommonAttributes{
1293 Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version},
1294 },
Alix14101de2023-01-06 03:42:07 +00001295 },
1296 },
1297 )
1298
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001299}
Alix32540022023-03-16 21:06:13 +00001300func AndroidLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties {
1301 return bazel.BazelTargetModuleProperties{
1302 Rule_class: "android_library",
Alixa381cd12023-05-10 14:49:38 +00001303 Bzl_load_location: "//build/bazel/rules/android:android_library.bzl",
Alix32540022023-03-16 21:06:13 +00001304 }
1305}
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001306
1307func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Liz Kammer7f375862023-08-04 16:37:42 -04001308 commonAttrs, bp2buildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
1309 if !supported {
1310 return
1311 }
1312
Alix8062f4d2022-11-14 21:38:07 +00001313 depLabels := bp2buildInfo.DepLabels
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001314
1315 deps := depLabels.Deps
1316 if !commonAttrs.Srcs.IsEmpty() {
1317 deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
1318 } else if !depLabels.Deps.IsEmpty() {
1319 ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
1320 }
Alix82fb94e2022-10-26 20:40:18 +00001321 name := a.Name()
Alix32540022023-03-16 21:06:13 +00001322 props := AndroidLibraryBazelTargetModuleProperties()
Alix82fb94e2022-10-26 20:40:18 +00001323
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001324 ctx.CreateBazelTargetModule(
Alix82fb94e2022-10-26 20:40:18 +00001325 props,
1326 android.CommonAttributes{Name: name},
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001327 &bazelAndroidLibrary{
1328 &javaLibraryAttributes{
1329 javaCommonAttributes: commonAttrs,
1330 Deps: deps,
1331 Exports: depLabels.StaticDeps,
1332 },
1333 a.convertAaptAttrsWithBp2Build(ctx),
1334 },
1335 )
Alix82fb94e2022-10-26 20:40:18 +00001336
1337 neverlink := true
1338 ctx.CreateBazelTargetModule(
1339 props,
1340 android.CommonAttributes{Name: name + "-neverlink"},
1341 &bazelAndroidLibrary{
1342 javaLibraryAttributes: &javaLibraryAttributes{
1343 Neverlink: bazel.BoolAttribute{Value: &neverlink},
1344 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}),
Romain Jobredeaux2eef2e12023-02-24 12:07:08 -05001345 javaCommonAttributes: &javaCommonAttributes{
1346 Sdk_version: bazel.StringAttribute{Value: a.deviceProperties.Sdk_version},
1347 Java_version: bazel.StringAttribute{Value: a.properties.Java_version},
1348 },
Alix82fb94e2022-10-26 20:40:18 +00001349 },
1350 },
1351 )
Romain Jobredeauxc9b2bba2022-02-15 09:35:07 -05001352}