Merge changes I4976d3e1,I4c53b937,I502eaa4b

* changes:
  Rust rlib vendor snapshot support.
  Export cc functions for snapshotting Rust rlibs.
  Rust cdylib/statliclib support for vendor snapshot.
This commit is contained in:
Ivan Lozano 2021-06-03 16:54:14 +00:00 committed by Gerrit Code Review
commit 42b7157ff6
17 changed files with 1516 additions and 145 deletions

View file

@ -1267,8 +1267,8 @@ func (c *Module) nativeCoverage() bool {
}
func (c *Module) IsSnapshotPrebuilt() bool {
if p, ok := c.linker.(snapshotInterface); ok {
return p.isSnapshotPrebuilt()
if p, ok := c.linker.(SnapshotInterface); ok {
return p.IsSnapshotPrebuilt()
}
return false
}
@ -2946,10 +2946,10 @@ func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableI
if ccDepModule != nil {
// TODO(ivanlozano) Support snapshots for Rust-produced C library variants.
// Use base module name for snapshots when exporting to Makefile.
if snapshotPrebuilt, ok := ccDepModule.linker.(snapshotInterface); ok {
if snapshotPrebuilt, ok := ccDepModule.linker.(SnapshotInterface); ok {
baseName := ccDepModule.BaseModuleName()
return baseName + snapshotPrebuilt.snapshotAndroidMkSuffix()
return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix()
}
}

View file

@ -365,8 +365,8 @@ func (m *Module) SetCoreVariantNeeded(b bool) {
}
func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
if snapshot, ok := m.linker.(snapshotInterface); ok {
return snapshot.version()
if snapshot, ok := m.linker.(SnapshotInterface); ok {
return snapshot.Version()
} else {
mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
// Should we be panicking here instead?

View file

@ -28,7 +28,7 @@ import (
// Defines the specifics of different images to which the snapshot process is applicable, e.g.,
// vendor, recovery, ramdisk.
type snapshotImage interface {
type SnapshotImage interface {
// Returns true if a snapshot should be generated for this image.
shouldGenerateSnapshot(ctx android.SingletonContext) bool
@ -120,6 +120,10 @@ func (vendorSnapshotImage) Init(ctx android.RegistrationContext) {
ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
}
func (vendorSnapshotImage) RegisterAdditionalModule(ctx android.RegistrationContext, name string, factory android.ModuleFactory) {
ctx.RegisterModuleType(name, factory)
}
func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
// BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot.
return ctx.DeviceConfig().VndkVersion() == "current"
@ -264,16 +268,18 @@ func init() {
const (
snapshotHeaderSuffix = "_header."
snapshotSharedSuffix = "_shared."
snapshotStaticSuffix = "_static."
SnapshotSharedSuffix = "_shared."
SnapshotStaticSuffix = "_static."
snapshotBinarySuffix = "_binary."
snapshotObjectSuffix = "_object."
SnapshotRlibSuffix = "_rlib."
)
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"`
Vndk_libs []string `android:"arch_variant"`
Binaries []string `android:"arch_variant"`
Objects []string `android:"arch_variant"`
@ -284,14 +290,14 @@ type snapshot struct {
properties SnapshotProperties
baseSnapshot baseSnapshotDecorator
baseSnapshot BaseSnapshotDecorator
image snapshotImage
image SnapshotImage
}
func (s *snapshot) ImageMutatorBegin(ctx android.BaseModuleContext) {
cfg := ctx.DeviceConfig()
if !s.image.isUsingSnapshot(cfg) || s.image.targetSnapshotVersion(cfg) != s.baseSnapshot.version() {
if !s.image.isUsingSnapshot(cfg) || s.image.targetSnapshotVersion(cfg) != s.baseSnapshot.Version() {
s.Disable()
}
}
@ -341,7 +347,7 @@ func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, name := range names {
snapshotMap[name] = name +
getSnapshotNameSuffix(snapshotSuffix+moduleSuffix,
s.baseSnapshot.version(),
s.baseSnapshot.Version(),
ctx.DeviceConfig().Arches()[0].ArchType.String())
}
return snapshotMap
@ -351,8 +357,9 @@ func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
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)
staticLibs := collectSnapshotMap(s.properties.Static_libs, snapshotSuffix, SnapshotStaticSuffix)
sharedLibs := collectSnapshotMap(s.properties.Shared_libs, snapshotSuffix, SnapshotSharedSuffix)
rlibs := collectSnapshotMap(s.properties.Rlibs, snapshotSuffix, SnapshotRlibSuffix)
vndkLibs := collectSnapshotMap(s.properties.Vndk_libs, "", vndkSuffix)
for k, v := range vndkLibs {
sharedLibs[k] = v
@ -364,11 +371,12 @@ func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
Objects: objects,
StaticLibs: staticLibs,
SharedLibs: sharedLibs,
Rlibs: rlibs,
})
}
type SnapshotInfo struct {
HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs map[string]string
HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs, Rlibs map[string]string
}
var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps")
@ -383,7 +391,7 @@ func recoverySnapshotFactory() android.Module {
return snapshotFactory(recoverySnapshotImageSingleton)
}
func snapshotFactory(image snapshotImage) android.Module {
func snapshotFactory(image SnapshotImage) android.Module {
snapshot := &snapshot{}
snapshot.image = image
snapshot.AddProperties(
@ -393,7 +401,7 @@ func snapshotFactory(image snapshotImage) android.Module {
return snapshot
}
type baseSnapshotDecoratorProperties struct {
type BaseSnapshotDecoratorProperties struct {
// snapshot version.
Version string
@ -408,7 +416,7 @@ type baseSnapshotDecoratorProperties struct {
ModuleSuffix string `blueprint:"mutated"`
}
// baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
// BaseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
// 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,
//
@ -420,40 +428,40 @@ type baseSnapshotDecoratorProperties struct {
// }
//
// will be seen as "libbase.vendor_static.30.arm64" by Soong.
type baseSnapshotDecorator struct {
baseProperties baseSnapshotDecoratorProperties
image snapshotImage
type BaseSnapshotDecorator struct {
baseProperties BaseSnapshotDecoratorProperties
image SnapshotImage
}
func (p *baseSnapshotDecorator) Name(name string) string {
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) NameSuffix() string {
return getSnapshotNameSuffix(p.moduleSuffix(), p.Version(), p.Arch())
}
func (p *baseSnapshotDecorator) version() string {
func (p *BaseSnapshotDecorator) Version() string {
return p.baseProperties.Version
}
func (p *baseSnapshotDecorator) arch() string {
func (p *BaseSnapshotDecorator) Arch() string {
return p.baseProperties.Target_arch
}
func (p *baseSnapshotDecorator) moduleSuffix() string {
func (p *BaseSnapshotDecorator) moduleSuffix() string {
return p.baseProperties.ModuleSuffix
}
func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool {
func (p *BaseSnapshotDecorator) IsSnapshotPrebuilt() bool {
return true
}
func (p *baseSnapshotDecorator) snapshotAndroidMkSuffix() string {
func (p *BaseSnapshotDecorator) SnapshotAndroidMkSuffix() string {
return p.baseProperties.Androidmk_suffix
}
func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleContext, variant string) {
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.
@ -461,7 +469,7 @@ func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleCon
Mutator: "image",
Variation: android.CoreVariation})
if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(*Module).BaseModuleName()) {
if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix()
return
}
@ -470,12 +478,12 @@ func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleCon
Mutator: "image",
Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()})
if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(*Module).BaseModuleName()) {
if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix()
return
}
images := []snapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton}
images := []SnapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton}
for _, image := range images {
if p.image == image {
@ -486,10 +494,10 @@ func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleCon
Variation: image.imageVariantName(ctx.DeviceConfig())})
if ctx.OtherModuleFarDependencyVariantExists(variations,
ctx.Module().(*Module).BaseModuleName()+
ctx.Module().(LinkableInterface).BaseModuleName()+
getSnapshotNameSuffix(
image.moduleNameSuffix()+variant,
p.version(),
p.Version(),
ctx.DeviceConfig().Arches()[0].ArchType.String())) {
p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix()
return
@ -501,7 +509,7 @@ func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleCon
// Call this with a module suffix after creating a snapshot module, such as
// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc.
func (p *baseSnapshotDecorator) init(m *Module, image snapshotImage, moduleSuffix string) {
func (p *BaseSnapshotDecorator) Init(m LinkableInterface, image SnapshotImage, moduleSuffix string) {
p.image = image
p.baseProperties.ModuleSuffix = image.moduleNameSuffix() + moduleSuffix
m.AddProperties(&p.baseProperties)
@ -512,8 +520,8 @@ func (p *baseSnapshotDecorator) init(m *Module, image snapshotImage, moduleSuffi
// 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() {
func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *BaseSnapshotDecorator) {
if p.Version() != ctx.DeviceConfig().VndkVersion() {
ctx.Module().Disable()
return
}
@ -528,7 +536,7 @@ func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *baseSnapshotDecorato
// include directories, c flags, sanitize dependency information, etc.
//
// These modules are auto-generated by development/vendor_snapshot/update.py.
type snapshotLibraryProperties struct {
type SnapshotLibraryProperties struct {
// Prebuilt file for each arch.
Src *string `android:"arch_variant"`
@ -554,14 +562,14 @@ type snapshotSanitizer interface {
}
type snapshotLibraryDecorator struct {
baseSnapshotDecorator
BaseSnapshotDecorator
*libraryDecorator
properties snapshotLibraryProperties
properties SnapshotLibraryProperties
sanitizerProperties struct {
CfiEnabled bool `blueprint:"mutated"`
// Library flags for cfi variant.
Cfi snapshotLibraryProperties `android:"arch_variant"`
Cfi SnapshotLibraryProperties `android:"arch_variant"`
}
}
@ -570,9 +578,9 @@ func (p *snapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) F
return p.libraryDecorator.linkerFlags(ctx, flags)
}
func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
func (p *snapshotLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
arches := config.Arches()
if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
if len(arches) == 0 || arches[0].ArchType.String() != p.Arch() {
return false
}
if !p.header() && p.properties.Src == nil {
@ -587,14 +595,14 @@ func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig
func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
var variant string
if p.shared() {
variant = snapshotSharedSuffix
variant = SnapshotSharedSuffix
} else if p.static() {
variant = snapshotStaticSuffix
variant = SnapshotStaticSuffix
} else {
variant = snapshotHeaderSuffix
}
p.setSnapshotAndroidMkSuffix(ctx, variant)
p.SetSnapshotAndroidMkSuffix(ctx, variant)
if p.header() {
return p.libraryDecorator.link(ctx, flags, deps, objs)
@ -604,7 +612,7 @@ func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps Pat
p.properties = p.sanitizerProperties.Cfi
}
if !p.matchesWithDevice(ctx.DeviceConfig()) {
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
@ -657,7 +665,7 @@ func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps Pat
}
func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
if p.MatchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
p.baseInstaller.install(ctx, file)
}
}
@ -687,7 +695,7 @@ func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enable
}
}
func snapshotLibraryFactory(image snapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
func snapshotLibraryFactory(image SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
module, library := NewLibrary(android.DeviceSupported)
module.stl = nil
@ -710,7 +718,7 @@ func snapshotLibraryFactory(image snapshotImage, moduleSuffix string) (*Module,
module.linker = prebuilt
module.installer = prebuilt
prebuilt.init(module, image, moduleSuffix)
prebuilt.Init(module, image, moduleSuffix)
module.AddProperties(
&prebuilt.properties,
&prebuilt.sanitizerProperties,
@ -724,7 +732,7 @@ func snapshotLibraryFactory(image snapshotImage, moduleSuffix string) (*Module,
// 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)
module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, SnapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init()
}
@ -734,7 +742,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(recoverySnapshotImageSingleton, snapshotSharedSuffix)
module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, SnapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init()
}
@ -744,7 +752,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(VendorSnapshotImageSingleton, snapshotStaticSuffix)
module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, SnapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init()
}
@ -754,7 +762,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(recoverySnapshotImageSingleton, snapshotStaticSuffix)
module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, SnapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init()
}
@ -794,13 +802,13 @@ type snapshotBinaryProperties struct {
}
type snapshotBinaryDecorator struct {
baseSnapshotDecorator
BaseSnapshotDecorator
*binaryDecorator
properties snapshotBinaryProperties
}
func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.arch() {
func (p *snapshotBinaryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.Arch() {
return false
}
if p.properties.Src == nil {
@ -812,9 +820,9 @@ func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig)
// 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)
p.SetSnapshotAndroidMkSuffix(ctx, snapshotBinarySuffix)
if !p.matchesWithDevice(ctx.DeviceConfig()) {
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
@ -852,7 +860,7 @@ func RecoverySnapshotBinaryFactory() android.Module {
return snapshotBinaryFactory(recoverySnapshotImageSingleton, snapshotBinarySuffix)
}
func snapshotBinaryFactory(image snapshotImage, moduleSuffix string) android.Module {
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)
@ -871,7 +879,7 @@ func snapshotBinaryFactory(image snapshotImage, moduleSuffix string) android.Mod
module.stl = nil
module.linker = prebuilt
prebuilt.init(module, image, moduleSuffix)
prebuilt.Init(module, image, moduleSuffix)
module.AddProperties(&prebuilt.properties)
return module.Init()
}
@ -889,13 +897,13 @@ type vendorSnapshotObjectProperties struct {
}
type snapshotObjectLinker struct {
baseSnapshotDecorator
BaseSnapshotDecorator
objectLinker
properties vendorSnapshotObjectProperties
}
func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.arch() {
func (p *snapshotObjectLinker) MatchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.Arch() {
return false
}
if p.properties.Src == nil {
@ -907,9 +915,9 @@ func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bo
// 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)
p.SetSnapshotAndroidMkSuffix(ctx, snapshotObjectSuffix)
if !p.matchesWithDevice(ctx.DeviceConfig()) {
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
@ -933,7 +941,7 @@ func VendorSnapshotObjectFactory() android.Module {
}
module.linker = prebuilt
prebuilt.init(module, VendorSnapshotImageSingleton, snapshotObjectSuffix)
prebuilt.Init(module, VendorSnapshotImageSingleton, snapshotObjectSuffix)
module.AddProperties(&prebuilt.properties)
return module.Init()
}
@ -951,19 +959,19 @@ func RecoverySnapshotObjectFactory() android.Module {
}
module.linker = prebuilt
prebuilt.init(module, recoverySnapshotImageSingleton, snapshotObjectSuffix)
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
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)
var _ SnapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
var _ SnapshotInterface = (*snapshotLibraryDecorator)(nil)
var _ SnapshotInterface = (*snapshotBinaryDecorator)(nil)
var _ SnapshotInterface = (*snapshotObjectLinker)(nil)

View file

@ -109,7 +109,7 @@ func ShouldCollectHeadersForSnapshot(ctx android.ModuleContext, m LinkableInterf
return ctx.Config().VndkSnapshotBuildArtifacts()
}
for _, image := range []snapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton} {
for _, image := range []SnapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton} {
if isSnapshotAware(ctx.DeviceConfig(), m, image.isProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()), apexInfo, image) {
return true
}

View file

@ -82,7 +82,7 @@ type snapshotSingleton struct {
// Implementation of the image interface specific to the image
// associated with this snapshot (e.g., specific to the vendor image,
// recovery image, etc.).
image snapshotImage
image SnapshotImage
// Whether this singleton is for fake snapshot or not.
// Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
@ -147,7 +147,7 @@ func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
}
// Determines if the module is a candidate for snapshot.
func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image SnapshotImage) bool {
if !m.Enabled() || m.HiddenFromMake() {
return false
}
@ -205,7 +205,7 @@ func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietar
if sanitizable.Static() {
return sanitizable.OutputFile().Valid() && !image.private(m)
}
if sanitizable.Shared() {
if sanitizable.Shared() || sanitizable.Rlib() {
if !sanitizable.OutputFile().Valid() {
return false
}
@ -393,6 +393,8 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
libType = "static"
} else if m.Shared() {
libType = "shared"
} else if m.Rlib() {
libType = "rlib"
} else {
libType = "header"
}
@ -404,7 +406,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
libPath := m.OutputFile().Path()
stem = libPath.Base()
if sanitizable, ok := m.(PlatformSanitizeable); ok {
if sanitizable.Static() && sanitizable.SanitizePropDefined() && sanitizable.IsSanitizerEnabled(cfi) {
if (sanitizable.Static() || sanitizable.Rlib()) && sanitizable.SanitizePropDefined() && sanitizable.IsSanitizerEnabled(cfi) {
// both cfi and non-cfi variant for static libraries can exist.
// attach .cfi to distinguish between cfi and non-cfi.
// e.g. libbase.a -> libbase.cfi.a

View file

@ -360,7 +360,7 @@ func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
// prebuilt vndk modules should match with device
// TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
// When b/142675459 is landed, remove following check
if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) {
if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.MatchesWithDevice(mctx.DeviceConfig()) {
return false
}

View file

@ -82,7 +82,7 @@ func (p *vndkPrebuiltLibraryDecorator) Name(name string) string {
}
func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string {
suffix := p.version()
suffix := p.Version()
if p.arch() != "" {
suffix += "." + p.arch()
}
@ -92,7 +92,7 @@ func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string {
return vndkSuffix + suffix
}
func (p *vndkPrebuiltLibraryDecorator) version() string {
func (p *vndkPrebuiltLibraryDecorator) Version() string {
return String(p.properties.Version)
}
@ -107,7 +107,7 @@ func (p *vndkPrebuiltLibraryDecorator) binderBit() string {
return "64"
}
func (p *vndkPrebuiltLibraryDecorator) snapshotAndroidMkSuffix() string {
func (p *vndkPrebuiltLibraryDecorator) SnapshotAndroidMkSuffix() string {
return ".vendor"
}
@ -133,7 +133,7 @@ func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) andro
func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
if !p.matchesWithDevice(ctx.DeviceConfig()) {
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
ctx.Module().HideFromMake()
return nil
}
@ -163,7 +163,7 @@ func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
p.androidMkSuffix = p.NameSuffix()
vndkVersion := ctx.DeviceConfig().VndkVersion()
if vndkVersion == p.version() {
if vndkVersion == p.Version() {
p.androidMkSuffix = ""
}
@ -184,7 +184,7 @@ func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
return nil
}
func (p *vndkPrebuiltLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
arches := config.Arches()
if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
return false
@ -202,7 +202,7 @@ func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool {
return false
}
func (p *vndkPrebuiltLibraryDecorator) isSnapshotPrebuilt() bool {
func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool {
return true
}

View file

@ -32,6 +32,7 @@ bootstrap_go_package {
"rust.go",
"sanitize.go",
"source_provider.go",
"snapshot_prebuilt.go",
"snapshot_utils.go",
"strip.go",
"test.go",
@ -53,6 +54,7 @@ bootstrap_go_package {
"rust_test.go",
"source_provider_test.go",
"test_test.go",
"vendor_snapshot_test.go",
],
pluginFor: ["soong_build"],
}

View file

@ -137,6 +137,9 @@ func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoD
// Binaries default to dylib dependencies for device, rlib for host.
if binary.preferRlib() {
return rlibAutoDep
} else if mod, ok := ctx.Module().(*Module); ok && mod.InVendor() {
// Vendor Rust binaries should prefer rlibs.
return rlibAutoDep
} else if ctx.Device() {
return dylibAutoDep
} else {
@ -147,6 +150,8 @@ func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoD
func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
if binary.preferRlib() {
return RlibLinkage
} else if ctx.RustModule().InVendor() {
return RlibLinkage
}
return binary.baseCompiler.stdLinkage(ctx)
}

View file

@ -82,7 +82,12 @@ func (mod *Module) SetCoreVariantNeeded(b bool) {
}
func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
panic("Rust modules do not support snapshotting: " + mod.BaseModuleName())
if snapshot, ok := mod.compiler.(cc.SnapshotInterface); ok {
return snapshot.Version()
} else {
mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
return ""
}
}
func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
@ -110,7 +115,9 @@ func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string {
}
func (mod *Module) IsSnapshotPrebuilt() bool {
// Rust does not support prebuilts in its snapshots
if p, ok := mod.compiler.(cc.SnapshotInterface); ok {
return p.IsSnapshotPrebuilt()
}
return false
}
@ -202,6 +209,8 @@ func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant stri
func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
// Rust does not support installing to the product image yet.
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
if Bool(mod.VendorProperties.Product_available) {
mctx.PropertyErrorf("product_available",
"Rust modules do not yet support being available to the product image")
@ -217,6 +226,11 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.")
}
}
if vendorSpecific {
if lib, ok := mod.compiler.(libraryInterface); ok && lib.buildDylib() {
mctx.PropertyErrorf("vendor", "Vendor-only dylibs are not yet supported, use rust_library_rlib.")
}
}
cc.MutateImage(mctx, mod)

View file

@ -99,6 +99,8 @@ type libraryDecorator struct {
MutatedProperties LibraryMutatedProperties
includeDirs android.Paths
sourceProvider SourceProvider
collectedSnapshotHeaders android.Paths
}
type libraryInterface interface {
@ -122,7 +124,8 @@ type libraryInterface interface {
setStatic()
setSource()
// Set libstd linkage
// libstd linkage functions
rlibStd() bool
setRlibStd()
setDylibStd()
@ -193,6 +196,10 @@ func (library *libraryDecorator) setDylib() {
library.MutatedProperties.VariantIsShared = false
}
func (library *libraryDecorator) rlibStd() bool {
return library.MutatedProperties.VariantIsStaticStd
}
func (library *libraryDecorator) setRlibStd() {
library.MutatedProperties.VariantIsStaticStd = true
}
@ -220,7 +227,10 @@ func (library *libraryDecorator) setSource() {
}
func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
if library.preferRlib() {
if ctx.Module().(*Module).InVendor() {
// Vendor modules should statically link libstd.
return rlibAutoDep
} else if library.preferRlib() {
return rlibAutoDep
} else if library.rlib() || library.static() {
return rlibAutoDep
@ -236,7 +246,10 @@ func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) aut
}
func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
if library.static() || library.MutatedProperties.VariantIsStaticStd {
if ctx.RustModule().InVendor() {
// Vendor modules should statically link libstd.
return RlibLinkage
} else if library.static() || library.MutatedProperties.VariantIsStaticStd {
return RlibLinkage
} else if library.baseCompiler.preferRlib() {
return RlibLinkage
@ -623,6 +636,19 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
// Disable dylib Vendor Ramdisk variations until we support these.
v.(*Module).Disable()
}
variation := v.(*Module).ModuleBase.ImageVariation().Variation
if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
m.HasVendorVariant() &&
!cc.IsVendorProprietaryModule(mctx) &&
strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() {
// cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are
// produced for Dylibs; however, dylibs should not be enabled for boardVndkVersion for
// non-vendor proprietary modules.
v.(*Module).Disable()
}
case "source":
v.(*Module).compiler.(libraryInterface).setSource()
// The source variant does not produce any library.
@ -659,9 +685,10 @@ func LibstdMutator(mctx android.BottomUpMutatorContext) {
dylib := modules[1].(*Module)
rlib.compiler.(libraryInterface).setRlibStd()
dylib.compiler.(libraryInterface).setDylibStd()
if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation ||
strings.HasPrefix(dylib.ModuleBase.ImageVariation().Variation, cc.VendorVariationPrefix) {
// TODO(b/165791368)
// Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
// Disable rlibs that link against dylib-std on vendor and vendor ramdisk variations until those dylib
// variants are properly supported.
dylib.Disable()
}
@ -671,3 +698,54 @@ func LibstdMutator(mctx android.BottomUpMutatorContext) {
}
}
}
func (l *libraryDecorator) snapshotHeaders() android.Paths {
if l.collectedSnapshotHeaders == nil {
panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
}
return l.collectedSnapshotHeaders
}
// collectHeadersForSnapshot collects all exported headers from library.
// It globs header files in the source tree for exported include directories,
// and tracks generated header files separately.
//
// This is to be called from GenerateAndroidBuildActions, and then collected
// header files can be retrieved by snapshotHeaders().
func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
ret := android.Paths{}
// Glob together the headers from the modules include_dirs property
for _, path := range android.CopyOfPaths(l.includeDirs) {
dir := path.String()
glob, err := ctx.GlobWithDeps(dir+"/**/*", nil)
if err != nil {
ctx.ModuleErrorf("glob failed: %#v", err)
return
}
for _, header := range glob {
// Filter out only the files with extensions that are headers.
found := false
for _, ext := range cc.HeaderExts {
if strings.HasSuffix(header, ext) {
found = true
break
}
}
if !found {
continue
}
ret = append(ret, android.PathForSource(ctx, header))
}
}
// Glob together the headers from C dependencies as well, starting with non-generated headers.
ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)
// Collect generated headers from C dependencies.
ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)
// TODO(185577950): If support for generated headers is added, they need to be collected here as well.
l.collectedSnapshotHeaders = ret
}

View file

@ -85,6 +85,9 @@ type BaseProperties struct {
VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
ExtraVariants []string `blueprint:"mutated"`
// Used by vendor snapshot to record dependencies from snapshot modules.
SnapshotSharedLibs []string `blueprint:"mutated"`
// Make this module available when building for vendor ramdisk.
// On device without a dedicated recovery partition, the module is only
// available after switching root into
@ -92,6 +95,20 @@ type BaseProperties struct {
// the recovery variant instead (TODO(b/165791368) recovery not yet supported)
Vendor_ramdisk_available *bool
// Normally Soong uses the directory structure to decide which modules
// should be included (framework) or excluded (non-framework) from the
// different snapshots (vendor, recovery, etc.), but this property
// allows a partner to exclude a module normally thought of as a
// framework module from the vendor snapshot.
Exclude_from_vendor_snapshot *bool
// Normally Soong uses the directory structure to decide which modules
// should be included (framework) or excluded (non-framework) from the
// different snapshots (vendor, recovery, etc.), but this property
// allows a partner to exclude a module normally thought of as a
// framework module from the recovery snapshot.
Exclude_from_recovery_snapshot *bool
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
Min_sdk_version *string
@ -826,6 +843,14 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps)
// glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
// RECOVERY_SNAPSHOT_VERSION is current.
if lib, ok := mod.compiler.(snapshotLibraryInterface); ok {
if cc.ShouldCollectHeadersForSnapshot(ctx, mod, apexInfo) {
lib.collectHeadersForSnapshot(ctx, deps)
}
}
apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if mod.installable(apexInfo) {
mod.compiler.install(ctx)
@ -1056,6 +1081,10 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
directSharedLibDeps = append(directSharedLibDeps, ccDep)
// Record baseLibName for snapshots.
mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName))
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName)
exportDep = true
case cc.IsHeaderDepTag(depTag):
@ -1161,6 +1190,11 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
deps := mod.deps(ctx)
var commonDepVariations []blueprint.Variation
var snapshotInfo *cc.SnapshotInfo
if ctx.Os() == android.Android {
deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
}
stdLinkage := "dylib-std"
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
@ -1168,61 +1202,101 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
}
rlibDepVariations := commonDepVariations
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
rlibDepVariations = append(rlibDepVariations,
blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
}
actx.AddVariationDependencies(
append(rlibDepVariations, []blueprint.Variation{
{Mutator: "rust_libraries", Variation: rlibVariation}}...),
rlibDepTag, deps.Rlibs...)
// rlibs
for _, lib := range deps.Rlibs {
depTag := rlibDepTag
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
{Mutator: "rust_libraries", Variation: rlibVariation},
}...), depTag, lib)
}
// dylibs
actx.AddVariationDependencies(
append(commonDepVariations, []blueprint.Variation{
{Mutator: "rust_libraries", Variation: dylibVariation}}...),
dylibDepTag, deps.Dylibs...)
// rustlibs
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
if autoDep.depTag == rlibDepTag {
actx.AddVariationDependencies(
append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}),
autoDep.depTag, deps.Rustlibs...)
for _, lib := range deps.Rustlibs {
depTag := autoDep.depTag
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
{Mutator: "rust_libraries", Variation: autoDep.variation},
}...), depTag, lib)
}
} else {
actx.AddVariationDependencies(
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}),
autoDep.depTag, deps.Rustlibs...)
}
}
// stdlibs
if deps.Stdlibs != nil {
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
actx.AddVariationDependencies(
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "rlib"}),
rlibDepTag, deps.Stdlibs...)
for _, lib := range deps.Stdlibs {
depTag := rlibDepTag
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
depTag, lib)
}
} else {
actx.AddVariationDependencies(
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"}),
dylibDepTag, deps.Stdlibs...)
}
}
actx.AddVariationDependencies(append(commonDepVariations,
blueprint.Variation{Mutator: "link", Variation: "shared"}),
cc.SharedDepTag(), deps.SharedLibs...)
actx.AddVariationDependencies(append(commonDepVariations,
blueprint.Variation{Mutator: "link", Variation: "static"}),
cc.StaticDepTag(false), deps.StaticLibs...)
actx.AddVariationDependencies(append(commonDepVariations,
blueprint.Variation{Mutator: "link", Variation: "static"}),
cc.StaticDepTag(true), deps.WholeStaticLibs...)
for _, lib := range deps.SharedLibs {
depTag := cc.SharedDepTag()
name, version := cc.StubsLibNameAndVersion(lib)
variations := []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
}
for _, lib := range deps.WholeStaticLibs {
depTag := cc.StaticDepTag(true)
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
}
for _, lib := range deps.StaticLibs {
depTag := cc.StaticDepTag(false)
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
}
actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...)
crtVariations := cc.GetCrtVariations(ctx, mod)
if deps.CrtBegin != "" {
actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, deps.CrtBegin)
actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag,
cc.RewriteSnapshotLib(deps.CrtBegin, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
}
if deps.CrtEnd != "" {
actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, deps.CrtEnd)
actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag,
cc.RewriteSnapshotLib(deps.CrtEnd, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
}
if mod.sourceProvider != nil {
@ -1232,6 +1306,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
bindgen.Properties.Custom_bindgen)
}
}
// proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy.
actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
}

