Add some comments for VNDK / vendor snapshots
Also some files are refactored:
- snapshot_prebuilt.go is separated from vendor_snapshot.go. Now
vendor_snapshot.go contains snapshot generation codes, while
snapshot_prebuilt.go contains module definition codes.
- Some helper functions are moved from snapshot_utils.go to util.go.
- Some ambiguous names of types and functions are renamed.
We still can add more detailed comments about the snapshots. They are to
be uploaded in follow-up changes, to avoid making this change too big.
Bug: 173474311
Test: generate vndk and vendor snapshot
Change-Id: I18fa837ccdf44a042b7a78e5c3df25fd2de96d95
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 3ef0b62..25960ab 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -13,625 +13,27 @@
// limitations under the License.
package cc
+// This file contains singletons to capture vendor and recovery snapshot. They consist of prebuilt
+// modules under AOSP so older vendor and recovery can be built with a newer system in a single
+// source tree.
+
import (
"encoding/json"
"path/filepath"
"sort"
"strings"
- "sync"
"github.com/google/blueprint/proptools"
"android/soong/android"
)
-// Defines the specifics of different images to which the snapshot process is
-// applicable, e.g., vendor, recovery, ramdisk.
-type image interface {
- // Used to register callbacks with the build system.
- init()
-
- // Function that returns true if the module is included in this image.
- // Using a function return instead of a value to prevent early
- // evalution of a function that may be not be defined.
- inImage(m *Module) func() bool
-
- // Returns the value of the "available" property for a given module for
- // and snapshot, e.g., "vendor_available", "recovery_available", etc.
- // or nil if the property is not defined.
- available(m *Module) *bool
-
- // Returns true if a dir under source tree is an SoC-owned proprietary
- // directory, such as device/, vendor/, etc.
- //
- // For a given snapshot (e.g., vendor, recovery, etc.) if
- // isProprietaryPath(dir) returns true, then the module in dir will be
- // built from sources.
- isProprietaryPath(dir string) bool
-
- // Whether to include VNDK in the snapshot for this image.
- includeVndk() bool
-
- // Whether a given module has been explicitly excluded from the
- // snapshot, e.g., using the exclude_from_vendor_snapshot or
- // exclude_from_recovery_snapshot properties.
- excludeFromSnapshot(m *Module) bool
-}
-
-type vendorImage struct{}
-type recoveryImage struct{}
-
-func (vendorImage) 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 (vendorImage) inImage(m *Module) func() bool {
- return m.inVendor
-}
-
-func (vendorImage) available(m *Module) *bool {
- return m.VendorProperties.Vendor_available
-}
-
-func (vendorImage) isProprietaryPath(dir string) bool {
- return isVendorProprietaryPath(dir)
-}
-
-func (vendorImage) includeVndk() bool {
- return true
-}
-
-func (vendorImage) excludeFromSnapshot(m *Module) bool {
- return m.ExcludeFromVendorSnapshot()
-}
-
-func (recoveryImage) 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 (recoveryImage) inImage(m *Module) func() bool {
- return m.InRecovery
-}
-
-func (recoveryImage) available(m *Module) *bool {
- return m.Properties.Recovery_available
-}
-
-func (recoveryImage) isProprietaryPath(dir string) bool {
- return isRecoveryProprietaryPath(dir)
-}
-
-func (recoveryImage) includeVndk() bool {
- return false
-}
-
-func (recoveryImage) excludeFromSnapshot(m *Module) bool {
- return m.ExcludeFromRecoverySnapshot()
-}
-
-var vendorImageSingleton vendorImage
-var recoveryImageSingleton recoveryImage
-
-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."
-)
-
-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")
-)
-
-// vendor snapshot maps hold names of vendor snapshot modules per arch
-func vendorSuffixModules(config android.Config) map[string]bool {
- return config.Once(vendorSuffixModulesKey, func() interface{} {
- return make(map[string]bool)
- }).(map[string]bool)
-}
-
-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)
-}
-
-type vendorSnapshotBaseProperties struct {
- // snapshot version.
- Version string
-
- // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
- Target_arch string
-}
-
-// vendorSnapshotModuleBase provides common basic functions for all snapshot modules.
-type vendorSnapshotModuleBase struct {
- baseProperties vendorSnapshotBaseProperties
- moduleSuffix string
-}
-
-func (p *vendorSnapshotModuleBase) Name(name string) string {
- return name + p.NameSuffix()
-}
-
-func (p *vendorSnapshotModuleBase) NameSuffix() string {
- versionSuffix := p.version()
- if p.arch() != "" {
- versionSuffix += "." + p.arch()
- }
-
- return p.moduleSuffix + versionSuffix
-}
-
-func (p *vendorSnapshotModuleBase) version() string {
- return p.baseProperties.Version
-}
-
-func (p *vendorSnapshotModuleBase) arch() string {
- return p.baseProperties.Target_arch
-}
-
-func (p *vendorSnapshotModuleBase) isSnapshotPrebuilt() bool {
- return true
-}
-
-// Call this after creating a snapshot module with module suffix
-// such as vendorSnapshotSharedSuffix
-func (p *vendorSnapshotModuleBase) init(m *Module, suffix string) {
- p.moduleSuffix = suffix
- m.AddProperties(&p.baseProperties)
- android.AddLoadHook(m, func(ctx android.LoadHookContext) {
- vendorSnapshotLoadHook(ctx, p)
- })
-}
-
-func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *vendorSnapshotModuleBase) {
- if p.version() != ctx.DeviceConfig().VndkVersion() {
- ctx.Module().Disable()
- return
- }
-}
-
-type snapshotLibraryProperties struct {
- // Prebuilt file for each arch.
- Src *string `android:"arch_variant"`
-
- // list of directories that will be added to the include path (using -I).
- Export_include_dirs []string `android:"arch_variant"`
-
- // list of directories that will be added to the system path (using -isystem).
- Export_system_include_dirs []string `android:"arch_variant"`
-
- // list of flags that will be used for any module that links against this module.
- Export_flags []string `android:"arch_variant"`
-
- // Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
- Sanitize_ubsan_dep *bool `android:"arch_variant"`
-
- // Whether this prebuilt needs to depend on sanitize minimal runtime or not.
- Sanitize_minimal_dep *bool `android:"arch_variant"`
-}
-
-type snapshotSanitizer interface {
- isSanitizerEnabled(t sanitizerType) bool
- setSanitizerVariation(t sanitizerType, enabled bool)
-}
-
-type snapshotLibraryDecorator struct {
- vendorSnapshotModuleBase
- *libraryDecorator
- properties snapshotLibraryProperties
- sanitizerProperties struct {
- CfiEnabled bool `blueprint:"mutated"`
-
- // Library flags for cfi variant.
- Cfi snapshotLibraryProperties `android:"arch_variant"`
- }
- androidMkVendorSuffix bool
-}
-
-func (p *snapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
- return p.libraryDecorator.linkerFlags(ctx, flags)
-}
-
-func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
- arches := config.Arches()
- if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
- return false
- }
- if !p.header() && p.properties.Src == nil {
- return false
- }
- return true
-}
-
-func (p *snapshotLibraryDecorator) link(ctx ModuleContext,
- flags Flags, deps PathDeps, objs Objects) android.Path {
- m := ctx.Module().(*Module)
- p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
-
- if p.header() {
- return p.libraryDecorator.link(ctx, flags, deps, objs)
- }
-
- if p.sanitizerProperties.CfiEnabled {
- p.properties = p.sanitizerProperties.Cfi
- }
-
- if !p.matchesWithDevice(ctx.DeviceConfig()) {
- return nil
- }
-
- p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
- p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
- p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
-
- in := android.PathForModuleSrc(ctx, *p.properties.Src)
- p.unstrippedOutputFile = in
-
- if p.shared() {
- libName := in.Base()
- builderFlags := flagsToBuilderFlags(flags)
-
- // Optimize out relinking against shared libraries whose interface hasn't changed by
- // depending on a table of contents file instead of the library itself.
- tocFile := android.PathForModuleOut(ctx, libName+".toc")
- p.tocFile = android.OptionalPathForPath(tocFile)
- transformSharedObjectToToc(ctx, in, tocFile, builderFlags)
-
- ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
- SharedLibrary: in,
- UnstrippedSharedLibrary: p.unstrippedOutputFile,
-
- TableOfContents: p.tocFile,
- })
- }
-
- if p.static() {
- depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
- ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
- StaticLibrary: in,
-
- TransitiveStaticLibrariesForOrdering: depSet,
- })
- }
-
- p.libraryDecorator.flagExporter.setProvider(ctx)
-
- return in
-}
-
-func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
- if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
- p.baseInstaller.install(ctx, file)
- }
-}
-
-func (p *snapshotLibraryDecorator) nativeCoverage() bool {
- return false
-}
-
-func (p *snapshotLibraryDecorator) isSanitizerEnabled(t sanitizerType) bool {
- switch t {
- case cfi:
- return p.sanitizerProperties.Cfi.Src != nil
- default:
- return false
- }
-}
-
-func (p *snapshotLibraryDecorator) setSanitizerVariation(t sanitizerType, enabled bool) {
- if !enabled {
- return
- }
- switch t {
- case cfi:
- p.sanitizerProperties.CfiEnabled = true
- default:
- return
- }
-}
-
-func snapshotLibrary(suffix string) (*Module, *snapshotLibraryDecorator) {
- module, library := NewLibrary(android.DeviceSupported)
-
- module.stl = nil
- module.sanitize = nil
- library.disableStripping()
-
- prebuilt := &snapshotLibraryDecorator{
- libraryDecorator: library,
- }
-
- prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
- prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
-
- // Prevent default system libs (libc, libm, and libdl) from being linked
- if prebuilt.baseLinker.Properties.System_shared_libs == nil {
- prebuilt.baseLinker.Properties.System_shared_libs = []string{}
- }
-
- module.compiler = nil
- module.linker = prebuilt
- module.installer = prebuilt
-
- prebuilt.init(module, suffix)
- module.AddProperties(
- &prebuilt.properties,
- &prebuilt.sanitizerProperties,
- )
-
- return module, prebuilt
-}
-
-func VendorSnapshotSharedFactory() android.Module {
- module, prebuilt := snapshotLibrary(vendorSnapshotSharedSuffix)
- prebuilt.libraryDecorator.BuildOnlyShared()
- return module.Init()
-}
-
-func RecoverySnapshotSharedFactory() android.Module {
- module, prebuilt := snapshotLibrary(recoverySnapshotSharedSuffix)
- prebuilt.libraryDecorator.BuildOnlyShared()
- return module.Init()
-}
-
-func VendorSnapshotStaticFactory() android.Module {
- module, prebuilt := snapshotLibrary(vendorSnapshotStaticSuffix)
- prebuilt.libraryDecorator.BuildOnlyStatic()
- return module.Init()
-}
-
-func RecoverySnapshotStaticFactory() android.Module {
- module, prebuilt := snapshotLibrary(recoverySnapshotStaticSuffix)
- prebuilt.libraryDecorator.BuildOnlyStatic()
- return module.Init()
-}
-
-func VendorSnapshotHeaderFactory() android.Module {
- module, prebuilt := snapshotLibrary(vendorSnapshotHeaderSuffix)
- prebuilt.libraryDecorator.HeaderOnly()
- return module.Init()
-}
-
-func RecoverySnapshotHeaderFactory() android.Module {
- module, prebuilt := snapshotLibrary(recoverySnapshotHeaderSuffix)
- prebuilt.libraryDecorator.HeaderOnly()
- return module.Init()
-}
-
-var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil)
-
-type snapshotBinaryProperties struct {
- // Prebuilt file for each arch.
- Src *string `android:"arch_variant"`
-}
-
-type snapshotBinaryDecorator struct {
- vendorSnapshotModuleBase
- *binaryDecorator
- properties snapshotBinaryProperties
- androidMkVendorSuffix bool
-}
-
-func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
- if config.DeviceArch() != p.arch() {
- return false
- }
- if p.properties.Src == nil {
- return false
- }
- return true
-}
-
-func (p *snapshotBinaryDecorator) link(ctx ModuleContext,
- flags Flags, deps PathDeps, objs Objects) android.Path {
- if !p.matchesWithDevice(ctx.DeviceConfig()) {
- return nil
- }
-
- in := android.PathForModuleSrc(ctx, *p.properties.Src)
- stripFlags := flagsToStripFlags(flags)
- p.unstrippedOutputFile = in
- binName := in.Base()
- if p.stripper.NeedsStrip(ctx) {
- stripped := android.PathForModuleOut(ctx, "stripped", binName)
- p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
- in = stripped
- }
-
- m := ctx.Module().(*Module)
- p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
-
- // use cpExecutable to make it executable
- outputFile := android.PathForModuleOut(ctx, binName)
- ctx.Build(pctx, android.BuildParams{
- Rule: android.CpExecutable,
- Description: "prebuilt",
- Output: outputFile,
- Input: in,
- })
-
- return outputFile
-}
-
-func (p *snapshotBinaryDecorator) nativeCoverage() bool {
- return false
-}
-
-func VendorSnapshotBinaryFactory() android.Module {
- return snapshotBinaryFactory(vendorSnapshotBinarySuffix)
-}
-
-func RecoverySnapshotBinaryFactory() android.Module {
- return snapshotBinaryFactory(recoverySnapshotBinarySuffix)
-}
-
-func snapshotBinaryFactory(suffix string) android.Module {
- module, binary := NewBinary(android.DeviceSupported)
- binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
- binary.baseLinker.Properties.Nocrt = BoolPtr(true)
-
- // Prevent default system libs (libc, libm, and libdl) from being linked
- if binary.baseLinker.Properties.System_shared_libs == nil {
- binary.baseLinker.Properties.System_shared_libs = []string{}
- }
-
- prebuilt := &snapshotBinaryDecorator{
- binaryDecorator: binary,
- }
-
- module.compiler = nil
- module.sanitize = nil
- module.stl = nil
- module.linker = prebuilt
-
- prebuilt.init(module, suffix)
- module.AddProperties(&prebuilt.properties)
- return module.Init()
-}
-
-type vendorSnapshotObjectProperties struct {
- // Prebuilt file for each arch.
- Src *string `android:"arch_variant"`
-}
-
-type snapshotObjectLinker struct {
- vendorSnapshotModuleBase
- objectLinker
- properties vendorSnapshotObjectProperties
- androidMkVendorSuffix bool
-}
-
-func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
- if config.DeviceArch() != p.arch() {
- return false
- }
- if p.properties.Src == nil {
- return false
- }
- return true
-}
-
-func (p *snapshotObjectLinker) link(ctx ModuleContext,
- flags Flags, deps PathDeps, objs Objects) android.Path {
- if !p.matchesWithDevice(ctx.DeviceConfig()) {
- return nil
- }
-
- m := ctx.Module().(*Module)
- p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
-
- return android.PathForModuleSrc(ctx, *p.properties.Src)
-}
-
-func (p *snapshotObjectLinker) nativeCoverage() bool {
- return false
-}
-
-func VendorSnapshotObjectFactory() android.Module {
- module := newObject()
-
- prebuilt := &snapshotObjectLinker{
- objectLinker: objectLinker{
- baseLinker: NewBaseLinker(nil),
- },
- }
- module.linker = prebuilt
-
- prebuilt.init(module, vendorSnapshotObjectSuffix)
- module.AddProperties(&prebuilt.properties)
- return module.Init()
-}
-
-func RecoverySnapshotObjectFactory() android.Module {
- module := newObject()
-
- prebuilt := &snapshotObjectLinker{
- objectLinker: objectLinker{
- baseLinker: NewBaseLinker(nil),
- },
- }
- module.linker = prebuilt
-
- prebuilt.init(module, recoverySnapshotObjectSuffix)
- module.AddProperties(&prebuilt.properties)
- return module.Init()
-}
-
-func init() {
- vendorImageSingleton.init()
- recoveryImageSingleton.init()
-}
-
var vendorSnapshotSingleton = snapshotSingleton{
"vendor",
"SOONG_VENDOR_SNAPSHOT_ZIP",
android.OptionalPath{},
true,
- vendorImageSingleton,
+ vendorSnapshotImageSingleton,
}
var recoverySnapshotSingleton = snapshotSingleton{
@@ -639,7 +41,7 @@
"SOONG_RECOVERY_SNAPSHOT_ZIP",
android.OptionalPath{},
false,
- recoveryImageSingleton,
+ recoverySnapshotImageSingleton,
}
func VendorSnapshotSingleton() android.Singleton {
@@ -667,13 +69,12 @@
// Implementation of the image interface specific to the image
// associated with this snapshot (e.g., specific to the vendor image,
// recovery image, etc.).
- image image
+ image snapshotImage
}
var (
// Modules under following directories are ignored. They are OEM's and vendor's
// proprietary modules(device/, kernel/, vendor/, and hardware/).
- // TODO(b/65377115): Clean up these with more maintainable way
vendorProprietaryDirs = []string{
"device",
"kernel",
@@ -683,7 +84,6 @@
// Modules under following directories are ignored. They are OEM's and vendor's
// proprietary modules(device/, kernel/, vendor/, and hardware/).
- // TODO(b/65377115): Clean up these with more maintainable way
recoveryProprietaryDirs = []string{
"bootable/recovery",
"device",
@@ -694,7 +94,6 @@
// Modules under following directories are included as they are in AOSP,
// although hardware/ and kernel/ are normally for vendor's own.
- // TODO(b/65377115): Clean up these with more maintainable way
aospDirsUnderProprietary = []string{
"kernel/configs",
"kernel/prebuilts",
@@ -738,10 +137,8 @@
}
func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
-
// Any module in a vendor proprietary path is a vendor proprietary
// module.
-
if isVendorProprietaryPath(ctx.ModuleDir()) {
return true
}
@@ -750,7 +147,6 @@
// still be a vendor proprietary module. This happens for cc modules
// that are excluded from the vendor snapshot, and it means that the
// vendor has assumed control of the framework-provided module.
-
if c, ok := ctx.Module().(*Module); ok {
if c.ExcludeFromVendorSnapshot() {
return true
@@ -766,15 +162,21 @@
// AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might
// depend on newer VNDK) So they are captured as vendor snapshot To build older vendor
// image and newer system image altogether.
-func isVendorSnapshotModule(m *Module, inVendorProprietaryPath bool, apexInfo android.ApexInfo) bool {
- return isSnapshotModule(m, inVendorProprietaryPath, apexInfo, vendorImageSingleton)
+func isVendorSnapshotAware(m *Module, inVendorProprietaryPath bool, apexInfo android.ApexInfo) bool {
+ return isSnapshotAware(m, inVendorProprietaryPath, apexInfo, vendorSnapshotImageSingleton)
}
-func isRecoverySnapshotModule(m *Module, inRecoveryProprietaryPath bool, apexInfo android.ApexInfo) bool {
- return isSnapshotModule(m, inRecoveryProprietaryPath, apexInfo, recoveryImageSingleton)
+// Determine if a module is going to be included in recovery snapshot or not.
+//
+// Targets of recovery snapshot are "recovery: true" or "recovery_available: true"
+// modules in AOSP. They are not guaranteed to be compatible with older recovery images.
+// So they are captured as recovery snapshot To build older recovery image.
+func isRecoverySnapshotAware(m *Module, inRecoveryProprietaryPath bool, apexInfo android.ApexInfo) bool {
+ return isSnapshotAware(m, inRecoveryProprietaryPath, apexInfo, recoverySnapshotImageSingleton)
}
-func isSnapshotModule(m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image image) bool {
+// Determines if the module is a candidate for snapshot.
+func isSnapshotAware(m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
if !m.Enabled() || m.Properties.HideFromMake {
return false
}
@@ -799,7 +201,7 @@
if m.Target().NativeBridge == android.NativeBridgeEnabled {
return false
}
- // the module must be installed in /vendor
+ // the module must be installed in target image
if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !image.inImage(m)() {
return false
}
@@ -817,7 +219,6 @@
// Libraries
if l, ok := m.linker.(snapshotLibraryInterface); ok {
- // TODO(b/65377115): add full support for sanitizer
if m.sanitize != nil {
// scs and hwasan export both sanitized and unsanitized variants for static and header
// Always use unsanitized variants of them.
@@ -827,6 +228,8 @@
}
}
// cfi also exports both variants. But for static, we capture both.
+ // This is because cfi static libraries can't be linked from non-cfi modules,
+ // and vice versa. This isn't the case for scs and hwasan sanitizers.
if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
return false
}
@@ -856,6 +259,33 @@
return false
}
+// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
+// These flags become Android.bp snapshot module properties.
+type snapshotJsonFlags struct {
+ ModuleName string `json:",omitempty"`
+ RelativeInstallPath string `json:",omitempty"`
+
+ // library flags
+ ExportedDirs []string `json:",omitempty"`
+ ExportedSystemDirs []string `json:",omitempty"`
+ ExportedFlags []string `json:",omitempty"`
+ Sanitize string `json:",omitempty"`
+ SanitizeMinimalDep bool `json:",omitempty"`
+ SanitizeUbsanDep bool `json:",omitempty"`
+
+ // binary flags
+ Symlinks []string `json:",omitempty"`
+
+ // dependencies
+ SharedLibs []string `json:",omitempty"`
+ RuntimeLibs []string `json:",omitempty"`
+ Required []string `json:",omitempty"`
+
+ // extra config files
+ InitRc []string `json:",omitempty"`
+ VintfFragments []string `json:",omitempty"`
+}
+
func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
// BOARD_VNDK_VERSION must be set to 'current' in order to generate a vendor snapshot.
if ctx.DeviceConfig().VndkVersion() != "current" {
@@ -909,6 +339,8 @@
var headers android.Paths
+ // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
+ // For executables, init_rc and vintf_fragments files are also copied.
installSnapshot := func(m *Module) android.Paths {
targetArch := "arch-" + m.Target().Arch.ArchType.String()
if m.Target().Arch.ArchVariant != "" {
@@ -917,30 +349,7 @@
var ret android.Paths
- prop := struct {
- ModuleName string `json:",omitempty"`
- RelativeInstallPath string `json:",omitempty"`
-
- // library flags
- ExportedDirs []string `json:",omitempty"`
- ExportedSystemDirs []string `json:",omitempty"`
- ExportedFlags []string `json:",omitempty"`
- Sanitize string `json:",omitempty"`
- SanitizeMinimalDep bool `json:",omitempty"`
- SanitizeUbsanDep bool `json:",omitempty"`
-
- // binary flags
- Symlinks []string `json:",omitempty"`
-
- // dependencies
- SharedLibs []string `json:",omitempty"`
- RuntimeLibs []string `json:",omitempty"`
- Required []string `json:",omitempty"`
-
- // extra config files
- InitRc []string `json:",omitempty"`
- VintfFragments []string `json:",omitempty"`
- }{}
+ prop := snapshotJsonFlags{}
// Common properties among snapshots.
prop.ModuleName = ctx.ModuleName(m)
@@ -968,7 +377,7 @@
out := filepath.Join(configsDir, path.Base())
if !installedConfigs[out] {
installedConfigs[out] = true
- ret = append(ret, copyFile(ctx, path, out))
+ ret = append(ret, copyFileRule(ctx, path, out))
}
}
@@ -1019,7 +428,7 @@
prop.ModuleName += ".cfi"
}
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
- ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
+ ret = append(ret, copyFileRule(ctx, libPath, snapshotLibOut))
} else {
stem = ctx.ModuleName(m)
}
@@ -1033,7 +442,7 @@
// install bin
binPath := m.outputFile.Path()
snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
- ret = append(ret, copyFile(ctx, binPath, snapshotBinOut))
+ ret = append(ret, copyFileRule(ctx, binPath, snapshotBinOut))
propOut = snapshotBinOut + ".json"
} else if m.object() {
// object files aren't installed to the device, so their names can conflict.
@@ -1041,7 +450,7 @@
objPath := m.outputFile.Path()
snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
- ret = append(ret, copyFile(ctx, objPath, snapshotObjOut))
+ ret = append(ret, copyFileRule(ctx, objPath, snapshotObjOut))
propOut = snapshotObjOut + ".json"
} else {
ctx.Errorf("unknown module %q in vendor snapshot", m.String())
@@ -1053,7 +462,7 @@
ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
return nil
}
- ret = append(ret, writeStringToFile(ctx, string(j), propOut))
+ ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
return ret
}
@@ -1088,11 +497,14 @@
}
}
- if !isSnapshotModule(m, inProprietaryPath, apexInfo, c.image) {
+ if !isSnapshotAware(m, inProprietaryPath, apexInfo, c.image) {
return
}
+ // installSnapshot installs prebuilts and json flag files
snapshotOutputs = append(snapshotOutputs, installSnapshot(m)...)
+
+ // just gather headers and notice files here, because they are to be deduplicated
if l, ok := m.linker.(snapshotLibraryInterface); ok {
headers = append(headers, l.snapshotHeaders()...)
}
@@ -1103,7 +515,7 @@
// skip already copied notice file
if !installedNotices[noticeOut] {
installedNotices[noticeOut] = true
- snapshotOutputs = append(snapshotOutputs, combineNotices(
+ snapshotOutputs = append(snapshotOutputs, combineNoticesRule(
ctx, m.NoticeFiles(), noticeOut))
}
}
@@ -1111,7 +523,7 @@
// install all headers after removing duplicates
for _, header := range android.FirstUniquePaths(headers) {
- snapshotOutputs = append(snapshotOutputs, copyFile(
+ snapshotOutputs = append(snapshotOutputs, copyFileRule(
ctx, header, filepath.Join(includeDir, header.String())))
}
@@ -1155,141 +567,3 @@
c.makeVar,
c.snapshotZipFile.String())
}
-
-type snapshotInterface interface {
- matchesWithDevice(config android.DeviceConfig) bool
-}
-
-var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
-var _ snapshotInterface = (*snapshotLibraryDecorator)(nil)
-var _ snapshotInterface = (*snapshotBinaryDecorator)(nil)
-var _ snapshotInterface = (*snapshotObjectLinker)(nil)
-
-// gathers all snapshot modules for vendor, and disable unnecessary snapshots
-// TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules
-func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) {
- vndkVersion := ctx.DeviceConfig().VndkVersion()
- // don't need snapshot if current
- if vndkVersion == "current" || vndkVersion == "" {
- return
- }
-
- module, ok := ctx.Module().(*Module)
- if !ok || !module.Enabled() || module.VndkVersion() != vndkVersion {
- 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
-
- if lib, ok := module.linker.(libraryInterface); ok {
- if lib.static() {
- snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
- } else if lib.shared() {
- snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
- } else {
- // header
- snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
- }
- } else if _, ok := module.linker.(*snapshotBinaryDecorator); ok {
- snapshotMap = vendorSnapshotBinaries(ctx.Config())
- } else if _, ok := module.linker.(*snapshotObjectLinker); ok {
- snapshotMap = vendorSnapshotObjects(ctx.Config())
- } else {
- return
- }
-
- vendorSnapshotsLock.Lock()
- defer vendorSnapshotsLock.Unlock()
- snapshotMap.add(module.BaseModuleName(), ctx.Arch().ArchType, ctx.ModuleName())
-}
-
-// Disables source modules which have snapshots
-func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
- if !ctx.Device() {
- return
- }
-
- vndkVersion := ctx.DeviceConfig().VndkVersion()
- // don't need snapshot if current
- if vndkVersion == "current" || vndkVersion == "" {
- return
- }
-
- module, ok := ctx.Module().(*Module)
- if !ok {
- return
- }
-
- // vendor suffix should be added to snapshots if the source module isn't vendor: true.
- if !module.SocSpecific() {
- // But we can't just check SocSpecific() since we already passed the image mutator.
- // Check ramdisk and recovery to see if we are real "vendor: true" module.
- ramdisk_available := module.InRamdisk() && !module.OnlyInRamdisk()
- vendor_ramdisk_available := module.InVendorRamdisk() && !module.OnlyInVendorRamdisk()
- recovery_available := module.InRecovery() && !module.OnlyInRecovery()
-
- if !ramdisk_available && !recovery_available && !vendor_ramdisk_available {
- vendorSnapshotsLock.Lock()
- defer vendorSnapshotsLock.Unlock()
-
- vendorSuffixModules(ctx.Config())[ctx.ModuleName()] = true
- }
- }
-
- if module.isSnapshotPrebuilt() || module.VndkVersion() != ctx.DeviceConfig().VndkVersion() {
- // only non-snapshot modules with BOARD_VNDK_VERSION
- return
- }
-
- // .. and also filter out llndk library
- if module.isLlndk(ctx.Config()) {
- return
- }
-
- var snapshotMap *snapshotMap
-
- if lib, ok := module.linker.(libraryInterface); ok {
- if lib.static() {
- snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
- } else if lib.shared() {
- snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
- } else {
- // header
- snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
- }
- } else if module.binary() {
- snapshotMap = vendorSnapshotBinaries(ctx.Config())
- } else if module.object() {
- snapshotMap = vendorSnapshotObjects(ctx.Config())
- } else {
- 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.SkipInstall()
- module.Properties.HideFromMake = true
- } else {
- module.Disable()
- }
-}