Merge "Move android_library resource handling to Bazel's ResourceProcessorBusyBox" into main

This commit is contained in:
Treehugger Robot
2023-07-26 00:34:57 +00:00
committed by Gerrit Code Review
7 changed files with 486 additions and 63 deletions

View File

@@ -88,16 +88,28 @@ type aaptProperties struct {
// do not include AndroidManifest from dependent libraries
Dont_merge_manifests *bool
// If use_resource_processor is set, use Bazel's resource processor instead of aapt2 to generate R.class files.
// The resource processor produces more optimal R.class files that only list resources in the package of the
// library that provided them, as opposed to aapt2 which produces R.java files for every package containing
// every resource. Using the resource processor can provide significant build time speedups, but requires
// fixing the module to use the correct package to reference each resource, and to avoid having any other
// libraries in the tree that use the same package name. Defaults to false, but will default to true in the
// future.
Use_resource_processor *bool
// true if RRO is enforced for any of the dependent modules
RROEnforcedForDependent bool `blueprint:"mutated"`
}
type aapt struct {
aaptSrcJar android.Path
transitiveAaptRJars android.Paths
transitiveAaptResourcePackages android.Paths
exportPackage android.Path
manifestPath android.Path
proguardOptionsFile android.Path
rTxt android.Path
rJar android.Path
extraAaptPackagesFile android.Path
mergedManifestFile android.Path
noticeFile android.OptionalPath
@@ -139,6 +151,10 @@ func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
}
}
func (a *aapt) useResourceProcessorBusyBox() bool {
return BoolDefault(a.aaptProperties.Use_resource_processor, false)
}
func (a *aapt) ExportPackage() android.Path {
return a.exportPackage
}
@@ -175,8 +191,6 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte
// Flags specified in Android.bp
linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
linkFlags = append(linkFlags, "--no-static-lib-packages")
// Find implicit or explicit asset and resource dirs
assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
@@ -348,6 +362,19 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
linkFlags = append(linkFlags, "--static-lib")
}
if a.isLibrary && a.useResourceProcessorBusyBox() {
// When building an android_library using ResourceProcessorBusyBox the resources are merged into
// package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
// contains resources from this library.
linkFlags = append(linkFlags, "--merge-only")
} else {
// When building and app or when building an android_library without ResourceProcessorBusyBox
// --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
// is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
// sort resources into the right packages in R.class.
linkFlags = append(linkFlags, "--no-static-lib-packages")
}
packageRes := android.PathForModuleOut(ctx, "package-res.apk")
// the subdir "android" is required to be filtered by package names
srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
@@ -355,6 +382,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
rTxt := android.PathForModuleOut(ctx, "R.txt")
// This file isn't used by Soong, but is generated for exporting
extraPackages := android.PathForModuleOut(ctx, "extra_packages")
var transitiveRJars android.Paths
var compiledResDirs []android.Paths
for _, dir := range resDirs {
@@ -374,7 +402,23 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
// of transitiveStaticLibs.
transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
if a.isLibrary && a.useResourceProcessorBusyBox() {
// When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
// as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
// instead modules depending on this module will reference package-res.apk from all transitive static
// dependencies.
for _, staticDep := range staticDeps {
linkDeps = append(linkDeps, staticDep.resPackage)
linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
if staticDep.usedResourceProcessor {
transitiveRJars = append(transitiveRJars, staticDep.rJar)
}
}
} else {
// When building an app or building a library without ResourceProcessorBusyBox enabled all static
// dependencies are compiled into this module's package-res.apk as overlays.
compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
}
if len(transitiveStaticLibs) > 0 {
// If we are using static android libraries, every source file becomes an overlay.
@@ -437,7 +481,16 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
a.assetPackage = android.OptionalPathForPath(assets)
}
if a.useResourceProcessorBusyBox() {
rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
transitiveRJars = append(transitiveRJars, rJar)
a.rJar = rJar
}
a.aaptSrcJar = srcJar
a.transitiveAaptRJars = transitiveRJars
a.transitiveAaptResourcePackages = staticDeps.resPackages()
a.exportPackage = packageRes
a.manifestPath = manifestPath
a.proguardOptionsFile = proguardOptionsFile
@@ -449,7 +502,11 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
resPackage: a.exportPackage,
manifest: a.manifestPath,
additionalManifests: additionalManifests,
rTxt: a.rTxt,
rJar: a.rJar,
assets: a.assetPackage,
usedResourceProcessor: a.useResourceProcessorBusyBox(),
}).
Transitive(staticResourcesNodesDepSet).Build()
a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
@@ -461,34 +518,93 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
Transitive(staticManifestsDepSet).Build()
}
var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
blueprint.RuleParams{
Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
"com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
"if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
Rspfile: "${out}.args",
RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
Restat: true,
}, "rTxt", "manifest", "args")
// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
// supports producing classes for static dependencies that only include resources from that dependency.
func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) {
var args []string
var deps android.Paths
if !isLibrary {
// When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
// to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
// package.
args, deps = transitiveDeps.resourceProcessorDeps()
} else {
// When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
// library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
// inlined into the library before the final IDs are assigned during app compilation.
args = append(args, "--finalFields=false")
}
deps = append(deps, rTxt, manifest)
ctx.Build(pctx, android.BuildParams{
Rule: resourceProcessorBusyBox,
Output: rJar,
Implicits: deps,
Description: "ResourceProcessorBusyBox",
Args: map[string]string{
"rTxt": rTxt.String(),
"manifest": manifest.String(),
"args": strings.Join(args, " "),
},
})
}
type resourcesNode struct {
resPackage android.Path
manifest android.Path
additionalManifests android.Paths
rTxt android.Path
rJar android.Path
assets android.OptionalPath
usedResourceProcessor bool
}
type transitiveAarDeps []*resourcesNode
func (t transitiveAarDeps) resPackages() android.Paths {
var paths android.Paths
paths := make(android.Paths, 0, len(t))
for _, dep := range t {
paths = append(paths, dep.resPackage)
}
return android.FirstUniquePaths(paths)
return paths
}
func (t transitiveAarDeps) manifests() android.Paths {
var paths android.Paths
paths := make(android.Paths, 0, len(t))
for _, dep := range t {
paths = append(paths, dep.manifest)
paths = append(paths, dep.additionalManifests...)
}
return android.FirstUniquePaths(paths)
return paths
}
func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
for _, dep := range t {
args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
deps = append(deps, dep.rTxt, dep.manifest)
}
return args, deps
}
func (t transitiveAarDeps) assets() android.Paths {
var paths android.Paths
paths := make(android.Paths, 0, len(t))
for _, dep := range t {
if dep.assets.Valid() {
paths = append(paths, dep.assets.Path())
@@ -613,9 +729,12 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
ctx.CheckbuildFile(a.proguardOptionsFile)
ctx.CheckbuildFile(a.exportPackage)
ctx.CheckbuildFile(a.aaptSrcJar)
ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
ctx.CheckbuildFile(a.aapt.exportPackage)
ctx.CheckbuildFile(a.aapt.aaptSrcJar)
if a.useResourceProcessorBusyBox() {
ctx.CheckbuildFile(a.aapt.rJar)
}
// apps manifests are handled by aapt, don't let Module see them
a.properties.Manifest = nil
@@ -627,7 +746,22 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
a.proguardOptionsFile)
a.Module.compile(ctx, a.aaptSrcJar)
var extraSrcJars android.Paths
var extraCombinedJars android.Paths
var extraClasspathJars android.Paths
if a.useResourceProcessorBusyBox() {
// When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
// library and each of the transitive static android_library dependencies has already created an
// R.class file for the appropriate package. Add all of those R.class files to the classpath.
extraClasspathJars = a.transitiveAaptRJars
} else {
// When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
// R.java files for the library's package and the packages from all transitive static android_library
// dependencies. Compile the srcjar alongside the rest of the sources.
extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
}
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
var res android.Paths
@@ -732,9 +866,12 @@ type AARImport struct {
classpathFile android.WritablePath
proguardFlags android.WritablePath
exportPackage android.WritablePath
transitiveAaptResourcePackages android.Paths
extraAaptPackagesFile android.WritablePath
manifest android.WritablePath
assetsPackage android.WritablePath
rTxt android.WritablePath
rJar android.WritablePath
resourcesNodesDepSet *android.DepSet[*resourcesNode]
manifestsDepSet *android.DepSet[android.Path]
@@ -903,12 +1040,13 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
aarRTxt := extractedAARDir.Join(ctx, "R.txt")
a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
ctx.Build(pctx, android.BuildParams{
Rule: unzipAAR,
Input: a.aarPath,
Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage},
Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt},
Description: "unzip AAR",
Args: map[string]string{
"outDir": extractedAARDir.String(),
@@ -928,14 +1066,14 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// the subdir "android" is required to be filtered by package names
srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
rTxt := android.PathForModuleOut(ctx, "R.txt")
a.rTxt = android.PathForModuleOut(ctx, "R.txt")
a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
var linkDeps android.Paths
linkFlags := []string{
"--static-lib",
"--no-static-lib-packages",
"--merge-only",
"--auto-add-overlay",
}
@@ -948,25 +1086,35 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
_ = staticRRODirsDepSet
staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
// AAPT2 overlays are in lowest to highest priority order, reverse the topological order
// of transitiveStaticLibs.
transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
linkDeps = append(linkDeps, sharedLibs...)
linkDeps = append(linkDeps, transitiveStaticLibs...)
linkDeps = append(linkDeps, staticDeps.resPackages()...)
linkFlags = append(linkFlags, libFlags...)
overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
overlayRes := android.Paths{flata}
// Treat static library dependencies of static libraries as imports.
transitiveStaticLibs := staticDeps.resPackages()
linkDeps = append(linkDeps, transitiveStaticLibs...)
for _, staticLib := range transitiveStaticLibs {
linkFlags = append(linkFlags, "-I "+staticLib.String())
}
transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile,
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
resourcesNodesDepSetBuilder.Direct(&resourcesNode{
resPackage: a.exportPackage,
manifest: a.manifest,
rTxt: a.rTxt,
rJar: a.rJar,
assets: android.OptionalPathForPath(a.assetsPackage),
usedResourceProcessor: true,
})
resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
@@ -981,6 +1129,8 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
_ = staticManifestsDepSet
a.manifestsDepSet = manifestDepSetBuilder.Build()
a.transitiveAaptResourcePackages = staticDeps.resPackages()
a.collectTransitiveHeaderJars(ctx)
ctx.SetProvider(JavaInfoProvider, JavaInfo{
HeaderJars: android.PathsIfNonNil(a.classpathFile),

View File

@@ -269,6 +269,7 @@ func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.classpathFile)
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.classpathFile)
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", prebuilt.exportPackage)
entries.SetPaths("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", prebuilt.transitiveAaptResourcePackages)
entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags)
entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", prebuilt.extraAaptPackagesFile)
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", prebuilt.manifest)
@@ -521,6 +522,7 @@ func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries {
}
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", a.exportPackage)
entries.SetPaths("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", a.transitiveAaptResourcePackages)
entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", a.extraAaptPackagesFile)
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", a.mergedManifestFile)
entries.AddStrings("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.exportedProguardFlagFiles.Strings()...)

View File

@@ -521,7 +521,23 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
if ctx.ModuleName() != "framework-res" {
a.Module.compile(ctx, a.aaptSrcJar)
var extraSrcJars android.Paths
var extraClasspathJars android.Paths
var extraCombinedJars android.Paths
if a.useResourceProcessorBusyBox() {
// When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
// created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
// classpath when compiling everything else, and add it to the final classes jar.
extraClasspathJars = android.Paths{a.aapt.rJar}
extraCombinedJars = android.Paths{a.aapt.rJar}
} else {
// When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
// R.java files for the app's package and the packages from all transitive static android_library
// dependencies. Compile the srcjar alongside the rest of the sources.
extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
}
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
}
return a.dexJarFile.PathOrNil()

View File

@@ -723,6 +723,9 @@ func TestAppJavaResources(t *testing.T) {
func TestAndroidResourceProcessor(t *testing.T) {
testCases := []struct {
name string
appUsesRP bool
directLibUsesRP bool
transitiveLibUsesRP bool
dontVerifyApp bool
appResources []string
@@ -759,7 +762,12 @@ func TestAndroidResourceProcessor(t *testing.T) {
transitiveImportImports []string
}{
{
// Test with all modules set to use_resource_processor: false (except android_library_import modules,
// which always use resource processor).
name: "legacy",
appUsesRP: false,
directLibUsesRP: false,
transitiveLibUsesRP: false,
appResources: nil,
appOverlays: []string{
@@ -771,7 +779,6 @@ func TestAndroidResourceProcessor(t *testing.T) {
"out/soong/.intermediates/direct_import/android_common/package-res.apk",
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
},
appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
@@ -792,7 +799,6 @@ func TestAndroidResourceProcessor(t *testing.T) {
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat",
},
directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
directClasspath: []string{
@@ -814,18 +820,256 @@ func TestAndroidResourceProcessor(t *testing.T) {
transitiveCombined: nil,
directImportResources: nil,
directImportOverlays: []string{
"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata",
directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"},
directImportImports: []string{
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
},
directImportImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveImportResources: nil,
transitiveImportOverlays: []string{
"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata",
transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"},
transitiveImportImports: []string{
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
},
transitiveImportImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
},
{
// Test with all modules set to use_resource_processor: true.
name: "resource_processor",
appUsesRP: true,
directLibUsesRP: true,
transitiveLibUsesRP: true,
appResources: nil,
appOverlays: []string{
"out/soong/.intermediates/transitive/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/direct/android_common/package-res.apk",
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/direct_import/android_common/package-res.apk",
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
},
appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
appSrcJars: nil,
appClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
directResources: nil,
directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"},
directImports: []string{
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/transitive/android_common/package-res.apk",
},
directSrcJars: nil,
directClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
transitiveOverlays: nil,
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: nil,
transitiveClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
},
transitiveCombined: nil,
directImportResources: nil,
directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"},
directImportImports: []string{
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
},
transitiveImportResources: nil,
transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"},
transitiveImportImports: []string{
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
},
}, {
// Test an app building with resource processor enabled but with dependencies built without
// resource processor.
name: "app_resource_processor",
appUsesRP: true,
directLibUsesRP: false,
transitiveLibUsesRP: false,
appResources: nil,
appOverlays: []string{
"out/soong/.intermediates/transitive/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/direct/android_common/package-res.apk",
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/direct_import/android_common/package-res.apk",
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
},
appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
appSrcJars: nil,
appClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
// R.jar has to come before direct.jar
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
dontVerifyDirect: true,
dontVerifyTransitive: true,
dontVerifyDirectImport: true,
dontVerifyTransitiveImport: true,
},
{
// Test an app building without resource processor enabled but with a dependency built with
// resource processor.
name: "app_dependency_lib_resource_processor",
appUsesRP: false,
directLibUsesRP: true,
transitiveLibUsesRP: false,
appOverlays: []string{
"out/soong/.intermediates/transitive/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/direct/android_common/package-res.apk",
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/direct_import/android_common/package-res.apk",
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
},
appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
directResources: nil,
directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"},
directImports: []string{
"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/transitive/android_common/package-res.apk",
},
directSrcJars: nil,
directClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
dontVerifyTransitive: true,
dontVerifyDirectImport: true,
dontVerifyTransitiveImport: true,
},
{
// Test a library building without resource processor enabled but with a dependency built with
// resource processor.
name: "lib_dependency_lib_resource_processor",
appUsesRP: false,
directLibUsesRP: false,
transitiveLibUsesRP: true,
appOverlays: []string{
"out/soong/.intermediates/transitive/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/direct/android_common/package-res.apk",
"out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/direct_import/android_common/package-res.apk",
"out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
},
appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
},
directResources: nil,
directOverlays: []string{
"out/soong/.intermediates/transitive/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
"out/soong/.intermediates/transitive_import/android_common/package-res.apk",
"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat",
},
directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
directClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
transitiveOverlays: nil,
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: nil,
transitiveClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
},
transitiveCombined: nil,
dontVerifyDirectImport: true,
dontVerifyTransitiveImport: true,
},
}
@@ -839,6 +1083,7 @@ func TestAndroidResourceProcessor(t *testing.T) {
resource_dirs: ["app/res"],
manifest: "app/AndroidManifest.xml",
static_libs: ["direct", "direct_import"],
use_resource_processor: %v,
}
android_library {
@@ -848,6 +1093,7 @@ func TestAndroidResourceProcessor(t *testing.T) {
resource_dirs: ["direct/res"],
manifest: "direct/AndroidManifest.xml",
static_libs: ["transitive", "transitive_import"],
use_resource_processor: %v,
}
android_library {
@@ -856,6 +1102,7 @@ func TestAndroidResourceProcessor(t *testing.T) {
srcs: ["transitive/transitive.java"],
resource_dirs: ["transitive/res"],
manifest: "transitive/AndroidManifest.xml",
use_resource_processor: %v,
}
android_library_import {
@@ -883,7 +1130,7 @@ func TestAndroidResourceProcessor(t *testing.T) {
sdk_version: "current",
aars: ["transitive_import_dep.aar"],
}
`)
`, testCase.appUsesRP, testCase.directLibUsesRP, testCase.transitiveLibUsesRP)
fs := android.MockFS{
"app/res/values/strings.xml": nil,

View File

@@ -1065,7 +1065,7 @@ func (module *Module) addGeneratedSrcJars(path android.Path) {
module.properties.Generated_srcjars = append(module.properties.Generated_srcjars, path)
}
func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) {
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
deps := j.collectDeps(ctx)
@@ -1103,9 +1103,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
srcJars := srcFiles.FilterByExt(".srcjar")
srcJars = append(srcJars, deps.srcJars...)
if aaptSrcJar != nil {
srcJars = append(srcJars, aaptSrcJar)
}
srcJars = append(srcJars, extraSrcJars...)
srcJars = append(srcJars, j.properties.Generated_srcjars...)
srcFiles = srcFiles.FilterOutByExt(".srcjar")
@@ -1148,6 +1146,11 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
var kotlinJars android.Paths
var kotlinHeaderJars android.Paths
// Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
// any dependencies so that it can override any non-final R classes from dependencies with the
// final R classes from the app.
flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
if srcFiles.HasExt(".kt") {
// When using kotlin sources turbine is used to generate annotation processor sources,
// including for annotation processors that generate API, so we can use turbine for
@@ -1241,8 +1244,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// allow for the use of annotation processors that do function correctly
// with sharding enabled. See: b/77284273.
}
extraJars := append(android.CopyOf(extraCombinedJars), kotlinHeaderJars...)
headerJarFileWithoutDepsOrJarjar, j.headerJarFile =
j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars)
j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
if ctx.Failed() {
return
}
@@ -1393,6 +1397,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
jars = append(jars, servicesJar)
}
jars = append(android.CopyOf(extraCombinedJars), jars...)
// Combine the classes built from sources, any manifests, and any static libraries into
// classes.jar. If there is only one input jar this step will be skipped.
var outputFile android.OutputPath

View File

@@ -148,6 +148,8 @@ func init() {
pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar")
pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
pctx.SourcePathVariable("ResourceProcessorBusyBox", "prebuilts/bazel/common/android_tools/android_tools/all_android_tools_deploy.jar")
pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file")
pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")

View File

@@ -699,7 +699,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
}
j.compile(ctx, nil)
j.compile(ctx, nil, nil, nil)
// Collect the module directory for IDE info in java/jdeps.go.
j.modulePaths = append(j.modulePaths, ctx.ModuleDir())