platform_build_soong/cc/snapshot_prebuilt.go
Ivan Lozano add122a828 rust: Add vendor and recovery dylib support.
Adds dylib support for vendor and recovery images.

This changes the default linkage for vendor and recovery images to
dylib, which matches the platform default linkage. This also means that
by default, dylib-std variants are used for rlib dependencies.

Bug: 204303985
Test: Soong tests.
Test: m dist vendor-snapshot
Test: RECOVERY_SNAPSHOT_VERSION=current m dist recovery-snapshot
Change-Id: If84074b8615a70c45e7e162abeb853dc8c34d49a
2023-07-14 12:43:09 -04:00

843 lines
29 KiB
Go

// Copyright 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cc
// This file defines snapshot prebuilt modules, e.g. vendor snapshot and recovery snapshot. Such
// snapshot modules will override original source modules with setting BOARD_VNDK_VERSION, with
// snapshot mutators and snapshot information maps which are also defined in this file.
import (
"fmt"
"strings"
"android/soong/android"
"android/soong/snapshot"
"github.com/google/blueprint"
)
// This interface overrides snapshot.SnapshotImage to implement cc module specific functions
type SnapshotImage interface {
snapshot.SnapshotImage
// 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 {
*snapshot.VendorSnapshotImage
}
type recoverySnapshotImage struct {
*snapshot.RecoverySnapshotImage
}
func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
return VendorVariationPrefix + cfg.VndkVersion()
}
func (vendorSnapshotImage) moduleNameSuffix() string {
return VendorSuffix
}
func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
return android.RecoveryVariation
}
func (recoverySnapshotImage) moduleNameSuffix() string {
return RecoverySuffix
}
// Override existing vendor and recovery snapshot for cc module specific extra functions
var VendorSnapshotImageSingleton vendorSnapshotImage = vendorSnapshotImage{&snapshot.VendorSnapshotImageSingleton}
var RecoverySnapshotImageSingleton recoverySnapshotImage = recoverySnapshotImage{&snapshot.RecoverySnapshotImageSingleton}
func RegisterVendorSnapshotModules(ctx android.RegistrationContext) {
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)
}
func RegisterRecoverySnapshotModules(ctx android.RegistrationContext) {
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 init() {
RegisterVendorSnapshotModules(android.InitRegistrationContext)
RegisterRecoverySnapshotModules(android.InitRegistrationContext)
android.RegisterMakeVarsProvider(pctx, snapshotMakeVarsProvider)
}
const (
snapshotHeaderSuffix = "_header."
SnapshotSharedSuffix = "_shared."
SnapshotStaticSuffix = "_static."
snapshotBinarySuffix = "_binary."
snapshotObjectSuffix = "_object."
SnapshotRlibSuffix = "_rlib."
SnapshotDylibSuffix = "_dylib."
)
type SnapshotProperties struct {
Header_libs []string `android:"arch_variant"`
Static_libs []string `android:"arch_variant"`
Shared_libs []string `android:"arch_variant"`
Rlibs []string `android:"arch_variant"`
Dylibs []string `android:"arch_variant"`
Vndk_libs []string `android:"arch_variant"`
Binaries []string `android:"arch_variant"`
Objects []string `android:"arch_variant"`
}
type snapshotModule struct {
android.ModuleBase
properties SnapshotProperties
baseSnapshot BaseSnapshotDecorator
image SnapshotImage
}
func (s *snapshotModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
cfg := ctx.DeviceConfig()
if !s.image.IsUsingSnapshot(cfg) || s.image.TargetSnapshotVersion(cfg) != s.baseSnapshot.Version() {
s.Disable()
}
}
func (s *snapshotModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
func (s *snapshotModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
func (s *snapshotModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
func (s *snapshotModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
func (s *snapshotModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
func (s *snapshotModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
return []string{s.image.imageVariantName(ctx.DeviceConfig())}
}
func (s *snapshotModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
}
func (s *snapshotModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Nothing, the snapshot module is only used to forward dependency information in DepsMutator.
}
func getSnapshotNameSuffix(moduleSuffix, version, arch string) string {
versionSuffix := version
if arch != "" {
versionSuffix += "." + arch
}
return moduleSuffix + versionSuffix
}
func (s *snapshotModule) DepsMutator(ctx android.BottomUpMutatorContext) {
collectSnapshotMap := func(names []string, snapshotSuffix, moduleSuffix string) map[string]string {
snapshotMap := make(map[string]string)
for _, name := range names {
snapshotMap[name] = name +
getSnapshotNameSuffix(snapshotSuffix+moduleSuffix,
s.baseSnapshot.Version(),
ctx.DeviceConfig().Arches()[0].ArchType.String())
}
return snapshotMap
}
snapshotSuffix := s.image.moduleNameSuffix()
headers := collectSnapshotMap(s.properties.Header_libs, snapshotSuffix, snapshotHeaderSuffix)
binaries := collectSnapshotMap(s.properties.Binaries, snapshotSuffix, snapshotBinarySuffix)
objects := collectSnapshotMap(s.properties.Objects, snapshotSuffix, snapshotObjectSuffix)
staticLibs := collectSnapshotMap(s.properties.Static_libs, snapshotSuffix, SnapshotStaticSuffix)
sharedLibs := collectSnapshotMap(s.properties.Shared_libs, snapshotSuffix, SnapshotSharedSuffix)
rlibs := collectSnapshotMap(s.properties.Rlibs, snapshotSuffix, SnapshotRlibSuffix)
dylibs := collectSnapshotMap(s.properties.Dylibs, snapshotSuffix, SnapshotDylibSuffix)
vndkLibs := collectSnapshotMap(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,
Rlibs: rlibs,
Dylibs: dylibs,
})
}
type SnapshotInfo struct {
HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs, Rlibs, Dylibs map[string]string
}
var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps")
var _ android.ImageInterface = (*snapshotModule)(nil)
func snapshotMakeVarsProvider(ctx android.MakeVarsContext) {
snapshotSet := map[string]struct{}{}
ctx.VisitAllModules(func(m android.Module) {
if s, ok := m.(*snapshotModule); ok {
if _, ok := snapshotSet[s.Name()]; ok {
// arch variant generates duplicated modules
// skip this as we only need to know the path of the module.
return
}
snapshotSet[s.Name()] = struct{}{}
imageNameVersion := strings.Split(s.image.imageVariantName(ctx.DeviceConfig()), ".")
ctx.Strict(
strings.Join([]string{strings.ToUpper(imageNameVersion[0]), s.baseSnapshot.Version(), "SNAPSHOT_DIR"}, "_"),
ctx.ModuleDir(s))
}
})
}
func vendorSnapshotFactory() android.Module {
return snapshotFactory(VendorSnapshotImageSingleton)
}
func recoverySnapshotFactory() android.Module {
return snapshotFactory(RecoverySnapshotImageSingleton)
}
func snapshotFactory(image SnapshotImage) android.Module {
snapshotModule := &snapshotModule{}
snapshotModule.image = image
snapshotModule.AddProperties(
&snapshotModule.properties,
&snapshotModule.baseSnapshot.baseProperties)
android.InitAndroidArchModule(snapshotModule, android.DeviceSupported, android.MultilibBoth)
return snapshotModule
}
type BaseSnapshotDecoratorProperties struct {
// snapshot version.
Version string
// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
Target_arch string
// Suffix to be added to the module name when exporting to Android.mk, e.g. ".vendor".
Androidmk_suffix string `blueprint:"mutated"`
// Suffix to be added to the module name, e.g., vendor_shared,
// recovery_shared, etc.
ModuleSuffix string `blueprint:"mutated"`
}
// BaseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
// version, snapshot arch, etc. It also adds a special suffix to Soong module name, so it doesn't
// collide with source modules. e.g. the following example module,
//
// vendor_snapshot_static {
// name: "libbase",
// arch: "arm64",
// version: 30,
// ...
// }
//
// will be seen as "libbase.vendor_static.30.arm64" by Soong.
type BaseSnapshotDecorator struct {
baseProperties BaseSnapshotDecoratorProperties
Image SnapshotImage
}
func (p *BaseSnapshotDecorator) Name(name string) string {
return name + p.NameSuffix()
}
func (p *BaseSnapshotDecorator) NameSuffix() string {
return getSnapshotNameSuffix(p.moduleSuffix(), p.Version(), p.Arch())
}
func (p *BaseSnapshotDecorator) Version() string {
return p.baseProperties.Version
}
func (p *BaseSnapshotDecorator) Arch() string {
return p.baseProperties.Target_arch
}
func (p *BaseSnapshotDecorator) moduleSuffix() string {
return p.baseProperties.ModuleSuffix
}
func (p *BaseSnapshotDecorator) IsSnapshotPrebuilt() bool {
return true
}
func (p *BaseSnapshotDecorator) SnapshotAndroidMkSuffix() string {
return p.baseProperties.Androidmk_suffix
}
func (p *BaseSnapshotDecorator) SetSnapshotAndroidMkSuffix(ctx android.ModuleContext, variant string) {
// If there are any 2 or more variations among {core, product, vendor, recovery}
// we have to add the androidmk suffix to avoid duplicate modules with the same
// name.
variations := append(ctx.Target().Variations(), blueprint.Variation{
Mutator: "image",
Variation: android.CoreVariation})
if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
return
}
variations = append(ctx.Target().Variations(), blueprint.Variation{
Mutator: "image",
Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()})
if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
return
}
images := []SnapshotImage{VendorSnapshotImageSingleton, RecoverySnapshotImageSingleton}
for _, image := range images {
if p.Image == image {
continue
}
variations = append(ctx.Target().Variations(), blueprint.Variation{
Mutator: "image",
Variation: image.imageVariantName(ctx.DeviceConfig())})
if ctx.OtherModuleFarDependencyVariantExists(variations,
ctx.Module().(LinkableInterface).BaseModuleName()+
getSnapshotNameSuffix(
image.moduleNameSuffix()+variant,
p.Version(),
ctx.DeviceConfig().Arches()[0].ArchType.String())) {
p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
return
}
}
p.baseProperties.Androidmk_suffix = ""
}
// Call this with a module suffix after creating a snapshot module, such as
// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc.
func (p *BaseSnapshotDecorator) Init(m LinkableInterface, image SnapshotImage, moduleSuffix string) {
p.Image = image
p.baseProperties.ModuleSuffix = image.moduleNameSuffix() + moduleSuffix
m.AddProperties(&p.baseProperties)
android.AddLoadHook(m, func(ctx android.LoadHookContext) {
vendorSnapshotLoadHook(ctx, p)
})
}
// vendorSnapshotLoadHook disables snapshots if it's not BOARD_VNDK_VERSION.
// As vendor snapshot is only for vendor, such modules won't be used at all.
func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *BaseSnapshotDecorator) {
if p.Version() != ctx.DeviceConfig().VndkVersion() {
ctx.Module().Disable()
return
}
}
// Module definitions for snapshots of libraries (shared, static, header).
//
// Modules (vendor|recovery)_snapshot_(shared|static|header) are defined here. Shared libraries and
// static libraries have their prebuilt library files (.so for shared, .a for static) as their src,
// which can be installed or linked against. Also they export flags needed when linked, such as
// include directories, c flags, sanitize dependency information, etc.
//
// These modules are auto-generated by development/vendor_snapshot/update.py.
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 {
isSanitizerAvailable(t SanitizerType) bool
setSanitizerVariation(t SanitizerType, enabled bool)
isSanitizerEnabled(t SanitizerType) bool
isUnsanitizedVariant() bool
}
type snapshotLibraryDecorator struct {
BaseSnapshotDecorator
*libraryDecorator
properties SnapshotLibraryProperties
sanitizerProperties struct {
SanitizerVariation SanitizerType `blueprint:"mutated"`
// Library flags for cfi variant.
Cfi SnapshotLibraryProperties `android:"arch_variant"`
// Library flags for hwasan variant.
Hwasan SnapshotLibraryProperties `android:"arch_variant"`
}
}
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
}
// cc modules' link functions are to link compiled objects into final binaries.
// As snapshots are prebuilts, this just returns the prebuilt binary after doing things which are
// done by normal library decorator, e.g. exporting flags.
func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
var variant string
if p.shared() {
variant = SnapshotSharedSuffix
} else if p.static() {
variant = SnapshotStaticSuffix
} else {
variant = snapshotHeaderSuffix
}
p.SetSnapshotAndroidMkSuffix(ctx, variant)
if p.header() {
return p.libraryDecorator.link(ctx, flags, deps, objs)
}
if p.isSanitizerEnabled(cfi) {
p.properties = p.sanitizerProperties.Cfi
} else if p.isSanitizerEnabled(Hwasan) {
p.properties = p.sanitizerProperties.Hwasan
}
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
// Flags specified directly to this module.
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...)
// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
in := android.PathForModuleSrc(ctx, *p.properties.Src)
p.unstrippedOutputFile = in
if p.shared() {
libName := in.Base()
// 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)
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: in,
Target: ctx.Target(),
TableOfContents: p.tocFile,
})
}
if p.static() {
depSet := android.NewDepSetBuilder[android.Path](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.baseInstaller.install(ctx, file)
}
}
func (p *snapshotLibraryDecorator) nativeCoverage() bool {
return false
}
var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil)
func (p *snapshotLibraryDecorator) isSanitizerAvailable(t SanitizerType) bool {
switch t {
case cfi:
return p.sanitizerProperties.Cfi.Src != nil
case Hwasan:
return p.sanitizerProperties.Hwasan.Src != nil
default:
return false
}
}
func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enabled bool) {
if !enabled || p.isSanitizerEnabled(t) {
return
}
if !p.isUnsanitizedVariant() {
panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both"))
}
p.sanitizerProperties.SanitizerVariation = t
}
func (p *snapshotLibraryDecorator) isSanitizerEnabled(t SanitizerType) bool {
return p.sanitizerProperties.SanitizerVariation == t
}
func (p *snapshotLibraryDecorator) isUnsanitizedVariant() bool {
return !p.isSanitizerEnabled(Asan) &&
!p.isSanitizerEnabled(Hwasan)
}
func snapshotLibraryFactory(image SnapshotImage, moduleSuffix 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, image, moduleSuffix)
module.AddProperties(
&prebuilt.properties,
&prebuilt.sanitizerProperties,
)
return module, prebuilt
}
// vendor_snapshot_shared is a special prebuilt shared library which is auto-generated by
// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_shared
// 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(VendorSnapshotImageSingleton, SnapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init()
}
// recovery_snapshot_shared is a special prebuilt shared library which is auto-generated by
// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_shared
// 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(RecoverySnapshotImageSingleton, SnapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init()
}
// vendor_snapshot_static is a special prebuilt static library which is auto-generated by
// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_static
// 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(VendorSnapshotImageSingleton, SnapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init()
}
// recovery_snapshot_static is a special prebuilt static library which is auto-generated by
// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_static
// 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(RecoverySnapshotImageSingleton, SnapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init()
}
// vendor_snapshot_header is a special header library which is auto-generated by
// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_header
// 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(VendorSnapshotImageSingleton, snapshotHeaderSuffix)
prebuilt.libraryDecorator.HeaderOnly()
return module.Init()
}
// recovery_snapshot_header is a special header library which is auto-generated by
// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_header
// 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(RecoverySnapshotImageSingleton, snapshotHeaderSuffix)
prebuilt.libraryDecorator.HeaderOnly()
return module.Init()
}
// Module definitions for snapshots of executable binaries.
//
// Modules (vendor|recovery)_snapshot_binary are defined here. They have their prebuilt executable
// binaries (e.g. toybox, sh) as their src, which can be installed.
//
// These modules are auto-generated by development/vendor_snapshot/update.py.
type snapshotBinaryProperties struct {
// Prebuilt file for each arch.
Src *string `android:"arch_variant"`
}
type snapshotBinaryDecorator struct {
BaseSnapshotDecorator
*binaryDecorator
properties snapshotBinaryProperties
}
func (p *snapshotBinaryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.Arch() {
return false
}
if p.properties.Src == nil {
return false
}
return true
}
// cc modules' link functions are to link compiled objects into final binaries.
// As snapshots are prebuilts, this just returns the prebuilt binary
func (p *snapshotBinaryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
p.SetSnapshotAndroidMkSuffix(ctx, snapshotBinarySuffix)
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
in := android.PathForModuleSrc(ctx, *p.properties.Src)
p.unstrippedOutputFile = in
binName := in.Base()
// 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,
})
// binary snapshots need symlinking
p.setSymlinkList(ctx)
return outputFile
}
func (p *snapshotBinaryDecorator) nativeCoverage() bool {
return false
}
// vendor_snapshot_binary is a special prebuilt executable binary which is auto-generated by
// 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(VendorSnapshotImageSingleton, 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(RecoverySnapshotImageSingleton, snapshotBinarySuffix)
}
func snapshotBinaryFactory(image SnapshotImage, moduleSuffix 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, image, moduleSuffix)
module.AddProperties(&prebuilt.properties)
return module.Init()
}
// Module definitions for snapshots of object files (*.o).
//
// Modules (vendor|recovery)_snapshot_object are defined here. They have their prebuilt object
// files (*.o) as their src.
//
// These modules are auto-generated by development/vendor_snapshot/update.py.
type vendorSnapshotObjectProperties struct {
// Prebuilt file for each arch.
Src *string `android:"arch_variant"`
}
type snapshotObjectLinker struct {
BaseSnapshotDecorator
objectLinker
properties vendorSnapshotObjectProperties
}
func (p *snapshotObjectLinker) MatchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.Arch() {
return false
}
if p.properties.Src == nil {
return false
}
return true
}
// cc modules' link functions are to link compiled objects into final binaries.
// As snapshots are prebuilts, this just returns the prebuilt binary
func (p *snapshotObjectLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
p.SetSnapshotAndroidMkSuffix(ctx, snapshotObjectSuffix)
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
return android.PathForModuleSrc(ctx, *p.properties.Src)
}
func (p *snapshotObjectLinker) nativeCoverage() bool {
return false
}
// vendor_snapshot_object is a special prebuilt compiled object file which is auto-generated by
// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_object
// overrides the vendor variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
func VendorSnapshotObjectFactory() android.Module {
module := newObject(android.DeviceSupported)
prebuilt := &snapshotObjectLinker{
objectLinker: objectLinker{
baseLinker: NewBaseLinker(nil),
},
}
module.linker = prebuilt
prebuilt.Init(module, VendorSnapshotImageSingleton, snapshotObjectSuffix)
module.AddProperties(&prebuilt.properties)
// vendor_snapshot_object module does not provide sanitizer variants
module.sanitize.Properties.Sanitize.Never = BoolPtr(true)
return module.Init()
}
// recovery_snapshot_object is a special prebuilt compiled object file which is auto-generated by
// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_object
// overrides the recovery variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
func RecoverySnapshotObjectFactory() android.Module {
module := newObject(android.DeviceSupported)
prebuilt := &snapshotObjectLinker{
objectLinker: objectLinker{
baseLinker: NewBaseLinker(nil),
},
}
module.linker = prebuilt
prebuilt.Init(module, RecoverySnapshotImageSingleton, snapshotObjectSuffix)
module.AddProperties(&prebuilt.properties)
return module.Init()
}
type SnapshotInterface interface {
MatchesWithDevice(config android.DeviceConfig) bool
IsSnapshotPrebuilt() bool
Version() string
SnapshotAndroidMkSuffix() string
}
var _ SnapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
var _ SnapshotInterface = (*snapshotLibraryDecorator)(nil)
var _ SnapshotInterface = (*snapshotBinaryDecorator)(nil)
var _ SnapshotInterface = (*snapshotObjectLinker)(nil)