Propagate flags_packages to static reverse dependencies
flags_packages property was added to supports flagging the manifest files. The listed names of `aconfig_declarations` modules are passed to aapt2. However, this is currently scoped to the module level, and is not propagated to the reverse dependencies. In other words, if the manifest is flagged with `featureFlag` property, all of the reverse dependency of the android_app/android_library should specify `flags_packages` property in the bp module definition, leading to huge toil for the users. In order to resolve such inconvenience, this change modifies the build rules of android_app,android_library and runtime_resource_overlay such that flags_packages of the static dependencies are collected. Test: Patch ag/27816261 && m Settings --no-skip-soong-tests Bug: 347289274 Change-Id: I4c3855541dd09cb72293515eb2626eaf4ae8c0df
This commit is contained in:
@@ -831,12 +831,13 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
|
|||||||
if a.usesLibrary.shouldDisableDexpreopt {
|
if a.usesLibrary.shouldDisableDexpreopt {
|
||||||
a.dexpreopter.disableDexpreopt()
|
a.dexpreopter.disableDexpreopt()
|
||||||
}
|
}
|
||||||
|
aconfigTextFilePaths := getAconfigFilePaths(ctx)
|
||||||
a.aapt.buildActions(ctx,
|
a.aapt.buildActions(ctx,
|
||||||
aaptBuildActionOptions{
|
aaptBuildActionOptions{
|
||||||
sdkContext: android.SdkContext(a),
|
sdkContext: android.SdkContext(a),
|
||||||
classLoaderContexts: a.classLoaderContexts,
|
classLoaderContexts: a.classLoaderContexts,
|
||||||
enforceDefaultTargetSdkVersion: false,
|
enforceDefaultTargetSdkVersion: false,
|
||||||
aconfigTextFiles: getAconfigFilePaths(ctx),
|
aconfigTextFiles: aconfigTextFilePaths,
|
||||||
usesLibrary: &a.usesLibrary,
|
usesLibrary: &a.usesLibrary,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -906,6 +907,10 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
|
|||||||
JniPackages: prebuiltJniPackages,
|
JniPackages: prebuiltJniPackages,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
|
||||||
|
AconfigTextFiles: aconfigTextFilePaths,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) {
|
func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) {
|
||||||
|
43
java/app.go
43
java/app.go
@@ -47,6 +47,13 @@ var (
|
|||||||
}, "packageName")
|
}, "packageName")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FlagsPackages struct {
|
||||||
|
// Paths to the aconfig dump output text files that are consumed by aapt2
|
||||||
|
AconfigTextFiles android.Paths
|
||||||
|
}
|
||||||
|
|
||||||
|
var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
|
||||||
|
|
||||||
func RegisterAppBuildComponents(ctx android.RegistrationContext) {
|
func RegisterAppBuildComponents(ctx android.RegistrationContext) {
|
||||||
ctx.RegisterModuleType("android_app", AndroidAppFactory)
|
ctx.RegisterModuleType("android_app", AndroidAppFactory)
|
||||||
ctx.RegisterModuleType("android_test", AndroidTestFactory)
|
ctx.RegisterModuleType("android_test", AndroidTestFactory)
|
||||||
@@ -478,18 +485,27 @@ func (a *AndroidApp) renameResourcesPackage() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
|
func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
|
||||||
ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
|
tag := ctx.OtherModuleDependencyTag(dep)
|
||||||
aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
|
switch tag {
|
||||||
} else {
|
case staticLibTag:
|
||||||
ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
|
if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
|
||||||
"flags_packages property, but %s is not aconfig_declarations module type",
|
aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
|
||||||
dep.Name(),
|
}
|
||||||
)
|
|
||||||
|
case aconfigDeclarationTag:
|
||||||
|
if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
|
||||||
|
aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
|
||||||
|
} else {
|
||||||
|
ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
|
||||||
|
"flags_packages property, but %s is not aconfig_declarations module type",
|
||||||
|
dep.Name(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return aconfigTextFilePaths
|
return android.FirstUniquePaths(aconfigTextFilePaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
||||||
@@ -544,6 +560,9 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
// Use non final ids if we are doing optimized shrinking and are using R8.
|
// Use non final ids if we are doing optimized shrinking and are using R8.
|
||||||
nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
|
nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
|
||||||
|
|
||||||
|
aconfigTextFilePaths := getAconfigFilePaths(ctx)
|
||||||
|
|
||||||
a.aapt.buildActions(ctx,
|
a.aapt.buildActions(ctx,
|
||||||
aaptBuildActionOptions{
|
aaptBuildActionOptions{
|
||||||
sdkContext: android.SdkContext(a),
|
sdkContext: android.SdkContext(a),
|
||||||
@@ -552,13 +571,17 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
|||||||
enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
|
enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
|
||||||
forceNonFinalResourceIDs: nonFinalIds,
|
forceNonFinalResourceIDs: nonFinalIds,
|
||||||
extraLinkFlags: aaptLinkFlags,
|
extraLinkFlags: aaptLinkFlags,
|
||||||
aconfigTextFiles: getAconfigFilePaths(ctx),
|
aconfigTextFiles: aconfigTextFilePaths,
|
||||||
usesLibrary: &a.usesLibrary,
|
usesLibrary: &a.usesLibrary,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// apps manifests are handled by aapt, don't let Module see them
|
// apps manifests are handled by aapt, don't let Module see them
|
||||||
a.properties.Manifest = nil
|
a.properties.Manifest = nil
|
||||||
|
|
||||||
|
android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
|
||||||
|
AconfigTextFiles: aconfigTextFilePaths,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
|
func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
|
||||||
|
@@ -4369,6 +4369,82 @@ func TestAppFlagsPackages(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAppFlagsPackagesPropagation(t *testing.T) {
|
||||||
|
ctx := testApp(t, `
|
||||||
|
aconfig_declarations {
|
||||||
|
name: "foo",
|
||||||
|
package: "com.example.package.foo",
|
||||||
|
container: "com.android.foo",
|
||||||
|
srcs: [
|
||||||
|
"foo.aconfig",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
aconfig_declarations {
|
||||||
|
name: "bar",
|
||||||
|
package: "com.example.package.bar",
|
||||||
|
container: "com.android.bar",
|
||||||
|
srcs: [
|
||||||
|
"bar.aconfig",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
aconfig_declarations {
|
||||||
|
name: "baz",
|
||||||
|
package: "com.example.package.baz",
|
||||||
|
container: "com.android.baz",
|
||||||
|
srcs: [
|
||||||
|
"baz.aconfig",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
android_library {
|
||||||
|
name: "foo_lib",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
sdk_version: "current",
|
||||||
|
flags_packages: [
|
||||||
|
"foo",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
android_library {
|
||||||
|
name: "bar_lib",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
sdk_version: "current",
|
||||||
|
flags_packages: [
|
||||||
|
"bar",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
android_app {
|
||||||
|
name: "baz_app",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
sdk_version: "current",
|
||||||
|
flags_packages: [
|
||||||
|
"baz",
|
||||||
|
],
|
||||||
|
static_libs: [
|
||||||
|
"bar_lib",
|
||||||
|
],
|
||||||
|
libs: [
|
||||||
|
"foo_lib",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
bazApp := ctx.ModuleForTests("baz_app", "android_common")
|
||||||
|
|
||||||
|
// android_app module depends on aconfig_declarations listed in flags_packages
|
||||||
|
// and that of static libs, but not libs
|
||||||
|
aapt2LinkRule := bazApp.Rule("android/soong/java.aapt2Link")
|
||||||
|
linkInFlags := aapt2LinkRule.Args["inFlags"]
|
||||||
|
android.AssertStringDoesContain(t,
|
||||||
|
"aapt2 link command expected to pass feature flags arguments of flags_packages and that of its static libs",
|
||||||
|
linkInFlags,
|
||||||
|
"--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
|
||||||
|
)
|
||||||
|
android.AssertStringDoesNotContain(t,
|
||||||
|
"aapt2 link command expected to not pass feature flags arguments of flags_packages of its libs",
|
||||||
|
linkInFlags,
|
||||||
|
"--feature-flags @out/soong/.intermediates/foo/intermediate.txt",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
|
// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
|
||||||
func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
|
func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
|
||||||
bp := `
|
bp := `
|
||||||
|
@@ -150,12 +150,13 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
|
|||||||
aaptLinkFlags = append(aaptLinkFlags,
|
aaptLinkFlags = append(aaptLinkFlags,
|
||||||
"--rename-overlay-category "+*r.overridableProperties.Category)
|
"--rename-overlay-category "+*r.overridableProperties.Category)
|
||||||
}
|
}
|
||||||
|
aconfigTextFilePaths := getAconfigFilePaths(ctx)
|
||||||
r.aapt.buildActions(ctx,
|
r.aapt.buildActions(ctx,
|
||||||
aaptBuildActionOptions{
|
aaptBuildActionOptions{
|
||||||
sdkContext: r,
|
sdkContext: r,
|
||||||
enforceDefaultTargetSdkVersion: false,
|
enforceDefaultTargetSdkVersion: false,
|
||||||
extraLinkFlags: aaptLinkFlags,
|
extraLinkFlags: aaptLinkFlags,
|
||||||
aconfigTextFiles: getAconfigFilePaths(ctx),
|
aconfigTextFiles: aconfigTextFilePaths,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -176,6 +177,10 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
|
|||||||
partition := rroPartition(ctx)
|
partition := rroPartition(ctx)
|
||||||
r.installDir = android.PathForModuleInPartitionInstall(ctx, partition, "overlay", String(r.properties.Theme))
|
r.installDir = android.PathForModuleInPartitionInstall(ctx, partition, "overlay", String(r.properties.Theme))
|
||||||
ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
|
ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
|
||||||
|
|
||||||
|
android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
|
||||||
|
AconfigTextFiles: aconfigTextFilePaths,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
|
func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
|
||||||
|
Reference in New Issue
Block a user