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
This commit is contained in:
Colin Cross 2021-01-11 17:31:17 -08:00 committed by Inseob Kim
parent 9da4aa8166
commit e0edaf9d49
6 changed files with 325 additions and 377 deletions

122
cc/cc.go
View file

@ -50,9 +50,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) {
ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("version", versionMutator).Parallel()
ctx.BottomUp("begin", BeginMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel()
ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel() ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel()
ctx.BottomUp("vendor_snapshot", VendorSnapshotMutator).Parallel()
ctx.BottomUp("vendor_snapshot_source", VendorSnapshotSourceMutator).Parallel() ctx.BottomUp("vendor_snapshot_source", VendorSnapshotSourceMutator).Parallel()
ctx.BottomUp("recovery_snapshot", RecoverySnapshotMutator).Parallel()
ctx.BottomUp("recovery_snapshot_source", RecoverySnapshotSourceMutator).Parallel() ctx.BottomUp("recovery_snapshot_source", RecoverySnapshotSourceMutator).Parallel()
}) })
@ -1937,6 +1935,40 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs 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{} variantNdkLibs := []string{}
variantLateNdkLibs := []string{} variantLateNdkLibs := []string{}
if ctx.Os() == android.Android { if ctx.Os() == android.Android {
@ -1956,21 +1988,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
// nonvariantLibs // nonvariantLibs
vendorPublicLibraries := vendorPublicLibraries(actx.Config()) 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) { rewriteLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) {
variantLibs = []string{} variantLibs = []string{}
@ -1979,21 +1996,11 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
// strip #version suffix out // strip #version suffix out
name, _ := StubsLibNameAndVersion(entry) name, _ := StubsLibNameAndVersion(entry)
if c.InRecovery() { if c.InRecovery() {
recoverySnapshotVersion := nonvariantLibs = append(nonvariantLibs, rewriteSnapshotLib(entry, getSnapshot().SharedLibs))
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)
}
} else if ctx.useSdk() && inList(name, *getNDKKnownLibs(ctx.Config())) { } else if ctx.useSdk() && inList(name, *getNDKKnownLibs(ctx.Config())) {
variantLibs = append(variantLibs, name+ndkLibrarySuffix) variantLibs = append(variantLibs, name+ndkLibrarySuffix)
} else if ctx.useVndk() { } 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) { } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, *vendorPublicLibraries) {
vendorPublicLib := name + vendorPublicLibrarySuffix vendorPublicLib := name + vendorPublicLibrarySuffix
if actx.OtherModuleExists(vendorPublicLib) { if actx.OtherModuleExists(vendorPublicLib) {
@ -2015,56 +2022,19 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
deps.SharedLibs, variantNdkLibs = rewriteLibs(deps.SharedLibs) deps.SharedLibs, variantNdkLibs = rewriteLibs(deps.SharedLibs)
deps.LateSharedLibs, variantLateNdkLibs = rewriteLibs(deps.LateSharedLibs) deps.LateSharedLibs, variantLateNdkLibs = rewriteLibs(deps.LateSharedLibs)
deps.ReexportSharedLibHeaders, _ = rewriteLibs(deps.ReexportSharedLibHeaders) deps.ReexportSharedLibHeaders, _ = rewriteLibs(deps.ReexportSharedLibHeaders)
if ctx.useVndk() {
for idx, lib := range deps.RuntimeLibs { for idx, lib := range deps.RuntimeLibs {
deps.RuntimeLibs[idx] = rewriteVendorLibs(lib) 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 { for _, lib := range deps.HeaderLibs {
depTag := libraryDependencyTag{Kind: headerLibraryDependency} depTag := libraryDependencyTag{Kind: headerLibraryDependency}
if inList(lib, deps.ReexportHeaderLibHeaders) { if inList(lib, deps.ReexportHeaderLibHeaders) {
depTag.reexportFlags = true depTag.reexportFlags = true
} }
lib = rewriteSnapshotLibs(lib, snapshotHeaderLibs) lib = rewriteSnapshotLib(lib, getSnapshot().HeaderLibs)
if c.IsStubs() { if c.IsStubs() {
actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
@ -2087,7 +2057,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
lib = impl lib = impl
} }
lib = rewriteSnapshotLibs(lib, snapshotStaticLibs) lib = rewriteSnapshotLib(lib, getSnapshot().StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
@ -2107,7 +2077,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
lib = impl lib = impl
} }
lib = rewriteSnapshotLibs(lib, snapshotStaticLibs) lib = rewriteSnapshotLib(lib, getSnapshot().StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
@ -2121,14 +2091,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true} depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true}
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
}, depTag, rewriteSnapshotLibs(staticUnwinder(actx), snapshotStaticLibs)) }, depTag, rewriteSnapshotLib(staticUnwinder(actx), getSnapshot().StaticLibs))
} }
for _, lib := range deps.LateStaticLibs { for _, lib := range deps.LateStaticLibs {
depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency} depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
}, depTag, rewriteSnapshotLibs(lib, snapshotStaticLibs)) }, depTag, rewriteSnapshotLib(lib, getSnapshot().StaticLibs))
} }
// shared lib names without the #version suffix // shared lib names without the #version suffix
@ -2192,11 +2162,11 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...) actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...)
if deps.CrtBegin != "" { if deps.CrtBegin != "" {
actx.AddVariationDependencies(crtVariations, CrtBeginDepTag, actx.AddVariationDependencies(crtVariations, CrtBeginDepTag,
rewriteSnapshotLibs(deps.CrtBegin, snapshotObjects)) rewriteSnapshotLib(deps.CrtBegin, getSnapshot().Objects))
} }
if deps.CrtEnd != "" { if deps.CrtEnd != "" {
actx.AddVariationDependencies(crtVariations, CrtEndDepTag, actx.AddVariationDependencies(crtVariations, CrtEndDepTag,
rewriteSnapshotLibs(deps.CrtEnd, snapshotObjects)) rewriteSnapshotLib(deps.CrtEnd, getSnapshot().Objects))
} }
if deps.LinkerFlagsFile != "" { if deps.LinkerFlagsFile != "" {
actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile) actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)

