From e0edaf9d4904df94331de42cb780797f2eb2a024 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 11 Jan 2021 17:31:17 -0800 Subject: [PATCH] Remove some global state from vendor and recovery snapshots Snapshots storead global sets of modules that should be replaced with vendor snapshot modules. Move the data instead to a vendor_snapshot or recovery_snapshot module type that depends on all the modules in the snapshot, and then have modules that should use the snaphsot depend on it to query for the set of modules that should be replaced. Bug: 177098205 Test: vendor_snapshot_test.go Change-Id: I2826adacfb473e9139b5ea93ba83b8a54cc1a56b --- cc/cc.go | 122 ++++----- cc/sanitize.go | 23 +- cc/sdk.go | 2 + cc/snapshot_prebuilt.go | 495 ++++++++++++++++--------------------- cc/testing.go | 8 +- cc/vendor_snapshot_test.go | 52 ++++ 6 files changed, 325 insertions(+), 377 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index afa6bf9b1..0dd90cf47 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -50,9 +50,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel() - ctx.BottomUp("vendor_snapshot", VendorSnapshotMutator).Parallel() ctx.BottomUp("vendor_snapshot_source", VendorSnapshotSourceMutator).Parallel() - ctx.BottomUp("recovery_snapshot", RecoverySnapshotMutator).Parallel() ctx.BottomUp("recovery_snapshot_source", RecoverySnapshotSourceMutator).Parallel() }) @@ -1937,6 +1935,40 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs + var snapshotInfo *SnapshotInfo + getSnapshot := func() SnapshotInfo { + // Only modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of + // SnapshotInfo, which provides no mappings. + if snapshotInfo == nil { + // Only retrieve the snapshot on demand in order to avoid circular dependencies + // between the modules in the snapshot and the snapshot itself. + var snapshotModule []blueprint.Module + if c.InVendor() && c.VndkVersion() == actx.DeviceConfig().VndkVersion() { + snapshotModule = ctx.AddVariationDependencies(nil, nil, "vendor_snapshot") + } else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() { + snapshotModule = ctx.AddVariationDependencies(nil, nil, "recovery_snapshot") + } + if len(snapshotModule) > 0 { + snapshot := ctx.OtherModuleProvider(snapshotModule[0], SnapshotInfoProvider).(SnapshotInfo) + snapshotInfo = &snapshot + // republish the snapshot for use in later mutators on this module + ctx.SetProvider(SnapshotInfoProvider, snapshot) + } else { + snapshotInfo = &SnapshotInfo{} + } + } + + return *snapshotInfo + } + + rewriteSnapshotLib := func(lib string, snapshotMap map[string]string) string { + if snapshot, ok := snapshotMap[lib]; ok { + return snapshot + } + + return lib + } + variantNdkLibs := []string{} variantLateNdkLibs := []string{} if ctx.Os() == android.Android { @@ -1956,21 +1988,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { // nonvariantLibs vendorPublicLibraries := vendorPublicLibraries(actx.Config()) - vendorSnapshotSharedLibs := vendorSnapshotSharedLibs(actx.Config()) - recoverySnapshotSharedLibs := recoverySnapshotSharedLibs(actx.Config()) - - rewriteVendorLibs := func(lib string) string { - // only modules with BOARD_VNDK_VERSION uses snapshot. - if c.VndkVersion() != actx.DeviceConfig().VndkVersion() { - return lib - } - - if snapshot, ok := vendorSnapshotSharedLibs.get(lib, actx.Arch().ArchType); ok { - return snapshot - } - - return lib - } rewriteLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) { variantLibs = []string{} @@ -1979,21 +1996,11 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { // strip #version suffix out name, _ := StubsLibNameAndVersion(entry) if c.InRecovery() { - recoverySnapshotVersion := - actx.DeviceConfig().RecoverySnapshotVersion() - if recoverySnapshotVersion == "current" || - recoverySnapshotVersion == "" { - nonvariantLibs = append(nonvariantLibs, name) - } else if snapshot, ok := recoverySnapshotSharedLibs.get( - name, actx.Arch().ArchType); ok { - nonvariantLibs = append(nonvariantLibs, snapshot) - } else { - nonvariantLibs = append(nonvariantLibs, name) - } + nonvariantLibs = append(nonvariantLibs, rewriteSnapshotLib(entry, getSnapshot().SharedLibs)) } else if ctx.useSdk() && inList(name, *getNDKKnownLibs(ctx.Config())) { variantLibs = append(variantLibs, name+ndkLibrarySuffix) } else if ctx.useVndk() { - nonvariantLibs = append(nonvariantLibs, rewriteVendorLibs(entry)) + nonvariantLibs = append(nonvariantLibs, rewriteSnapshotLib(entry, getSnapshot().SharedLibs)) } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, *vendorPublicLibraries) { vendorPublicLib := name + vendorPublicLibrarySuffix if actx.OtherModuleExists(vendorPublicLib) { @@ -2015,56 +2022,19 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps.SharedLibs, variantNdkLibs = rewriteLibs(deps.SharedLibs) deps.LateSharedLibs, variantLateNdkLibs = rewriteLibs(deps.LateSharedLibs) deps.ReexportSharedLibHeaders, _ = rewriteLibs(deps.ReexportSharedLibHeaders) - if ctx.useVndk() { - for idx, lib := range deps.RuntimeLibs { - deps.RuntimeLibs[idx] = rewriteVendorLibs(lib) - } + + for idx, lib := range deps.RuntimeLibs { + deps.RuntimeLibs[idx] = rewriteSnapshotLib(lib, getSnapshot().SharedLibs) } } - rewriteSnapshotLibs := func(lib string, snapshotMap *snapshotMap) string { - // only modules with BOARD_VNDK_VERSION uses snapshot. - if c.VndkVersion() != actx.DeviceConfig().VndkVersion() { - return lib - } - - if snapshot, ok := snapshotMap.get(lib, actx.Arch().ArchType); ok { - return snapshot - } - - return lib - } - - snapshotHeaderLibs := vendorSnapshotHeaderLibs(actx.Config()) - snapshotStaticLibs := vendorSnapshotStaticLibs(actx.Config()) - snapshotObjects := vendorSnapshotObjects(actx.Config()) - - if c.InRecovery() { - rewriteSnapshotLibs = func(lib string, snapshotMap *snapshotMap) string { - recoverySnapshotVersion := - actx.DeviceConfig().RecoverySnapshotVersion() - if recoverySnapshotVersion == "current" || - recoverySnapshotVersion == "" { - return lib - } else if snapshot, ok := snapshotMap.get(lib, actx.Arch().ArchType); ok { - return snapshot - } - - return lib - } - - snapshotHeaderLibs = recoverySnapshotHeaderLibs(actx.Config()) - snapshotStaticLibs = recoverySnapshotStaticLibs(actx.Config()) - snapshotObjects = recoverySnapshotObjects(actx.Config()) - } - for _, lib := range deps.HeaderLibs { depTag := libraryDependencyTag{Kind: headerLibraryDependency} if inList(lib, deps.ReexportHeaderLibHeaders) { depTag.reexportFlags = true } - lib = rewriteSnapshotLibs(lib, snapshotHeaderLibs) + lib = rewriteSnapshotLib(lib, getSnapshot().HeaderLibs) if c.IsStubs() { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), @@ -2087,7 +2057,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { lib = impl } - lib = rewriteSnapshotLibs(lib, snapshotStaticLibs) + lib = rewriteSnapshotLib(lib, getSnapshot().StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, @@ -2107,7 +2077,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { lib = impl } - lib = rewriteSnapshotLibs(lib, snapshotStaticLibs) + lib = rewriteSnapshotLib(lib, getSnapshot().StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, @@ -2121,14 +2091,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, - }, depTag, rewriteSnapshotLibs(staticUnwinder(actx), snapshotStaticLibs)) + }, depTag, rewriteSnapshotLib(staticUnwinder(actx), getSnapshot().StaticLibs)) } for _, lib := range deps.LateStaticLibs { depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, - }, depTag, rewriteSnapshotLibs(lib, snapshotStaticLibs)) + }, depTag, rewriteSnapshotLib(lib, getSnapshot().StaticLibs)) } // shared lib names without the #version suffix @@ -2192,11 +2162,11 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...) if deps.CrtBegin != "" { actx.AddVariationDependencies(crtVariations, CrtBeginDepTag, - rewriteSnapshotLibs(deps.CrtBegin, snapshotObjects)) + rewriteSnapshotLib(deps.CrtBegin, getSnapshot().Objects)) } if deps.CrtEnd != "" { actx.AddVariationDependencies(crtVariations, CrtEndDepTag, - rewriteSnapshotLibs(deps.CrtEnd, snapshotObjects)) + rewriteSnapshotLib(deps.CrtEnd, getSnapshot().Objects)) } if deps.LinkerFlagsFile != "" { actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile) diff --git a/cc/sanitize.go b/cc/sanitize.go index 8eeb35559..8218d972c 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -1149,13 +1149,11 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { // added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module if c.staticBinary() { deps := append(extraStaticDeps, runtimeLibrary) - // If we're using snapshots and in vendor, redirect to snapshot whenever possible - if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() { - snapshots := vendorSnapshotStaticLibs(mctx.Config()) - for idx, dep := range deps { - if lib, ok := snapshots.get(dep, mctx.Arch().ArchType); ok { - deps[idx] = lib - } + // If we're using snapshots, redirect to snapshot whenever possible + snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo) + for idx, dep := range deps { + if lib, ok := snapshot.StaticLibs[dep]; ok { + deps[idx] = lib } } @@ -1168,13 +1166,12 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { } mctx.AddFarVariationDependencies(variations, depTag, deps...) } else if !c.static() && !c.Header() { - // If we're using snapshots and in vendor, redirect to snapshot whenever possible - if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() { - snapshots := vendorSnapshotSharedLibs(mctx.Config()) - if lib, ok := snapshots.get(runtimeLibrary, mctx.Arch().ArchType); ok { - runtimeLibrary = lib - } + // If we're using snapshots, redirect to snapshot whenever possible + snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo) + if lib, ok := snapshot.SharedLibs[runtimeLibrary]; ok { + runtimeLibrary = lib } + // Skip apex dependency check for sharedLibraryDependency // when sanitizer diags are enabled. Skipping the check will allow // building with diag libraries without having to list the diff --git a/cc/sdk.go b/cc/sdk.go index 2c3fec3fd..aec950b94 100644 --- a/cc/sdk.go +++ b/cc/sdk.go @@ -75,5 +75,7 @@ func sdkMutator(ctx android.BottomUpMutatorContext) { } ctx.AliasVariation("") } + case *snapshot: + ctx.CreateVariations("") } } diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index 2003e03ff..c0b8d5d06 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -23,15 +23,13 @@ import ( "android/soong/android" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) // Defines the specifics of different images to which the snapshot process is applicable, e.g., // vendor, recovery, ramdisk. type snapshotImage interface { - // Used to register callbacks with the build system. - init() - // Returns true if a snapshot should be generated for this image. shouldGenerateSnapshot(ctx android.SingletonContext) bool @@ -61,10 +59,6 @@ type snapshotImage interface { // exclude_from_recovery_snapshot properties. excludeFromSnapshot(m *Module) bool - // Returns the snapshotMap to be used for a given module and config, or nil if the - // module is not included in this image. - getSnapshotMap(m *Module, cfg android.Config) *snapshotMap - // Returns mutex used for mutual exclusion when updating the snapshot maps. getMutex() *sync.Mutex @@ -77,30 +71,38 @@ type snapshotImage interface { // Returns true if the build is using a snapshot for this image. isUsingSnapshot(cfg android.DeviceConfig) bool - // Whether to skip the module mutator for a module in a given context. - skipModuleMutator(ctx android.BottomUpMutatorContext) bool - - // Whether to skip the source mutator for a given module. - skipSourceMutator(ctx android.BottomUpMutatorContext) bool + // Returns a version of which the snapshot should be used in this target. + // This will only be meaningful when isUsingSnapshot is true. + targetSnapshotVersion(cfg android.DeviceConfig) string // Whether to exclude a given module from the directed snapshot or not. // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on, // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured. excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool + + // The image variant name for this snapshot image. + // For example, recovery snapshot image will return "recovery", and vendor snapshot image will + // return "vendor." + version. + imageVariantName(cfg android.DeviceConfig) string + + // The variant suffix for snapshot modules. For example, vendor snapshot modules will have + // ".vendor" as their suffix. + moduleNameSuffix() string } type vendorSnapshotImage struct{} type recoverySnapshotImage struct{} -func (vendorSnapshotImage) init() { - android.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) - android.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) - android.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) - android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) - android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) - android.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory) +func (vendorSnapshotImage) init(ctx android.RegistrationContext) { + ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) + ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory) + ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) + ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) + ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) + ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) + ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory) - android.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton) + ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton) } func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { @@ -129,25 +131,6 @@ func (vendorSnapshotImage) excludeFromSnapshot(m *Module) bool { return m.ExcludeFromVendorSnapshot() } -func (vendorSnapshotImage) getSnapshotMap(m *Module, cfg android.Config) *snapshotMap { - if lib, ok := m.linker.(libraryInterface); ok { - if lib.static() { - return vendorSnapshotStaticLibs(cfg) - } else if lib.shared() { - return vendorSnapshotSharedLibs(cfg) - } else { - // header - return vendorSnapshotHeaderLibs(cfg) - } - } else if m.binary() { - return vendorSnapshotBinaries(cfg) - } else if m.object() { - return vendorSnapshotObjects(cfg) - } else { - return nil - } -} - func (vendorSnapshotImage) getMutex() *sync.Mutex { return &vendorSnapshotsLock } @@ -176,26 +159,8 @@ func (vendorSnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool { return vndkVersion != "current" && vndkVersion != "" } -func (vendorSnapshotImage) skipModuleMutator(ctx android.BottomUpMutatorContext) bool { - vndkVersion := ctx.DeviceConfig().VndkVersion() - module, ok := ctx.Module().(*Module) - return !ok || module.VndkVersion() != vndkVersion -} - -func (vendorSnapshotImage) skipSourceMutator(ctx android.BottomUpMutatorContext) bool { - vndkVersion := ctx.DeviceConfig().VndkVersion() - module, ok := ctx.Module().(*Module) - if !ok { - return true - } - if module.VndkVersion() != vndkVersion { - return true - } - // .. and also filter out llndk library - if module.IsLlndk() { - return true - } - return false +func (vendorSnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string { + return cfg.VndkVersion() } // returns true iff a given module SHOULD BE EXCLUDED, false if included @@ -208,13 +173,22 @@ func (vendorSnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, return !cfg.VendorSnapshotModules()[name] } -func (recoverySnapshotImage) init() { - android.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton) - android.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory) - android.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory) - android.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory) - android.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory) - android.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory) +func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string { + return VendorVariationPrefix + cfg.VndkVersion() +} + +func (vendorSnapshotImage) moduleNameSuffix() string { + return vendorSuffix +} + +func (recoverySnapshotImage) init(ctx android.RegistrationContext) { + ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton) + ctx.RegisterModuleType("recovery_snapshot", recoverySnapshotFactory) + ctx.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory) + ctx.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory) + ctx.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory) + ctx.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory) + ctx.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory) } func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { @@ -245,25 +219,6 @@ func (recoverySnapshotImage) excludeFromSnapshot(m *Module) bool { return m.ExcludeFromRecoverySnapshot() } -func (recoverySnapshotImage) getSnapshotMap(m *Module, cfg android.Config) *snapshotMap { - if lib, ok := m.linker.(libraryInterface); ok { - if lib.static() { - return recoverySnapshotStaticLibs(cfg) - } else if lib.shared() { - return recoverySnapshotSharedLibs(cfg) - } else { - // header - return recoverySnapshotHeaderLibs(cfg) - } - } else if m.binary() { - return recoverySnapshotBinaries(cfg) - } else if m.object() { - return recoverySnapshotObjects(cfg) - } else { - return nil - } -} - func (recoverySnapshotImage) getMutex() *sync.Mutex { return &recoverySnapshotsLock } @@ -281,14 +236,8 @@ func (recoverySnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool { return recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" } -func (recoverySnapshotImage) skipModuleMutator(ctx android.BottomUpMutatorContext) bool { - module, ok := ctx.Module().(*Module) - return !ok || !module.InRecovery() -} - -func (recoverySnapshotImage) skipSourceMutator(ctx android.BottomUpMutatorContext) bool { - module, ok := ctx.Module().(*Module) - return !ok || !module.InRecovery() +func (recoverySnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string { + return cfg.RecoverySnapshotVersion() } func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { @@ -296,50 +245,172 @@ func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfi return false } +func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string { + return android.RecoveryVariation +} + +func (recoverySnapshotImage) moduleNameSuffix() string { + return recoverySuffix +} + var vendorSnapshotImageSingleton vendorSnapshotImage var recoverySnapshotImageSingleton recoverySnapshotImage func init() { - vendorSnapshotImageSingleton.init() - recoverySnapshotImageSingleton.init() + vendorSnapshotImageSingleton.init(android.InitRegistrationContext) + recoverySnapshotImageSingleton.init(android.InitRegistrationContext) } const ( - vendorSnapshotHeaderSuffix = ".vendor_header." - vendorSnapshotSharedSuffix = ".vendor_shared." - vendorSnapshotStaticSuffix = ".vendor_static." - vendorSnapshotBinarySuffix = ".vendor_binary." - vendorSnapshotObjectSuffix = ".vendor_object." -) - -const ( - recoverySnapshotHeaderSuffix = ".recovery_header." - recoverySnapshotSharedSuffix = ".recovery_shared." - recoverySnapshotStaticSuffix = ".recovery_static." - recoverySnapshotBinarySuffix = ".recovery_binary." - recoverySnapshotObjectSuffix = ".recovery_object." + snapshotHeaderSuffix = "_header." + snapshotSharedSuffix = "_shared." + snapshotStaticSuffix = "_static." + snapshotBinarySuffix = "_binary." + snapshotObjectSuffix = "_object." ) var ( - vendorSnapshotsLock sync.Mutex - vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules") - vendorSnapshotHeaderLibsKey = android.NewOnceKey("vendorSnapshotHeaderLibs") - vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs") - vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs") - vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries") - vendorSnapshotObjectsKey = android.NewOnceKey("vendorSnapshotObjects") + vendorSnapshotsLock sync.Mutex + vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules") ) var ( - recoverySnapshotsLock sync.Mutex - recoverySuffixModulesKey = android.NewOnceKey("recoverySuffixModules") - recoverySnapshotHeaderLibsKey = android.NewOnceKey("recoverySnapshotHeaderLibs") - recoverySnapshotStaticLibsKey = android.NewOnceKey("recoverySnapshotStaticLibs") - recoverySnapshotSharedLibsKey = android.NewOnceKey("recoverySnapshotSharedLibs") - recoverySnapshotBinariesKey = android.NewOnceKey("recoverySnapshotBinaries") - recoverySnapshotObjectsKey = android.NewOnceKey("recoverySnapshotObjects") + recoverySnapshotsLock sync.Mutex + recoverySuffixModulesKey = android.NewOnceKey("recoverySuffixModules") ) +type SnapshotProperties struct { + Header_libs []string `android:"arch_variant"` + Static_libs []string `android:"arch_variant"` + Shared_libs []string `android:"arch_variant"` + Vndk_libs []string `android:"arch_variant"` + Binaries []string `android:"arch_variant"` + Objects []string `android:"arch_variant"` +} + +type snapshot struct { + android.ModuleBase + + properties SnapshotProperties + + baseSnapshot baseSnapshotDecorator + + image snapshotImage +} + +func (s *snapshot) ImageMutatorBegin(ctx android.BaseModuleContext) { + cfg := ctx.DeviceConfig() + if !s.image.isUsingSnapshot(cfg) || s.image.targetSnapshotVersion(cfg) != s.baseSnapshot.version() { + s.Disable() + } +} + +func (s *snapshot) CoreVariantNeeded(ctx android.BaseModuleContext) bool { + return false +} + +func (s *snapshot) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { + return false +} + +func (s *snapshot) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { + return false +} + +func (s *snapshot) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { + return false +} + +func (s *snapshot) ExtraImageVariations(ctx android.BaseModuleContext) []string { + return []string{s.image.imageVariantName(ctx.DeviceConfig())} +} + +func (s *snapshot) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { +} + +func (s *snapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // Nothing, the snapshot module is only used to forward dependency information in DepsMutator. +} + +func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) { + collectSnapshotMap := func(variations []blueprint.Variation, depTag blueprint.DependencyTag, + names []string, snapshotSuffix, moduleSuffix string) map[string]string { + + decoratedNames := make([]string, 0, len(names)) + for _, name := range names { + decoratedNames = append(decoratedNames, name+ + snapshotSuffix+moduleSuffix+ + s.baseSnapshot.version()+ + "."+ctx.Arch().ArchType.Name) + } + + deps := ctx.AddVariationDependencies(variations, depTag, decoratedNames...) + snapshotMap := make(map[string]string) + for _, dep := range deps { + if dep == nil { + continue + } + + snapshotMap[dep.(*Module).BaseModuleName()] = ctx.OtherModuleName(dep) + } + return snapshotMap + } + + snapshotSuffix := s.image.moduleNameSuffix() + headers := collectSnapshotMap(nil, HeaderDepTag(), s.properties.Header_libs, snapshotSuffix, snapshotHeaderSuffix) + binaries := collectSnapshotMap(nil, nil, s.properties.Binaries, snapshotSuffix, snapshotBinarySuffix) + objects := collectSnapshotMap(nil, nil, s.properties.Objects, snapshotSuffix, snapshotObjectSuffix) + + staticLibs := collectSnapshotMap([]blueprint.Variation{ + {Mutator: "link", Variation: "static"}, + }, StaticDepTag(), s.properties.Static_libs, snapshotSuffix, snapshotStaticSuffix) + + sharedLibs := collectSnapshotMap([]blueprint.Variation{ + {Mutator: "link", Variation: "shared"}, + }, SharedDepTag(), s.properties.Shared_libs, snapshotSuffix, snapshotSharedSuffix) + + vndkLibs := collectSnapshotMap([]blueprint.Variation{ + {Mutator: "link", Variation: "shared"}, + }, SharedDepTag(), s.properties.Vndk_libs, "", vndkSuffix) + + for k, v := range vndkLibs { + sharedLibs[k] = v + } + ctx.SetProvider(SnapshotInfoProvider, SnapshotInfo{ + HeaderLibs: headers, + Binaries: binaries, + Objects: objects, + StaticLibs: staticLibs, + SharedLibs: sharedLibs, + }) +} + +type SnapshotInfo struct { + HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs map[string]string +} + +var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps") + +var _ android.ImageInterface = (*snapshot)(nil) + +func vendorSnapshotFactory() android.Module { + return snapshotFactory(vendorSnapshotImageSingleton) +} + +func recoverySnapshotFactory() android.Module { + return snapshotFactory(recoverySnapshotImageSingleton) +} + +func snapshotFactory(image snapshotImage) android.Module { + snapshot := &snapshot{} + snapshot.image = image + snapshot.AddProperties( + &snapshot.properties, + &snapshot.baseSnapshot.baseProperties) + android.InitAndroidArchModule(snapshot, android.DeviceSupported, android.MultilibBoth) + return snapshot +} + // vendorSuffixModules holds names of modules whose vendor variants should have the vendor suffix. // This is determined by source modules, and then this will be used when exporting snapshot modules // to Makefile. @@ -355,73 +426,12 @@ func vendorSuffixModules(config android.Config) map[string]bool { }).(map[string]bool) } -// these are vendor snapshot maps holding names of vendor snapshot modules -func vendorSnapshotHeaderLibs(config android.Config) *snapshotMap { - return config.Once(vendorSnapshotHeaderLibsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func vendorSnapshotSharedLibs(config android.Config) *snapshotMap { - return config.Once(vendorSnapshotSharedLibsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func vendorSnapshotStaticLibs(config android.Config) *snapshotMap { - return config.Once(vendorSnapshotStaticLibsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func vendorSnapshotBinaries(config android.Config) *snapshotMap { - return config.Once(vendorSnapshotBinariesKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func vendorSnapshotObjects(config android.Config) *snapshotMap { - return config.Once(vendorSnapshotObjectsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - func recoverySuffixModules(config android.Config) map[string]bool { return config.Once(recoverySuffixModulesKey, func() interface{} { return make(map[string]bool) }).(map[string]bool) } -func recoverySnapshotHeaderLibs(config android.Config) *snapshotMap { - return config.Once(recoverySnapshotHeaderLibsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func recoverySnapshotSharedLibs(config android.Config) *snapshotMap { - return config.Once(recoverySnapshotSharedLibsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func recoverySnapshotStaticLibs(config android.Config) *snapshotMap { - return config.Once(recoverySnapshotStaticLibsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func recoverySnapshotBinaries(config android.Config) *snapshotMap { - return config.Once(recoverySnapshotBinariesKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - -func recoverySnapshotObjects(config android.Config) *snapshotMap { - return config.Once(recoverySnapshotObjectsKey, func() interface{} { - return newSnapshotMap() - }).(*snapshotMap) -} - type baseSnapshotDecoratorProperties struct { // snapshot version. Version string @@ -431,7 +441,7 @@ type baseSnapshotDecoratorProperties struct { // Suffix to be added to the module name, e.g., vendor_shared, // recovery_shared, etc. - Module_suffix string + ModuleSuffix string `blueprint:"mutated"` } // baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot @@ -460,7 +470,7 @@ func (p *baseSnapshotDecorator) NameSuffix() string { versionSuffix += "." + p.arch() } - return p.baseProperties.Module_suffix + versionSuffix + return p.baseProperties.ModuleSuffix + versionSuffix } func (p *baseSnapshotDecorator) version() string { @@ -471,8 +481,8 @@ func (p *baseSnapshotDecorator) arch() string { return p.baseProperties.Target_arch } -func (p *baseSnapshotDecorator) module_suffix() string { - return p.baseProperties.Module_suffix +func (p *baseSnapshotDecorator) moduleSuffix() string { + return p.baseProperties.ModuleSuffix } func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool { @@ -481,8 +491,8 @@ func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool { // Call this with a module suffix after creating a snapshot module, such as // vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc. -func (p *baseSnapshotDecorator) init(m *Module, suffix string) { - p.baseProperties.Module_suffix = suffix +func (p *baseSnapshotDecorator) init(m *Module, snapshotSuffix, moduleSuffix string) { + p.baseProperties.ModuleSuffix = snapshotSuffix + moduleSuffix m.AddProperties(&p.baseProperties) android.AddLoadHook(m, func(ctx android.LoadHookContext) { vendorSnapshotLoadHook(ctx, p) @@ -655,7 +665,7 @@ func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enable } } -func snapshotLibraryFactory(suffix string) (*Module, *snapshotLibraryDecorator) { +func snapshotLibraryFactory(snapshotSuffix, moduleSuffix string) (*Module, *snapshotLibraryDecorator) { module, library := NewLibrary(android.DeviceSupported) module.stl = nil @@ -678,7 +688,7 @@ func snapshotLibraryFactory(suffix string) (*Module, *snapshotLibraryDecorator) module.linker = prebuilt module.installer = prebuilt - prebuilt.init(module, suffix) + prebuilt.init(module, snapshotSuffix, moduleSuffix) module.AddProperties( &prebuilt.properties, &prebuilt.sanitizerProperties, @@ -692,7 +702,7 @@ func snapshotLibraryFactory(suffix string) (*Module, *snapshotLibraryDecorator) // overrides the vendor variant of the cc shared library with the same name, if BOARD_VNDK_VERSION // is set. func VendorSnapshotSharedFactory() android.Module { - module, prebuilt := snapshotLibraryFactory(vendorSnapshotSharedSuffix) + module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotSharedSuffix) prebuilt.libraryDecorator.BuildOnlyShared() return module.Init() } @@ -702,7 +712,7 @@ func VendorSnapshotSharedFactory() android.Module { // overrides the recovery variant of the cc shared library with the same name, if BOARD_VNDK_VERSION // is set. func RecoverySnapshotSharedFactory() android.Module { - module, prebuilt := snapshotLibraryFactory(recoverySnapshotSharedSuffix) + module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotSharedSuffix) prebuilt.libraryDecorator.BuildOnlyShared() return module.Init() } @@ -712,7 +722,7 @@ func RecoverySnapshotSharedFactory() android.Module { // overrides the vendor variant of the cc static library with the same name, if BOARD_VNDK_VERSION // is set. func VendorSnapshotStaticFactory() android.Module { - module, prebuilt := snapshotLibraryFactory(vendorSnapshotStaticSuffix) + module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotStaticSuffix) prebuilt.libraryDecorator.BuildOnlyStatic() return module.Init() } @@ -722,7 +732,7 @@ func VendorSnapshotStaticFactory() android.Module { // overrides the recovery variant of the cc static library with the same name, if BOARD_VNDK_VERSION // is set. func RecoverySnapshotStaticFactory() android.Module { - module, prebuilt := snapshotLibraryFactory(recoverySnapshotStaticSuffix) + module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotStaticSuffix) prebuilt.libraryDecorator.BuildOnlyStatic() return module.Init() } @@ -732,7 +742,7 @@ func RecoverySnapshotStaticFactory() android.Module { // overrides the vendor variant of the cc header library with the same name, if BOARD_VNDK_VERSION // is set. func VendorSnapshotHeaderFactory() android.Module { - module, prebuilt := snapshotLibraryFactory(vendorSnapshotHeaderSuffix) + module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotHeaderSuffix) prebuilt.libraryDecorator.HeaderOnly() return module.Init() } @@ -742,7 +752,7 @@ func VendorSnapshotHeaderFactory() android.Module { // overrides the recovery variant of the cc header library with the same name, if BOARD_VNDK_VERSION // is set. func RecoverySnapshotHeaderFactory() android.Module { - module, prebuilt := snapshotLibraryFactory(recoverySnapshotHeaderSuffix) + module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotHeaderSuffix) prebuilt.libraryDecorator.HeaderOnly() return module.Init() } @@ -817,17 +827,17 @@ func (p *snapshotBinaryDecorator) nativeCoverage() bool { // development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_binary // overrides the vendor variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set. func VendorSnapshotBinaryFactory() android.Module { - return snapshotBinaryFactory(vendorSnapshotBinarySuffix) + return snapshotBinaryFactory(vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotBinarySuffix) } // recovery_snapshot_binary is a special prebuilt executable binary which is auto-generated by // development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_binary // overrides the recovery variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set. func RecoverySnapshotBinaryFactory() android.Module { - return snapshotBinaryFactory(recoverySnapshotBinarySuffix) + return snapshotBinaryFactory(recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotBinarySuffix) } -func snapshotBinaryFactory(suffix string) android.Module { +func snapshotBinaryFactory(snapshotSuffix, moduleSuffix string) android.Module { module, binary := NewBinary(android.DeviceSupported) binary.baseLinker.Properties.No_libcrt = BoolPtr(true) binary.baseLinker.Properties.Nocrt = BoolPtr(true) @@ -846,7 +856,7 @@ func snapshotBinaryFactory(suffix string) android.Module { module.stl = nil module.linker = prebuilt - prebuilt.init(module, suffix) + prebuilt.init(module, snapshotSuffix, moduleSuffix) module.AddProperties(&prebuilt.properties) return module.Init() } @@ -915,7 +925,7 @@ func VendorSnapshotObjectFactory() android.Module { } module.linker = prebuilt - prebuilt.init(module, vendorSnapshotObjectSuffix) + prebuilt.init(module, vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotObjectSuffix) module.AddProperties(&prebuilt.properties) return module.Init() } @@ -933,7 +943,7 @@ func RecoverySnapshotObjectFactory() android.Module { } module.linker = prebuilt - prebuilt.init(module, recoverySnapshotObjectSuffix) + prebuilt.init(module, recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotObjectSuffix) module.AddProperties(&prebuilt.properties) return module.Init() } @@ -951,59 +961,6 @@ var _ snapshotInterface = (*snapshotObjectLinker)(nil) // Mutators that helps vendor snapshot modules override source modules. // -// VendorSnapshotMutator gathers all snapshots for vendor, and disable all snapshots which don't -// match with device, e.g. -// - snapshot version is different with BOARD_VNDK_VERSION -// - snapshot arch is different with device's arch (e.g. arm vs x86) -// -// This also handles vndk_prebuilt_shared, except for they won't be disabled in any cases, given -// that any versions of VNDK might be packed into vndk APEX. -// -// TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules -func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) { - snapshotMutator(ctx, vendorSnapshotImageSingleton) -} - -func RecoverySnapshotMutator(ctx android.BottomUpMutatorContext) { - snapshotMutator(ctx, recoverySnapshotImageSingleton) -} - -func snapshotMutator(ctx android.BottomUpMutatorContext, image snapshotImage) { - if !image.isUsingSnapshot(ctx.DeviceConfig()) { - return - } - module, ok := ctx.Module().(*Module) - if !ok || !module.Enabled() { - return - } - if image.skipModuleMutator(ctx) { - return - } - if !module.isSnapshotPrebuilt() { - return - } - - // isSnapshotPrebuilt ensures snapshotInterface - if !module.linker.(snapshotInterface).matchesWithDevice(ctx.DeviceConfig()) { - // Disable unnecessary snapshot module, but do not disable - // vndk_prebuilt_shared because they might be packed into vndk APEX - if !module.IsVndk() { - module.Disable() - } - return - } - - var snapshotMap *snapshotMap = image.getSnapshotMap(module, ctx.Config()) - if snapshotMap == nil { - return - } - - mutex := image.getMutex() - mutex.Lock() - defer mutex.Unlock() - snapshotMap.add(module.BaseModuleName(), ctx.Arch().ArchType, ctx.ModuleName()) -} - // VendorSnapshotSourceMutator disables source modules which have corresponding snapshots. func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) { snapshotSourceMutator(ctx, vendorSnapshotImageSingleton) @@ -1033,30 +990,4 @@ func snapshotSourceMutator(ctx android.BottomUpMutatorContext, image snapshotIma image.suffixModules(ctx.Config())[ctx.ModuleName()] = true } - - if module.isSnapshotPrebuilt() { - return - } - if image.skipSourceMutator(ctx) { - return - } - - var snapshotMap *snapshotMap = image.getSnapshotMap(module, ctx.Config()) - if snapshotMap == nil { - return - } - - if _, ok := snapshotMap.get(ctx.ModuleName(), ctx.Arch().ArchType); !ok { - // Corresponding snapshot doesn't exist - return - } - - // Disables source modules if corresponding snapshot exists. - if lib, ok := module.linker.(libraryInterface); ok && lib.buildStatic() && lib.buildShared() { - // But do not disable because the shared variant depends on the static variant. - module.HideFromMake() - module.Properties.HideFromMake = true - } else { - module.Disable() - } } diff --git a/cc/testing.go b/cc/testing.go index dc9a59d0b..3a5bd1762 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -586,17 +586,13 @@ func CreateTestContext(config android.Config) *android.TestContext { ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) - ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) - ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) - ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) + vendorSnapshotImageSingleton.init(ctx) + recoverySnapshotImageSingleton.init(ctx) RegisterVndkLibraryTxtTypes(ctx) ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) android.RegisterPrebuiltMutators(ctx) RegisterRequiredBuildComponentsForTest(ctx) ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) - ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) - ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton) - ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton) return ctx } diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go index cce28b0f8..39c84f049 100644 --- a/cc/vendor_snapshot_test.go +++ b/cc/vendor_snapshot_test.go @@ -329,6 +329,24 @@ func TestVendorSnapshotUse(t *testing.T) { }, }, } + + // old snapshot module which has to be ignored + vndk_prebuilt_shared { + name: "libvndk", + version: "OLD", + target_arch: "arm64", + vendor_available: true, + product_available: true, + vndk: { + enabled: true, + }, + arch: { + arm64: { + srcs: ["libvndk.so"], + export_include_dirs: ["include/libvndk"], + }, + }, + } ` vendorProprietaryBp := ` @@ -367,6 +385,27 @@ func TestVendorSnapshotUse(t *testing.T) { srcs: ["bin.cpp"], } + vendor_snapshot { + name: "vendor_snapshot", + compile_multilib: "first", + version: "BOARD", + vndk_libs: [ + "libvndk", + ], + static_libs: [ + "libvendor", + "libvendor_available", + "libvndk", + ], + shared_libs: [ + "libvendor", + "libvendor_available", + ], + binaries: [ + "bin", + ], + } + vendor_snapshot_static { name: "libvndk", version: "BOARD", @@ -443,6 +482,19 @@ func TestVendorSnapshotUse(t *testing.T) { }, }, } + + // old snapshot module which has to be ignored + vendor_snapshot_binary { + name: "bin", + version: "OLD", + target_arch: "arm64", + vendor: true, + arch: { + arm64: { + src: "bin", + }, + }, + } ` depsBp := GatherRequiredDepsForTest(android.Android)