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("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)

View File

@ -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

View File

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

View File

@ -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()
}
}

View File

@ -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
}

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 := `
@ -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)