View file

@ -1149,13 +1149,11 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
// added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module // added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
if c.staticBinary() { if c.staticBinary() {
deps := append(extraStaticDeps, runtimeLibrary) deps := append(extraStaticDeps, runtimeLibrary)
// If we're using snapshots and in vendor, redirect to snapshot whenever possible // If we're using snapshots, redirect to snapshot whenever possible
if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() { snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
snapshots := vendorSnapshotStaticLibs(mctx.Config()) for idx, dep := range deps {
for idx, dep := range deps { if lib, ok := snapshot.StaticLibs[dep]; ok {
if lib, ok := snapshots.get(dep, mctx.Arch().ArchType); ok { deps[idx] = lib
deps[idx] = lib
}
} }
} }
@ -1168,13 +1166,12 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
} }
mctx.AddFarVariationDependencies(variations, depTag, deps...) mctx.AddFarVariationDependencies(variations, depTag, deps...)
} else if !c.static() && !c.Header() { } else if !c.static() && !c.Header() {
// If we're using snapshots and in vendor, redirect to snapshot whenever possible // If we're using snapshots, redirect to snapshot whenever possible
if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() { snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
snapshots := vendorSnapshotSharedLibs(mctx.Config()) if lib, ok := snapshot.SharedLibs[runtimeLibrary]; ok {
if lib, ok := snapshots.get(runtimeLibrary, mctx.Arch().ArchType); ok { runtimeLibrary = lib
runtimeLibrary = lib
}
} }
// Skip apex dependency check for sharedLibraryDependency // Skip apex dependency check for sharedLibraryDependency
// when sanitizer diags are enabled. Skipping the check will allow // when sanitizer diags are enabled. Skipping the check will allow
// building with diag libraries without having to list the // building with diag libraries without having to list the

View file

@ -75,5 +75,7 @@ func sdkMutator(ctx android.BottomUpMutatorContext) {
} }
ctx.AliasVariation("") ctx.AliasVariation("")
} }
case *snapshot:
ctx.CreateVariations("")
} }
} }

