Remove global state from apex modules
A global variant was used to store the global mapping between
modules and APEXes. Replace it with storing pointers to APEX
contents inside each module so that they can query the contents
of any APEXes they belong to.
Bug: 146393795
Test: all Soong tests
Test: single line change to build.ninja host install dependency ordering
Test: no Android-${TARGET_PRODUCT}.mk, make_vars-${TARGET_PRODUCT}.mk or late-${TARGET_PRODUCT}.mk
Change-Id: Id2d7b73ea27f8c3b41d30820bdd86b65c539bfa4
diff --git a/apex/apex.go b/apex/apex.go
index a5b228c..a9a58a6 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -67,6 +67,7 @@
androidAppTag = dependencyTag{name: "androidApp", payload: true}
rroTag = dependencyTag{name: "rro", payload: true}
bpfTag = dependencyTag{name: "bpf", payload: true}
+ testForTag = dependencyTag{name: "test for"}
apexAvailBaseline = makeApexAvailableBaseline()
@@ -769,7 +770,10 @@
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
+ ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
+ ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
ctx.BottomUp("apex", apexMutator).Parallel()
+ ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
@@ -785,13 +789,6 @@
if !ok || a.vndkApex {
return
}
- apexInfo := android.ApexInfo{
- ApexVariationName: mctx.ModuleName(),
- MinSdkVersionStr: a.minSdkVersion(mctx).String(),
- RequiredSdks: a.RequiredSdks(),
- Updatable: a.Updatable(),
- InApexes: []string{mctx.ModuleName()},
- }
useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
@@ -800,7 +797,9 @@
return
}
- mctx.WalkDeps(func(child, parent android.Module) bool {
+ contents := make(map[string]android.ApexMembership)
+
+ continueApexDepsWalk := func(child, parent android.Module) bool {
am, ok := child.(android.ApexModule)
if !ok || !am.CanHaveApexVariants() {
return false
@@ -813,12 +812,41 @@
return false
}
}
+ return true
+ }
+
+ mctx.WalkDeps(func(child, parent android.Module) bool {
+ if !continueApexDepsWalk(child, parent) {
+ return false
+ }
depName := mctx.OtherModuleName(child)
// If the parent is apexBundle, this child is directly depended.
_, directDep := parent.(*apexBundle)
- android.UpdateApexDependency(apexInfo, depName, directDep)
- am.BuildForApex(apexInfo)
+ contents[depName] = contents[depName].Add(directDep)
+ return true
+ })
+
+ apexContents := android.NewApexContents(mctx.ModuleName(), contents)
+ mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
+ Contents: apexContents,
+ })
+
+ apexInfo := android.ApexInfo{
+ ApexVariationName: mctx.ModuleName(),
+ MinSdkVersionStr: a.minSdkVersion(mctx).String(),
+ RequiredSdks: a.RequiredSdks(),
+ Updatable: a.Updatable(),
+ InApexes: []string{mctx.ModuleName()},
+ ApexContents: []*android.ApexContents{apexContents},
+ }
+
+ mctx.WalkDeps(func(child, parent android.Module) bool {
+ if !continueApexDepsWalk(child, parent) {
+ return false
+ }
+
+ child.(android.ApexModule).BuildForApex(apexInfo)
return true
})
}
@@ -830,7 +858,40 @@
if am, ok := mctx.Module().(android.ApexModule); ok {
// Check if any dependencies use unique apex variations. If so, use unique apex variations
// for this module.
- am.UpdateUniqueApexVariationsForDeps(mctx)
+ android.UpdateUniqueApexVariationsForDeps(mctx, am)
+ }
+}
+
+func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
+ if !mctx.Module().Enabled() {
+ return
+ }
+ // Check if this module is a test for an apex. If so, add a dependency on the apex
+ // in order to retrieve its contents later.
+ if am, ok := mctx.Module().(android.ApexModule); ok {
+ if testFor := am.TestFor(); len(testFor) > 0 {
+ mctx.AddFarVariationDependencies([]blueprint.Variation{
+ {Mutator: "os", Variation: am.Target().OsVariation()},
+ {"arch", "common"},
+ }, testForTag, testFor...)
+ }
+ }
+}
+
+func apexTestForMutator(mctx android.BottomUpMutatorContext) {
+ if !mctx.Module().Enabled() {
+ return
+ }
+
+ if _, ok := mctx.Module().(android.ApexModule); ok {
+ var contents []*android.ApexContents
+ for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
+ abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
+ contents = append(contents, abInfo.Contents)
+ }
+ mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
+ ApexContents: contents,
+ })
}
}
@@ -891,8 +952,9 @@
if !mctx.Module().Enabled() {
return
}
+
if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
- am.CreateApexVariations(mctx)
+ android.CreateApexVariations(mctx, am)
} else if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex {
// apex bundle itself is mutated so that it and its modules have same
// apex variant.
@@ -909,6 +971,15 @@
}
+func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
+ if !mctx.Module().Enabled() {
+ return
+ }
+ if am, ok := mctx.Module().(android.ApexModule); ok {
+ android.UpdateDirectlyInAnyApex(mctx, am)
+ }
+}
+
func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
if !mctx.Module().Enabled() {
return
@@ -1118,6 +1189,12 @@
Payload_fs_type *string
}
+type ApexBundleInfo struct {
+ Contents *android.ApexContents
+}
+
+var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_deps")
+
type apexTargetBundleProperties struct {
Target struct {
// Multilib properties only for android.
@@ -1908,6 +1985,8 @@
return false
}
+ childApexInfo := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
+
dt := ctx.OtherModuleDependencyTag(child)
if _, ok := dt.(android.ExcludeFromApexContentsTag); ok {
@@ -1924,7 +2003,7 @@
}
// Check for the indirect dependencies if it is considered as part of the APEX
- if android.InList(ctx.ModuleName(), am.InApexes()) {
+ if android.InList(ctx.ModuleName(), childApexInfo.InApexes) {
return do(ctx, parent, am, false /* externalDep */)
}
@@ -2032,6 +2111,8 @@
return
}
+ abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
+
a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if ccm, ok := to.(*cc.Module); ok {
apexName := ctx.ModuleName()
@@ -2052,7 +2133,7 @@
return false
}
- isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !android.DirectlyInApex(apexName, toName)
+ isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
if isStubLibraryFromOtherApex && !externalDep {
ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
"It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
@@ -2291,7 +2372,8 @@
}
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
af.transitiveDep = true
- if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
+ abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
+ if !a.Host() && !abInfo.Contents.DirectlyInApex(depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
// If the dependency is a stubs lib, don't include it in this APEX,
// but make sure that the lib is installed on the device.
// In case no APEX is having the lib, the lib is installed to the system
@@ -2299,7 +2381,7 @@
//
// Always include if we are a host-apex however since those won't have any
// system libraries.
- if !android.DirectlyInAnyApex(ctx, depName) {
+ if !am.DirectlyInAnyApex() {
// we need a module name for Make
name := cc.BaseModuleName() + cc.Properties.SubName
if proptools.Bool(a.properties.Use_vendor) {
@@ -2338,6 +2420,8 @@
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
}
+ } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
+ // nothing
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
}