View file

@ -37,21 +37,29 @@ var prepareForRustTest = android.GroupFixturePreparers(
genrule.PrepareForTestWithGenRuleBuildComponents,
PrepareForIntegrationTestWithRust,
PrepareForTestWithRustIncludeVndk,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("29")
}),
)
var rustMockedFiles = android.MockFS{
"foo.rs": nil,
"foo.c": nil,
"src/bar.rs": nil,
"src/any.h": nil,
"proto.proto": nil,
"proto/buf.proto": nil,
"buf.proto": nil,
"foo.proto": nil,
"liby.so": nil,
"libz.so": nil,
"data.txt": nil,
"foo.rs": nil,
"foo.c": nil,
"src/bar.rs": nil,
"src/any.h": nil,
"c_includes/c_header.h": nil,
"rust_includes/rust_headers.h": nil,
"proto.proto": nil,
"proto/buf.proto": nil,
"buf.proto": nil,
"foo.proto": nil,
"liby.so": nil,
"libz.so": nil,
"data.txt": nil,
"liblog.map.txt": nil,
}
// testRust returns a TestContext in which a basic environment has been setup.
@ -67,19 +75,33 @@ func testRust(t *testing.T, bp string) *android.TestContext {
}
func testRustVndk(t *testing.T, bp string) *android.TestContext {
return testRustVndkFs(t, bp, rustMockedFiles)
}
const (
sharedVendorVariant = "android_vendor.29_arm64_armv8-a_shared"
rlibVendorVariant = "android_vendor.29_arm64_armv8-a_rlib_rlib-std"
)
func testRustVndkFs(t *testing.T, bp string, fs android.MockFS) *android.TestContext {
return testRustVndkFsVersions(t, bp, fs, "current", "current", "29")
}
func testRustVndkFsVersions(t *testing.T, bp string, fs android.MockFS, device_version, product_version, vndk_version string) *android.TestContext {
skipTestIfOsNotSupported(t)
result := android.GroupFixturePreparers(
prepareForRustTest,
rustMockedFiles.AddToFixture(),
fs.AddToFixture(),
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("29")
variables.DeviceVndkVersion = StringPtr(device_version)
variables.ProductVndkVersion = StringPtr(product_version)
variables.Platform_vndk_version = StringPtr(vndk_version)
},
),
).RunTestWithBp(t, bp)
return result.TestContext
}
// testRustCov returns a TestContext in which a basic environment has been
@ -115,10 +137,14 @@ func testRustError(t *testing.T, pattern string, bp string) {
// testRustVndkError is similar to testRustError, but can be used to test VNDK-related errors.
func testRustVndkError(t *testing.T, pattern string, bp string) {
testRustVndkFsError(t, pattern, bp, rustMockedFiles)
}
func testRustVndkFsError(t *testing.T, pattern string, bp string, fs android.MockFS) {
skipTestIfOsNotSupported(t)
android.GroupFixturePreparers(
prepareForRustTest,
rustMockedFiles.AddToFixture(),
fs.AddToFixture(),
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")

121
rust/snapshot_prebuilt.go Normal file
View file

@ -0,0 +1,121 @@
// Copyright 2021 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 rust
import (
"android/soong/android"
"android/soong/cc"
"github.com/google/blueprint/proptools"
)
const (
snapshotRlibSuffix = "_rlib."
)
type snapshotLibraryDecorator struct {
cc.BaseSnapshotDecorator
*libraryDecorator
properties cc.SnapshotLibraryProperties
sanitizerProperties struct {
CfiEnabled bool `blueprint:"mutated"`
// Library flags for cfi variant.
Cfi cc.SnapshotLibraryProperties `android:"arch_variant"`
}
}
func init() {
registerRustSnapshotModules(android.InitRegistrationContext)
}
func registerRustSnapshotModules(ctx android.RegistrationContext) {
cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
"vendor_snapshot_rlib", VendorSnapshotRlibFactory)
}
func snapshotLibraryFactory(image cc.SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
module, library := NewRustLibrary(android.DeviceSupported)
module.sanitize = nil
library.stripper.StripProperties.Strip.None = proptools.BoolPtr(true)
prebuilt := &snapshotLibraryDecorator{
libraryDecorator: library,
}
module.compiler = prebuilt
prebuilt.Init(module, image, moduleSuffix)
module.AddProperties(
&prebuilt.properties,
&prebuilt.sanitizerProperties,
)
return module, prebuilt
}
func (library *snapshotLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
var variant string
if library.static() {
variant = cc.SnapshotStaticSuffix
} else if library.shared() {
variant = cc.SnapshotSharedSuffix
} else if library.rlib() {
variant = cc.SnapshotRlibSuffix
}
if !library.dylib() {
// TODO(184042776): Remove this check when dylibs are supported in snapshots.
library.SetSnapshotAndroidMkSuffix(ctx, variant)
}
if !library.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
return android.PathForModuleSrc(ctx, *library.properties.Src)
}
func (library *snapshotLibraryDecorator) rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath {
return android.OptionalPath{}
}
// vendor_snapshot_rlib is a special prebuilt rlib library which is auto-generated by
// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_rlib
// overrides the vendor variant of the rust rlib library with the same name, if BOARD_VNDK_VERSION
// is set.
func VendorSnapshotRlibFactory() android.Module {
module, prebuilt := snapshotLibraryFactory(cc.VendorSnapshotImageSingleton, cc.SnapshotRlibSuffix)
prebuilt.libraryDecorator.BuildOnlyRlib()
prebuilt.libraryDecorator.setNoStdlibs()
return module.Init()
}
func (library *snapshotLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
arches := config.Arches()
if len(arches) == 0 || arches[0].ArchType.String() != library.Arch() {
return false
}
if library.properties.Src == nil {
return false
}
return true
}
func (library *snapshotLibraryDecorator) IsSnapshotPrebuilt() bool {
return true
}
var _ cc.SnapshotInterface = (*snapshotLibraryDecorator)(nil)

View file

@ -18,18 +18,33 @@ import (
"android/soong/android"
)
// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
type snapshotLibraryInterface interface {
libraryInterface
// collectHeadersForSnapshot is called in GenerateAndroidBuildActions for snapshot aware
// modules (See isSnapshotAware below).
// This function should gather all headers needed for snapshot.
collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps)
// snapshotHeaders should return collected headers by collectHeadersForSnapshot.
// Calling snapshotHeaders before collectHeadersForSnapshot is an error.
snapshotHeaders() android.Paths
}
func (mod *Module) ExcludeFromVendorSnapshot() bool {
// TODO Rust does not yet support snapshotting
return false
return Bool(mod.Properties.Exclude_from_vendor_snapshot)
}
func (mod *Module) ExcludeFromRecoverySnapshot() bool {
// TODO Rust does not yet support snapshotting
return false
return Bool(mod.Properties.Exclude_from_recovery_snapshot)
}
func (mod *Module) IsSnapshotLibrary() bool {
// TODO Rust does not yet support snapshotting
if lib, ok := mod.compiler.(libraryInterface); ok {
// Rust-native dylibs are not snapshot supported yet. Only snapshot the rlib-std variants of rlibs.
return lib.shared() || lib.static() || (lib.rlib() && lib.rlibStd())
}
return false
}
@ -39,8 +54,7 @@ func (mod *Module) SnapshotRuntimeLibs() []string {
}
func (mod *Module) SnapshotSharedLibs() []string {
// TODO Rust does not yet support snapshotting
return []string{}
return mod.Properties.SnapshotSharedLibs
}
func (mod *Module) Symlinks() []string {
@ -49,6 +63,8 @@ func (mod *Module) Symlinks() []string {
}
func (m *Module) SnapshotHeaders() android.Paths {
// TODO Rust does not yet support snapshotting
if l, ok := m.compiler.(snapshotLibraryInterface); ok {
return l.snapshotHeaders()
}
return android.Paths{}
}

View file

@ -45,6 +45,11 @@ var PrepareForIntegrationTestWithRust = android.GroupFixturePreparers(
PrepareForTestWithRustDefaultModules,
)
var PrepareForTestWithRustIncludeVndk = android.GroupFixturePreparers(
PrepareForIntegrationTestWithRust,
cc.PrepareForTestWithCcIncludeVndk,
)
func GatherRequiredDepsForTest() string {
bp := `
rust_prebuilt_library {
@ -130,6 +135,9 @@ func GatherRequiredDepsForTest() string {
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
vendor_available: true,
llndk: {
symbol_file: "liblog.map.txt",
},
}
cc_library {
name: "libprotobuf-cpp-full",
@ -240,4 +248,5 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
registerRustSnapshotModules(ctx)
}

1015
rust/vendor_snapshot_test.go Normal file

File diff suppressed because it is too large Load diff