View file

@ -23,15 +23,13 @@ import (
"android/soong/android" "android/soong/android"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
) )
// Defines the specifics of different images to which the snapshot process is applicable, e.g., // Defines the specifics of different images to which the snapshot process is applicable, e.g.,
// vendor, recovery, ramdisk. // vendor, recovery, ramdisk.
type snapshotImage interface { type snapshotImage interface {
// Used to register callbacks with the build system.
init()
// Returns true if a snapshot should be generated for this image. // Returns true if a snapshot should be generated for this image.
shouldGenerateSnapshot(ctx android.SingletonContext) bool shouldGenerateSnapshot(ctx android.SingletonContext) bool
@ -61,10 +59,6 @@ type snapshotImage interface {
// exclude_from_recovery_snapshot properties. // exclude_from_recovery_snapshot properties.
excludeFromSnapshot(m *Module) bool 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. // Returns mutex used for mutual exclusion when updating the snapshot maps.
getMutex() *sync.Mutex getMutex() *sync.Mutex
@ -77,30 +71,38 @@ type snapshotImage interface {
// Returns true if the build is using a snapshot for this image. // Returns true if the build is using a snapshot for this image.
isUsingSnapshot(cfg android.DeviceConfig) bool isUsingSnapshot(cfg android.DeviceConfig) bool
// Whether to skip the module mutator for a module in a given context. // Returns a version of which the snapshot should be used in this target.
skipModuleMutator(ctx android.BottomUpMutatorContext) bool // This will only be meaningful when isUsingSnapshot is true.
targetSnapshotVersion(cfg android.DeviceConfig) string
// Whether to skip the source mutator for a given module.
skipSourceMutator(ctx android.BottomUpMutatorContext) bool
// Whether to exclude a given module from the directed snapshot or not. // 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, // 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. // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured.
excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool 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 vendorSnapshotImage struct{}
type recoverySnapshotImage struct{} type recoverySnapshotImage struct{}
func (vendorSnapshotImage) init() { func (vendorSnapshotImage) init(ctx android.RegistrationContext) {
android.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
android.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory)
android.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
android.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory) 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 { func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
@ -129,25 +131,6 @@ func (vendorSnapshotImage) excludeFromSnapshot(m *Module) bool {
return m.ExcludeFromVendorSnapshot() 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 { func (vendorSnapshotImage) getMutex() *sync.Mutex {
return &vendorSnapshotsLock return &vendorSnapshotsLock
} }
@ -176,26 +159,8 @@ func (vendorSnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
return vndkVersion != "current" && vndkVersion != "" return vndkVersion != "current" && vndkVersion != ""
} }
func (vendorSnapshotImage) skipModuleMutator(ctx android.BottomUpMutatorContext) bool { func (vendorSnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string {
vndkVersion := ctx.DeviceConfig().VndkVersion() return cfg.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
} }
// returns true iff a given module SHOULD BE EXCLUDED, false if included // 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] return !cfg.VendorSnapshotModules()[name]
} }
func (recoverySnapshotImage) init() { func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
android.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton) return VendorVariationPrefix + cfg.VndkVersion()
android.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory) }
android.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory)
android.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory) func (vendorSnapshotImage) moduleNameSuffix() string {
android.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory) return vendorSuffix
android.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory) }
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 { func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
@ -245,25 +219,6 @@ func (recoverySnapshotImage) excludeFromSnapshot(m *Module) bool {
return m.ExcludeFromRecoverySnapshot() 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 { func (recoverySnapshotImage) getMutex() *sync.Mutex {
return &recoverySnapshotsLock return &recoverySnapshotsLock
} }
@ -281,14 +236,8 @@ func (recoverySnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
return recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" return recoverySnapshotVersion != "current" && recoverySnapshotVersion != ""
} }
func (recoverySnapshotImage) skipModuleMutator(ctx android.BottomUpMutatorContext) bool { func (recoverySnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string {
module, ok := ctx.Module().(*Module) return cfg.RecoverySnapshotVersion()
return !ok || !module.InRecovery()
}
func (recoverySnapshotImage) skipSourceMutator(ctx android.BottomUpMutatorContext) bool {
module, ok := ctx.Module().(*Module)
return !ok || !module.InRecovery()
} }
func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
@ -296,50 +245,172 @@ func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfi
return false return false
} }
func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
return android.RecoveryVariation
}
func (recoverySnapshotImage) moduleNameSuffix() string {
return recoverySuffix
}
var vendorSnapshotImageSingleton vendorSnapshotImage var vendorSnapshotImageSingleton vendorSnapshotImage
var recoverySnapshotImageSingleton recoverySnapshotImage var recoverySnapshotImageSingleton recoverySnapshotImage
func init() { func init() {
vendorSnapshotImageSingleton.init() vendorSnapshotImageSingleton.init(android.InitRegistrationContext)
recoverySnapshotImageSingleton.init() recoverySnapshotImageSingleton.init(android.InitRegistrationContext)
} }
const ( const (
vendorSnapshotHeaderSuffix = ".vendor_header." snapshotHeaderSuffix = "_header."
vendorSnapshotSharedSuffix = ".vendor_shared." snapshotSharedSuffix = "_shared."
vendorSnapshotStaticSuffix = ".vendor_static." snapshotStaticSuffix = "_static."
vendorSnapshotBinarySuffix = ".vendor_binary." snapshotBinarySuffix = "_binary."
vendorSnapshotObjectSuffix = ".vendor_object." snapshotObjectSuffix = "_object."
)
const (
recoverySnapshotHeaderSuffix = ".recovery_header."
recoverySnapshotSharedSuffix = ".recovery_shared."
recoverySnapshotStaticSuffix = ".recovery_static."
recoverySnapshotBinarySuffix = ".recovery_binary."
recoverySnapshotObjectSuffix = ".recovery_object."
) )
var ( var (
vendorSnapshotsLock sync.Mutex vendorSnapshotsLock sync.Mutex
vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules") vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules")
vendorSnapshotHeaderLibsKey = android.NewOnceKey("vendorSnapshotHeaderLibs")
vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs")
vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs")
vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries")
vendorSnapshotObjectsKey = android.NewOnceKey("vendorSnapshotObjects")
) )
var ( var (
recoverySnapshotsLock sync.Mutex recoverySnapshotsLock sync.Mutex
recoverySuffixModulesKey = android.NewOnceKey("recoverySuffixModules") recoverySuffixModulesKey = android.NewOnceKey("recoverySuffixModules")
recoverySnapshotHeaderLibsKey = android.NewOnceKey("recoverySnapshotHeaderLibs")
recoverySnapshotStaticLibsKey = android.NewOnceKey("recoverySnapshotStaticLibs")
recoverySnapshotSharedLibsKey = android.NewOnceKey("recoverySnapshotSharedLibs")
recoverySnapshotBinariesKey = android.NewOnceKey("recoverySnapshotBinaries")
recoverySnapshotObjectsKey = android.NewOnceKey("recoverySnapshotObjects")
) )
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. // 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 // This is determined by source modules, and then this will be used when exporting snapshot modules
// to Makefile. // to Makefile.
@ -355,73 +426,12 @@ func vendorSuffixModules(config android.Config) map[string]bool {
}).(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 { func recoverySuffixModules(config android.Config) map[string]bool {
return config.Once(recoverySuffixModulesKey, func() interface{} { return config.Once(recoverySuffixModulesKey, func() interface{} {
return make(map[string]bool) return make(map[string]bool)
}).(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 { type baseSnapshotDecoratorProperties struct {
// snapshot version. // snapshot version.
Version string Version string
@ -431,7 +441,7 @@ type baseSnapshotDecoratorProperties struct {
// Suffix to be added to the module name, e.g., vendor_shared, // Suffix to be added to the module name, e.g., vendor_shared,
// recovery_shared, etc. // recovery_shared, etc.
Module_suffix string ModuleSuffix string `blueprint:"mutated"`
} }
// baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot // baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
@ -460,7 +470,7 @@ func (p *baseSnapshotDecorator) NameSuffix() string {
versionSuffix += "." + p.arch() versionSuffix += "." + p.arch()
} }
return p.baseProperties.Module_suffix + versionSuffix return p.baseProperties.ModuleSuffix + versionSuffix
} }
func (p *baseSnapshotDecorator) version() string { func (p *baseSnapshotDecorator) version() string {
@ -471,8 +481,8 @@ func (p *baseSnapshotDecorator) arch() string {
return p.baseProperties.Target_arch return p.baseProperties.Target_arch
} }
func (p *baseSnapshotDecorator) module_suffix() string { func (p *baseSnapshotDecorator) moduleSuffix() string {
return p.baseProperties.Module_suffix return p.baseProperties.ModuleSuffix
} }
func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool { 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 // Call this with a module suffix after creating a snapshot module, such as
// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc. // vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc.
func (p *baseSnapshotDecorator) init(m *Module, suffix string) { func (p *baseSnapshotDecorator) init(m *Module, snapshotSuffix, moduleSuffix string) {
p.baseProperties.Module_suffix = suffix p.baseProperties.ModuleSuffix = snapshotSuffix + moduleSuffix
m.AddProperties(&p.baseProperties) m.AddProperties(&p.baseProperties)
android.AddLoadHook(m, func(ctx android.LoadHookContext) { android.AddLoadHook(m, func(ctx android.LoadHookContext) {
vendorSnapshotLoadHook(ctx, p) 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, library := NewLibrary(android.DeviceSupported)
module.stl = nil module.stl = nil
@ -678,7 +688,7 @@ func snapshotLibraryFactory(suffix string) (*Module, *snapshotLibraryDecorator)
module.linker = prebuilt module.linker = prebuilt
module.installer = prebuilt module.installer = prebuilt
prebuilt.init(module, suffix) prebuilt.init(module, snapshotSuffix, moduleSuffix)
module.AddProperties( module.AddProperties(
&prebuilt.properties, &prebuilt.properties,
&prebuilt.sanitizerProperties, &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 // overrides the vendor variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
// is set. // is set.
func VendorSnapshotSharedFactory() android.Module { func VendorSnapshotSharedFactory() android.Module {
module, prebuilt := snapshotLibraryFactory(vendorSnapshotSharedSuffix) module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared() prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init() 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 // overrides the recovery variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
// is set. // is set.
func RecoverySnapshotSharedFactory() android.Module { func RecoverySnapshotSharedFactory() android.Module {
module, prebuilt := snapshotLibraryFactory(recoverySnapshotSharedSuffix) module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared() prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init() 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 // overrides the vendor variant of the cc static library with the same name, if BOARD_VNDK_VERSION
// is set. // is set.
func VendorSnapshotStaticFactory() android.Module { func VendorSnapshotStaticFactory() android.Module {
module, prebuilt := snapshotLibraryFactory(vendorSnapshotStaticSuffix) module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic() prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init() 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 // overrides the recovery variant of the cc static library with the same name, if BOARD_VNDK_VERSION
// is set. // is set.
func RecoverySnapshotStaticFactory() android.Module { func RecoverySnapshotStaticFactory() android.Module {
module, prebuilt := snapshotLibraryFactory(recoverySnapshotStaticSuffix) module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic() prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init() 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 // overrides the vendor variant of the cc header library with the same name, if BOARD_VNDK_VERSION
// is set. // is set.
func VendorSnapshotHeaderFactory() android.Module { func VendorSnapshotHeaderFactory() android.Module {
module, prebuilt := snapshotLibraryFactory(vendorSnapshotHeaderSuffix) module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotHeaderSuffix)
prebuilt.libraryDecorator.HeaderOnly() prebuilt.libraryDecorator.HeaderOnly()
return module.Init() 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 // overrides the recovery variant of the cc header library with the same name, if BOARD_VNDK_VERSION
// is set. // is set.
func RecoverySnapshotHeaderFactory() android.Module { func RecoverySnapshotHeaderFactory() android.Module {
module, prebuilt := snapshotLibraryFactory(recoverySnapshotHeaderSuffix) module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotHeaderSuffix)
prebuilt.libraryDecorator.HeaderOnly() prebuilt.libraryDecorator.HeaderOnly()
return module.Init() 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 // 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. // overrides the vendor variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
func VendorSnapshotBinaryFactory() android.Module { 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 // 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 // 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. // overrides the recovery variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
func RecoverySnapshotBinaryFactory() android.Module { 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) module, binary := NewBinary(android.DeviceSupported)
binary.baseLinker.Properties.No_libcrt = BoolPtr(true) binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
binary.baseLinker.Properties.Nocrt = BoolPtr(true) binary.baseLinker.Properties.Nocrt = BoolPtr(true)
@ -846,7 +856,7 @@ func snapshotBinaryFactory(suffix string) android.Module {
module.stl = nil module.stl = nil
module.linker = prebuilt module.linker = prebuilt
prebuilt.init(module, suffix) prebuilt.init(module, snapshotSuffix, moduleSuffix)
module.AddProperties(&prebuilt.properties) module.AddProperties(&prebuilt.properties)
return module.Init() return module.Init()
} }
@ -915,7 +925,7 @@ func VendorSnapshotObjectFactory() android.Module {
} }
module.linker = prebuilt module.linker = prebuilt
prebuilt.init(module, vendorSnapshotObjectSuffix) prebuilt.init(module, vendorSnapshotImageSingleton.moduleNameSuffix(), snapshotObjectSuffix)
module.AddProperties(&prebuilt.properties) module.AddProperties(&prebuilt.properties)
return module.Init() return module.Init()
} }
@ -933,7 +943,7 @@ func RecoverySnapshotObjectFactory() android.Module {
} }
module.linker = prebuilt module.linker = prebuilt
prebuilt.init(module, recoverySnapshotObjectSuffix) prebuilt.init(module, recoverySnapshotImageSingleton.moduleNameSuffix(), snapshotObjectSuffix)
module.AddProperties(&prebuilt.properties) module.AddProperties(&prebuilt.properties)
return module.Init() return module.Init()
} }
@ -951,59 +961,6 @@ var _ snapshotInterface = (*snapshotObjectLinker)(nil)
// Mutators that helps vendor snapshot modules override source modules. // 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. // VendorSnapshotSourceMutator disables source modules which have corresponding snapshots.
func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) { func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
snapshotSourceMutator(ctx, vendorSnapshotImageSingleton) snapshotSourceMutator(ctx, vendorSnapshotImageSingleton)
@ -1033,30 +990,4 @@ func snapshotSourceMutator(ctx android.BottomUpMutatorContext, image snapshotIma
image.suffixModules(ctx.Config())[ctx.ModuleName()] = true 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()
}
} }

View file

@ -586,17 +586,13 @@ func CreateTestContext(config android.Config) *android.TestContext {
ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory) ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) vendorSnapshotImageSingleton.init(ctx)
ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) recoverySnapshotImageSingleton.init(ctx)
ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
RegisterVndkLibraryTxtTypes(ctx) RegisterVndkLibraryTxtTypes(ctx)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
android.RegisterPrebuiltMutators(ctx) android.RegisterPrebuiltMutators(ctx)
RegisterRequiredBuildComponentsForTest(ctx) RegisterRequiredBuildComponentsForTest(ctx)
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton)
return ctx return ctx
} }

View file

@ -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 := ` vendorProprietaryBp := `
@ -367,6 +385,27 @@ func TestVendorSnapshotUse(t *testing.T) {
srcs: ["bin.cpp"], 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 { vendor_snapshot_static {
name: "libvndk", name: "libvndk",
version: "BOARD", 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) depsBp := GatherRequiredDepsForTest(android.Android)