Remove overriden modules from deps of autogenerated filesystem modules
`android_filesystem` supports overrides, but only if the module is
overriden by another module in its deps. For AOSP CF, the autogenerated
system.img contains an additional /bin/charger. The Kati system.img does
not contain this file because it is overriden by a module which is
installed in /vendor.
This CL updates the autogen mutators to remove a module from deps if it
is overriden by another module in PRODUCT_PACKAGES or by a transitve
required module dependency of PRODUCT_PACKAGES
Test: go test ./fsgen
Test: verified that /bin/charger no longer appears in diff_test of
system for aosp_cf_x86_64
Change-Id: Idafa1db07a42519ba3c441f851480b1c6faa63b8
Change-Id: If09050a6fd110d07d975595644dba85c740027e2
diff --git a/android/module.go b/android/module.go
index ec0f446..06754e8 100644
--- a/android/module.go
+++ b/android/module.go
@@ -118,6 +118,10 @@
// The usage of this method is experimental and should not be used outside of fsgen package.
// This will be removed once product packaging migration to Soong is complete.
DecodeMultilib(ctx ConfigContext) (string, string)
+
+ // WARNING: This should not be used outside build/soong/fsgen
+ // Overrides returns the list of modules which should not be installed if this module is installed.
+ Overrides() []string
}
// Qualified id for a module
@@ -2291,6 +2295,10 @@
return decodeMultilib(ctx, m)
}
+func (m *ModuleBase) Overrides() []string {
+ return m.commonProperties.Overrides
+}
+
type ConfigContext interface {
Config() Config
}
diff --git a/android/module_proxy.go b/android/module_proxy.go
index 0f552dd..2a65072 100644
--- a/android/module_proxy.go
+++ b/android/module_proxy.go
@@ -205,3 +205,7 @@
func (m ModuleProxy) DecodeMultilib(ctx ConfigContext) (string, string) {
panic("method is not implemented on ModuleProxy")
}
+
+func (m ModuleProxy) Overrides() []string {
+ panic("method is not implemented on ModuleProxy")
+}
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index c903338..468794f 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -47,6 +47,7 @@
}
var fsGenStateOnceKey = android.NewOnceKey("FsGenState")
+var fsGenRemoveOverridesOnceKey = android.NewOnceKey("FsGenRemoveOverrides")
// Map of partition module name to its partition that may be generated by Soong.
// Note that it is not guaranteed that all modules returned by this function are successfully
@@ -79,6 +80,13 @@
soongGeneratedPartitions []string
// Mutex to protect the fsDeps
fsDepsMutex sync.Mutex
+ // Map of _all_ soong module names to their corresponding installation properties
+ moduleToInstallationProps map[string]installationProperties
+}
+
+type installationProperties struct {
+ Required []string
+ Overrides []string
}
func newMultilibDeps() multilibDeps {
@@ -147,8 +155,9 @@
"com.android.vndk.v34": defaultDepCandidateProps(ctx.Config()),
},
},
- soongGeneratedPartitions: generatedPartitions,
- fsDepsMutex: sync.Mutex{},
+ soongGeneratedPartitions: generatedPartitions,
+ fsDepsMutex: sync.Mutex{},
+ moduleToInstallationProps: map[string]installationProperties{},
}
}).(*FsGenState)
}
@@ -193,6 +202,16 @@
}
fsGenState.fsDepsMutex.Unlock()
}
+ // store the map of module to (required,overrides) even if the module is not in PRODUCT_PACKAGES.
+ // the module might be installed transitively.
+ if m.Target().Os.Class == android.Device && m.Enabled(mctx) && m.ExportedToMake() {
+ fsGenState.fsDepsMutex.Lock()
+ fsGenState.moduleToInstallationProps[m.Name()] = installationProperties{
+ Required: m.RequiredModuleNames(mctx),
+ Overrides: m.Overrides(),
+ }
+ fsGenState.fsDepsMutex.Unlock()
+ }
}
type depsStruct struct {
@@ -231,6 +250,7 @@
}
func setDepsMutator(mctx android.BottomUpMutatorContext) {
+ removeOverriddenDeps(mctx)
fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
fsDeps := fsGenState.fsDeps
soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions)
@@ -243,6 +263,47 @@
}
}
+// removeOverriddenDeps collects PRODUCT_PACKAGES and (transitive) required deps.
+// it then removes any modules which appear in `overrides` of the above list.
+func removeOverriddenDeps(mctx android.BottomUpMutatorContext) {
+ mctx.Config().Once(fsGenRemoveOverridesOnceKey, func() interface{} {
+ fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+ fsDeps := fsGenState.fsDeps
+ overridden := map[string]bool{}
+ allDeps := []string{}
+
+ // Step 1: Initialization: Append PRODUCT_PACKAGES to the queue
+ for _, fsDep := range fsDeps {
+ for depName, _ := range *fsDep {
+ allDeps = append(allDeps, depName)
+ }
+ }
+
+ // Step 2: Process the queue, and add required modules to the queue.
+ i := 0
+ for {
+ if i == len(allDeps) {
+ break
+ }
+ depName := allDeps[i]
+ for _, overrides := range fsGenState.moduleToInstallationProps[depName].Overrides {
+ overridden[overrides] = true
+ }
+ // add required dep to the queue.
+ allDeps = append(allDeps, fsGenState.moduleToInstallationProps[depName].Required...)
+ i += 1
+ }
+
+ // Step 3: Delete all the overridden modules.
+ for overridden, _ := range overridden {
+ for partition, _ := range fsDeps {
+ delete(*fsDeps[partition], overridden)
+ }
+ }
+ return nil
+ })
+}
+
func generateDepStruct(deps map[string]*depCandidateProps) *packagingPropsStruct {
depsStruct := packagingPropsStruct{}
for depName, depProps := range deps {
diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go
index 484cc38..199eaad 100644
--- a/fsgen/filesystem_creator_test.go
+++ b/fsgen/filesystem_creator_test.go
@@ -217,3 +217,39 @@
"//c/d:bar",
)
}
+
+func TestRemoveOverriddenModulesFromDeps(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ android.PrepareForIntegrationTestWithAndroid,
+ android.PrepareForTestWithAndroidBuildComponents,
+ android.PrepareForTestWithAllowMissingDependencies,
+ prepareForTestWithFsgenBuildComponents,
+ java.PrepareForTestWithJavaBuildComponents,
+ android.FixtureMergeMockFs(android.MockFS{
+ "external/avb/test/data/testkey_rsa4096.pem": nil,
+ "build/soong/fsgen/Android.bp": []byte(`
+ soong_filesystem_creator {
+ name: "foo",
+ }
+ `),
+ }),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"libfoo", "libbar"}
+ }),
+ ).RunTestWithBp(t, `
+java_library {
+ name: "libfoo",
+}
+java_library {
+ name: "libbar",
+ required: ["libbaz"],
+}
+java_library {
+ name: "libbaz",
+ overrides: ["libfoo"], // overrides libfoo
+}
+ `)
+ resolvedSystemDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system"]
+ _, libFooInDeps := (*resolvedSystemDeps)["libfoo"]
+ android.AssertBoolEquals(t, "libfoo should not appear in deps because it has been overridden by libbaz. The latter is a required dep of libbar, which is listed in PRODUCT_PACKAGES", false, libFooInDeps)
+}