Refactor vendor snapshot to use LinkableInterface.

Refactors the vendor snapshot support to use the LinkableInterface
so that support can be extended to Rust. This CL does not add
vendor snapshot support for Rust; that is left for a follow-on CL.

Bug: 184042776
Test: m nothing
Change-Id: Id0c4970ca00053484a52677d182153cbc454c301
This commit is contained in:
Ivan Lozano 2021-04-01 09:49:36 -04:00
parent c8aeb00a9c
commit d7586b6526
18 changed files with 429 additions and 116 deletions

View file

@ -1256,7 +1256,7 @@ func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
}
// Implements cc.Coverage
func (a *apexBundle) PreventInstall() {
func (a *apexBundle) SetPreventInstall() {
a.properties.PreventInstall = true
}

View file

@ -841,6 +841,10 @@ func (c *Module) SetHideFromMake() {
c.Properties.HideFromMake = true
}
func (c *Module) HiddenFromMake() bool {
return c.Properties.HideFromMake
}
func (c *Module) Toc() android.OptionalPath {
if c.linker != nil {
if library, ok := c.linker.(libraryInterface); ok {
@ -1088,12 +1092,6 @@ func (c *Module) IsDependencyRoot() bool {
return false
}
// Returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64.
// "product" and "vendor" variant modules return true for this function.
// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
// "soc_specific: true" and more vendor installed modules are included here.
// When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "product_available: true" or
// "product_specific: true" modules are included here.
func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
@ -1141,6 +1139,18 @@ func (c *Module) IsVendorPublicLibrary() bool {
return c.VendorProperties.IsVendorPublicLibrary
}
func (c *Module) HasLlndkStubs() bool {
lib := moduleLibraryInterface(c)
return lib != nil && lib.hasLLNDKStubs()
}
func (c *Module) StubsVersion() string {
if lib, ok := c.linker.(versionedInterface); ok {
return lib.stubsVersion()
}
panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", c.BaseModuleName()))
}
// isImplementationForLLNDKPublic returns true for any variant of a cc_library that has LLNDK stubs
// and does not set llndk.vendor_available: false.
func (c *Module) isImplementationForLLNDKPublic() bool {
@ -1185,7 +1195,7 @@ func (c *Module) isNDKStubLibrary() bool {
return false
}
func (c *Module) isVndkSp() bool {
func (c *Module) IsVndkSp() bool {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.isVndkSp()
}
@ -1204,7 +1214,7 @@ func (c *Module) SubName() string {
}
func (c *Module) MustUseVendorVariant() bool {
return c.isVndkSp() || c.Properties.MustUseVendorVariant
return c.IsVndkSp() || c.Properties.MustUseVendorVariant
}
func (c *Module) getVndkExtendsModuleName() string {
@ -1343,11 +1353,11 @@ func (ctx *moduleContextImpl) header() bool {
}
func (ctx *moduleContextImpl) binary() bool {
return ctx.mod.binary()
return ctx.mod.Binary()
}
func (ctx *moduleContextImpl) object() bool {
return ctx.mod.object()
return ctx.mod.Object()
}
func (ctx *moduleContextImpl) canUseSdk() bool {
@ -1445,7 +1455,7 @@ func (ctx *moduleContextImpl) isNDKStubLibrary() bool {
}
func (ctx *moduleContextImpl) isVndkSp() bool {
return ctx.mod.isVndkSp()
return ctx.mod.IsVndkSp()
}
func (ctx *moduleContextImpl) IsVndkExt() bool {
@ -1786,7 +1796,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
// glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
// RECOVERY_SNAPSHOT_VERSION is current.
if i, ok := c.linker.(snapshotLibraryInterface); ok {
if shouldCollectHeadersForSnapshot(ctx, c, apexInfo) {
if ShouldCollectHeadersForSnapshot(ctx, c, apexInfo) {
i.collectHeadersForSnapshot(ctx)
}
}
@ -1799,7 +1809,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
// modules can be hidden from make as some are needed for resolving make side
// dependencies.
c.HideFromMake()
} else if !c.installable(apexInfo) {
} else if !installable(c, apexInfo) {
c.SkipInstall()
}
@ -2451,7 +2461,7 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
return true
}
if to.isVndkSp() || to.IsLlndk() {
if to.IsVndkSp() || to.IsLlndk() {
return false
}
@ -3064,7 +3074,7 @@ func (c *Module) Header() bool {
return false
}
func (c *Module) binary() bool {
func (c *Module) Binary() bool {
if b, ok := c.linker.(interface {
binary() bool
}); ok {
@ -3073,7 +3083,7 @@ func (c *Module) binary() bool {
return false
}
func (c *Module) object() bool {
func (c *Module) Object() bool {
if o, ok := c.linker.(interface {
object() bool
}); ok {
@ -3155,18 +3165,25 @@ func (c *Module) UniqueApexVariations() bool {
}
}
// Return true if the module is ever installable.
func (c *Module) EverInstallable() bool {
return c.installer != nil &&
// Check to see whether the module is actually ever installable.
c.installer.everInstallable()
}
func (c *Module) installable(apexInfo android.ApexInfo) bool {
func (c *Module) PreventInstall() bool {
return c.Properties.PreventInstall
}
func (c *Module) Installable() *bool {
return c.Properties.Installable
}
func installable(c LinkableInterface, apexInfo android.ApexInfo) bool {
ret := c.EverInstallable() &&
// Check to see whether the module has been configured to not be installed.
proptools.BoolDefault(c.Properties.Installable, true) &&
!c.Properties.PreventInstall && c.outputFile.Valid()
proptools.BoolDefault(c.Installable(), true) &&
!c.PreventInstall() && c.OutputFile().Valid()
// The platform variant doesn't need further condition. Apex variants however might not
// be installable because it will likely to be included in the APEX and won't appear

View file

@ -381,8 +381,8 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string
if !mod.IsVndk() {
t.Errorf("%q IsVndk() must equal to true", name)
}
if mod.isVndkSp() != isVndkSp {
t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
if mod.IsVndkSp() != isVndkSp {
t.Errorf("%q IsVndkSp() must equal to %t", name, isVndkSp)
}
// Check VNDK extension properties.

View file

@ -203,7 +203,7 @@ func SetCoverageProperties(ctx android.BaseModuleContext, properties CoveragePro
type Coverage interface {
android.Module
IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
PreventInstall()
SetPreventInstall()
HideFromMake()
MarkAsCoverageVariant(bool)
EnableCoverageIfNeeded()
@ -236,7 +236,7 @@ func coverageMutator(mctx android.BottomUpMutatorContext) {
// to an APEX via 'data' property.
m := mctx.CreateVariations("", "cov")
m[0].(Coverage).MarkAsCoverageVariant(false)
m[0].(Coverage).PreventInstall()
m[0].(Coverage).SetPreventInstall()
m[0].(Coverage).HideFromMake()
m[1].(Coverage).MarkAsCoverageVariant(true)

View file

@ -48,6 +48,20 @@ type PlatformSanitizeable interface {
// SanitizerSupported returns true if a sanitizer type is supported by this modules compiler.
SanitizerSupported(t SanitizerType) bool
// MinimalRuntimeDep returns true if this module needs to link the minimal UBSan runtime,
// either because it requires it or because a dependent module which requires it to be linked in this module.
MinimalRuntimeDep() bool
// UbsanRuntimeDep returns true if this module needs to link the full UBSan runtime,
// either because it requires it or because a dependent module which requires it to be linked in this module.
UbsanRuntimeDep() bool
// UbsanRuntimeNeeded returns true if the full UBSan runtime is required by this module.
UbsanRuntimeNeeded() bool
// MinimalRuntimeNeeded returns true if the minimal UBSan runtime is required by this module
MinimalRuntimeNeeded() bool
// SanitizableDepTagChecker returns a SantizableDependencyTagChecker function type.
SanitizableDepTagChecker() SantizableDependencyTagChecker
}
@ -60,14 +74,42 @@ type PlatformSanitizeable interface {
// implementation should handle tags from both.
type SantizableDependencyTagChecker func(tag blueprint.DependencyTag) bool
// Snapshottable defines those functions necessary for handling module snapshots.
type Snapshottable interface {
// SnapshotHeaders returns a list of header paths provided by this module.
SnapshotHeaders() android.Paths
// ExcludeFromVendorSnapshot returns true if this module should be otherwise excluded from the vendor snapshot.
ExcludeFromVendorSnapshot() bool
// ExcludeFromRecoverySnapshot returns true if this module should be otherwise excluded from the recovery snapshot.
ExcludeFromRecoverySnapshot() bool
// SnapshotLibrary returns true if this module is a snapshot library.
IsSnapshotLibrary() bool
// SnapshotRuntimeLibs returns a list of libraries needed by this module at runtime but which aren't build dependencies.
SnapshotRuntimeLibs() []string
// SnapshotSharedLibs returns the list of shared library dependencies for this module.
SnapshotSharedLibs() []string
// IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
IsSnapshotPrebuilt() bool
}
// LinkableInterface is an interface for a type of module that is linkable in a C++ library.
type LinkableInterface interface {
android.Module
Snapshottable
Module() android.Module
CcLibrary() bool
CcLibraryInterface() bool
// BaseModuleName returns the android.ModuleBase.BaseModuleName() value for this module.
BaseModuleName() string
OutputFile() android.OptionalPath
CoverageFiles() android.Paths
@ -79,9 +121,6 @@ type LinkableInterface interface {
BuildSharedVariant() bool
SetStatic()
SetShared()
Static() bool
Shared() bool
Header() bool
IsPrebuilt() bool
Toc() android.OptionalPath
@ -106,13 +145,29 @@ type LinkableInterface interface {
// IsLlndkPublic returns true only for LLNDK (public) libs.
IsLlndkPublic() bool
// HasLlndkStubs returns true if this library has a variant that will build LLNDK stubs.
HasLlndkStubs() bool
// NeedsLlndkVariants returns true if this module has LLNDK stubs or provides LLNDK headers.
NeedsLlndkVariants() bool
// NeedsVendorPublicLibraryVariants returns true if this module has vendor public library stubs.
NeedsVendorPublicLibraryVariants() bool
//StubsVersion returns the stubs version for this module.
StubsVersion() string
// UseVndk returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64.
// "product" and "vendor" variant modules return true for this function.
// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
// "soc_specific: true" and more vendor installed modules are included here.
// When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "vendor_available: true" or
// "product_specific: true" modules are included here.
UseVndk() bool
// IsVndkSp returns true if this is a VNDK-SP module.
IsVndkSp() bool
MustUseVendorVariant() bool
IsVndk() bool
IsVndkExt() bool
@ -140,6 +195,51 @@ type LinkableInterface interface {
// KernelHeadersDecorator returns true if this is a kernel headers decorator module.
// This is specific to cc and should always return false for all other packages.
KernelHeadersDecorator() bool
// HiddenFromMake returns true if this module is hidden from Make.
HiddenFromMake() bool
// RelativeInstallPath returns the relative install path for this module.
RelativeInstallPath() string
// Binary returns true if this is a binary module.
Binary() bool
// Object returns true if this is an object module.
Object() bool
// Rlib returns true if this is an rlib module.
Rlib() bool
// Dylib returns true if this is an dylib module.
Dylib() bool
// Static returns true if this is a static library module.
Static() bool
// Shared returns true if this is a shared library module.
Shared() bool
// Header returns true if this is a library headers module.
Header() bool
// EverInstallable returns true if the module is ever installable
EverInstallable() bool
// PreventInstall returns true if this module is prevented from installation.
PreventInstall() bool
// InstallInData returns true if this module is installed in data.
InstallInData() bool
// Installable returns a bool pointer to the module installable property.
Installable() *bool
// Symlinks returns a list of symlinks that should be created for this module.
Symlinks() []string
// VndkVersion returns the VNDK version string for this module.
VndkVersion() string
}
var (

View file

@ -84,7 +84,7 @@ func classifySourceAbiDump(ctx android.BaseModuleContext) string {
return "LLNDK"
}
if m.UseVndk() && m.IsVndk() && !m.IsVndkPrivate() {
if m.isVndkSp() {
if m.IsVndkSp() {
if m.IsVndkExt() {
return "VNDK-SP-ext"
} else {

View file

@ -1075,7 +1075,7 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
sanitizers = append(sanitizers, "shadow-call-stack")
}
if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.binary() {
if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.Binary() {
noteDep := "note_memtag_heap_async"
if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
noteDep = "note_memtag_heap_sync"
@ -1208,6 +1208,14 @@ type Sanitizeable interface {
AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string)
}
func (c *Module) MinimalRuntimeDep() bool {
return c.sanitize.Properties.MinimalRuntimeDep
}
func (c *Module) UbsanRuntimeDep() bool {
return c.sanitize.Properties.UbsanRuntimeDep
}
func (c *Module) SanitizePropDefined() bool {
return c.sanitize != nil
}
@ -1441,6 +1449,14 @@ func enableMinimalRuntime(sanitize *sanitize) bool {
return false
}
func (m *Module) UbsanRuntimeNeeded() bool {
return enableUbsanRuntime(m.sanitize)
}
func (m *Module) MinimalRuntimeNeeded() bool {
return enableMinimalRuntime(m.sanitize)
}
func enableUbsanRuntime(sanitize *sanitize) bool {
return Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||

View file

@ -35,12 +35,12 @@ type snapshotImage interface {
// 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
inImage(m LinkableInterface) func() bool
// Returns true if the module is private and must not be included in the
// snapshot. For example VNDK-private modules must return true for the
// vendor snapshots. But false for the recovery snapshots.
private(m *Module) bool
private(m LinkableInterface) bool
// Returns true if a dir under source tree is an SoC-owned proprietary
// directory, such as device/, vendor/, etc.
@ -56,7 +56,7 @@ type snapshotImage interface {
// 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
excludeFromSnapshot(m LinkableInterface) bool
// Returns true if the build is using a snapshot for this image.
isUsingSnapshot(cfg android.DeviceConfig) bool
@ -125,11 +125,11 @@ func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext)
return ctx.DeviceConfig().VndkVersion() == "current"
}
func (vendorSnapshotImage) inImage(m *Module) func() bool {
func (vendorSnapshotImage) inImage(m LinkableInterface) func() bool {
return m.InVendor
}
func (vendorSnapshotImage) private(m *Module) bool {
func (vendorSnapshotImage) private(m LinkableInterface) bool {
return m.IsVndkPrivate()
}
@ -159,7 +159,7 @@ func (vendorSnapshotImage) includeVndk() bool {
return true
}
func (vendorSnapshotImage) excludeFromSnapshot(m *Module) bool {
func (vendorSnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
return m.ExcludeFromVendorSnapshot()
}
@ -206,12 +206,12 @@ func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext
return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
}
func (recoverySnapshotImage) inImage(m *Module) func() bool {
func (recoverySnapshotImage) inImage(m LinkableInterface) func() bool {
return m.InRecovery
}
// recovery snapshot does not have private libraries.
func (recoverySnapshotImage) private(m *Module) bool {
func (recoverySnapshotImage) private(m LinkableInterface) bool {
return false
}
@ -224,7 +224,7 @@ func (recoverySnapshotImage) includeVndk() bool {
return false
}
func (recoverySnapshotImage) excludeFromSnapshot(m *Module) bool {
func (recoverySnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
return m.ExcludeFromRecoverySnapshot()
}

View file

@ -23,6 +23,36 @@ var (
headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
)
func (m *Module) IsSnapshotLibrary() bool {
if _, ok := m.linker.(snapshotLibraryInterface); ok {
return true
}
return false
}
func (m *Module) SnapshotHeaders() android.Paths {
if m.IsSnapshotLibrary() {
return m.linker.(snapshotLibraryInterface).snapshotHeaders()
}
return android.Paths{}
}
func (m *Module) Dylib() bool {
return false
}
func (m *Module) Rlib() bool {
return false
}
func (m *Module) SnapshotRuntimeLibs() []string {
return m.Properties.SnapshotRuntimeLibs
}
func (m *Module) SnapshotSharedLibs() []string {
return m.Properties.SnapshotSharedLibs
}
// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
type snapshotLibraryInterface interface {
libraryInterface
@ -68,14 +98,14 @@ func (s *snapshotMap) get(name string, arch android.ArchType) (snapshot string,
return snapshot, found
}
// shouldCollectHeadersForSnapshot determines if the module is a possible candidate for snapshot.
// ShouldCollectHeadersForSnapshot determines if the module is a possible candidate for snapshot.
// If it's true, collectHeadersForSnapshot will be called in GenerateAndroidBuildActions.
func shouldCollectHeadersForSnapshot(ctx android.ModuleContext, m *Module, apexInfo android.ApexInfo) bool {
func ShouldCollectHeadersForSnapshot(ctx android.ModuleContext, m LinkableInterface, apexInfo android.ApexInfo) bool {
if ctx.DeviceConfig().VndkVersion() != "current" &&
ctx.DeviceConfig().RecoverySnapshotVersion() != "current" {
return false
}
if _, _, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo); ok {
if _, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo); ok {
return ctx.Config().VndkSnapshotBuildArtifacts()
}

View file

@ -115,7 +115,7 @@ func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
// 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, ok := ctx.Module().(LinkableInterface); ok {
if c.ExcludeFromVendorSnapshot() {
return true
}
@ -137,7 +137,7 @@ func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
// that are excluded from the recovery snapshot, and it means that the
// vendor has assumed control of the framework-provided module.
if c, ok := ctx.Module().(*Module); ok {
if c, ok := ctx.Module().(LinkableInterface); ok {
if c.ExcludeFromRecoverySnapshot() {
return true
}
@ -147,8 +147,8 @@ func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
}
// Determines if the module is a candidate for snapshot.
func isSnapshotAware(cfg android.DeviceConfig, m *Module, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
if !m.Enabled() || m.Properties.HideFromMake {
func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
if !m.Enabled() || m.HiddenFromMake() {
return false
}
// When android/prebuilt.go selects between source and prebuilt, it sets
@ -177,51 +177,51 @@ func isSnapshotAware(cfg android.DeviceConfig, m *Module, inProprietaryPath bool
return false
}
// skip kernel_headers which always depend on vendor
if _, ok := m.linker.(*kernelHeadersDecorator); ok {
if m.KernelHeadersDecorator() {
return false
}
// skip LLNDK libraries which are backward compatible
if m.IsLlndk() {
return false
}
// Libraries
if l, ok := m.linker.(snapshotLibraryInterface); ok {
if m.sanitize != nil {
if sanitizable, ok := m.(PlatformSanitizeable); ok && sanitizable.IsSnapshotLibrary() {
if sanitizable.SanitizePropDefined() {
// scs and hwasan export both sanitized and unsanitized variants for static and header
// Always use unsanitized variants of them.
for _, t := range []SanitizerType{scs, Hwasan} {
if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
if !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(t) {
return false
}
}
// 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) {
if !sanitizable.Static() && !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(cfi) {
return false
}
}
if l.static() {
return m.outputFile.Valid() && !image.private(m)
if sanitizable.Static() {
return sanitizable.OutputFile().Valid() && !image.private(m)
}
if l.shared() {
if !m.outputFile.Valid() {
if sanitizable.Shared() {
if !sanitizable.OutputFile().Valid() {
return false
}
if image.includeVndk() {
if !m.IsVndk() {
if !sanitizable.IsVndk() {
return true
}
return m.IsVndkExt()
return sanitizable.IsVndkExt()
}
}
return true
}
// Binaries and Objects
if m.binary() || m.object() {
return m.outputFile.Valid()
if m.Binary() || m.Object() {
return m.OutputFile().Valid()
}
return false
@ -323,7 +323,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
// 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, fake bool) android.Paths {
installSnapshot := func(m LinkableInterface, fake bool) android.Paths {
targetArch := "arch-" + m.Target().Arch.ArchType.String()
if m.Target().Arch.ArchVariant != "" {
targetArch += "-" + m.Target().Arch.ArchVariant
@ -337,7 +337,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
prop.ModuleName = ctx.ModuleName(m)
if c.supportsVndkExt && m.IsVndkExt() {
// vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
if m.isVndkSp() {
if m.IsVndkSp() {
prop.RelativeInstallPath = "vndk-sp"
} else {
prop.RelativeInstallPath = "vndk"
@ -345,7 +345,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
} else {
prop.RelativeInstallPath = m.RelativeInstallPath()
}
prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
prop.RuntimeLibs = m.SnapshotRuntimeLibs()
prop.Required = m.RequiredModuleNames()
for _, path := range m.InitRc() {
prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
@ -365,8 +365,8 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var propOut string
if l, ok := m.linker.(snapshotLibraryInterface); ok {
exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
if m.IsSnapshotLibrary() {
exporterInfo := ctx.ModuleProvider(m.Module(), FlagExporterInfoProvider).(FlagExporterInfo)
// library flags
prop.ExportedFlags = exporterInfo.Flags
@ -376,19 +376,22 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
for _, dir := range exporterInfo.SystemIncludeDirs {
prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
}
// shared libs dependencies aren't meaningful on static or header libs
if l.shared() {
prop.SharedLibs = m.Properties.SnapshotSharedLibs
if m.Shared() {
prop.SharedLibs = m.SnapshotSharedLibs()
}
if l.static() && m.sanitize != nil {
prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
if sanitizable, ok := m.(PlatformSanitizeable); ok {
if sanitizable.Static() && sanitizable.SanitizePropDefined() {
prop.SanitizeMinimalDep = sanitizable.MinimalRuntimeDep() || sanitizable.MinimalRuntimeNeeded()
prop.SanitizeUbsanDep = sanitizable.UbsanRuntimeDep() || sanitizable.UbsanRuntimeNeeded()
}
}
var libType string
if l.static() {
if m.Static() {
libType = "static"
} else if l.shared() {
} else if m.Shared() {
libType = "shared"
} else {
libType = "header"
@ -398,16 +401,18 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
// install .a or .so
if libType != "header" {
libPath := m.outputFile.Path()
libPath := m.OutputFile().Path()
stem = libPath.Base()
if l.static() && m.sanitize != nil && m.sanitize.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
ext := filepath.Ext(stem)
stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
prop.Sanitize = "cfi"
prop.ModuleName += ".cfi"
if sanitizable, ok := m.(PlatformSanitizeable); ok {
if sanitizable.Static() && 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
ext := filepath.Ext(stem)
stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
prop.Sanitize = "cfi"
prop.ModuleName += ".cfi"
}
}
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut, fake))
@ -416,20 +421,20 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
}
propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
} else if m.binary() {
} else if m.Binary() {
// binary flags
prop.Symlinks = m.Symlinks()
prop.SharedLibs = m.Properties.SnapshotSharedLibs
prop.SharedLibs = m.SnapshotSharedLibs()
// install bin
binPath := m.outputFile.Path()
binPath := m.OutputFile().Path()
snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
ret = append(ret, copyFile(ctx, binPath, snapshotBinOut, fake))
propOut = snapshotBinOut + ".json"
} else if m.object() {
} else if m.Object() {
// object files aren't installed to the device, so their names can conflict.
// Use module name as stem.
objPath := m.outputFile.Path()
objPath := m.OutputFile().Path()
snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
ret = append(ret, copyFile(ctx, objPath, snapshotObjOut, fake))
@ -450,7 +455,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
}
ctx.VisitAllModules(func(module android.Module) {
m, ok := module.(*Module)
m, ok := module.(LinkableInterface)
if !ok {
return
}
@ -484,8 +489,8 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
// installSnapshot installs prebuilts and json flag files
snapshotOutputs = append(snapshotOutputs, installSnapshot(m, installAsFake)...)
// 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()...)
if m.IsSnapshotLibrary() {
headers = append(headers, m.SnapshotHeaders()...)
}
if len(m.NoticeFiles()) > 0 {

View file

@ -372,7 +372,7 @@ func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
if mctx.ModuleName() == "libz" {
return false
}
return m.ImageVariation().Variation == android.CoreVariation && lib.shared() && m.isVndkSp()
return m.ImageVariation().Variation == android.CoreVariation && lib.shared() && m.IsVndkSp()
}
useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
@ -574,38 +574,37 @@ type vndkSnapshotSingleton struct {
vndkSnapshotZipFile android.OptionalPath
}
func isVndkSnapshotAware(config android.DeviceConfig, m *Module,
apexInfo android.ApexInfo) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
func isVndkSnapshotAware(config android.DeviceConfig, m LinkableInterface,
apexInfo android.ApexInfo) (vndkType string, isVndkSnapshotLib bool) {
if m.Target().NativeBridge == android.NativeBridgeEnabled {
return nil, "", false
return "", false
}
// !inVendor: There's product/vendor variants for VNDK libs. We only care about vendor variants.
// !installable: Snapshot only cares about "installable" modules.
// !m.IsLlndk: llndk stubs are required for building against snapshots.
// IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
// !outputFile.Valid: Snapshot requires valid output file.
if !m.InVendor() || (!m.installable(apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.outputFile.Valid() {
return nil, "", false
if !m.InVendor() || (!installable(m, apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.OutputFile().Valid() {
return "", false
}
l, ok := m.linker.(snapshotLibraryInterface)
if !ok || !l.shared() {
return nil, "", false
if !m.IsSnapshotLibrary() || !m.Shared() {
return "", false
}
if m.VndkVersion() == config.PlatformVndkVersion() {
if m.IsVndk() && !m.IsVndkExt() {
if m.isVndkSp() {
return l, "vndk-sp", true
if m.IsVndkSp() {
return "vndk-sp", true
} else {
return l, "vndk-core", true
return "vndk-core", true
}
} else if l.hasLLNDKStubs() && l.stubsVersion() == "" {
} else if m.HasLlndkStubs() && m.StubsVersion() == "" {
// Use default version for the snapshot.
return l, "llndk-stub", true
return "llndk-stub", true
}
}
return nil, "", false
return "", false
}
func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
@ -722,7 +721,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
l, vndkType, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo)
vndkType, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo)
if !ok {
return
}
@ -761,7 +760,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
}
if ctx.Config().VndkSnapshotBuildArtifacts() {
headers = append(headers, l.snapshotHeaders()...)
headers = append(headers, m.SnapshotHeaders()...)
}
})

View file

@ -893,7 +893,7 @@ func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
}
func (a *AndroidApp) PreventInstall() {
func (a *AndroidApp) SetPreventInstall() {
a.appProperties.PreventInstall = true
}

View file

@ -31,8 +31,9 @@ bootstrap_go_package {
"protobuf.go",
"rust.go",
"sanitize.go",
"strip.go",
"source_provider.go",
"snapshot_utils.go",
"strip.go",
"test.go",
"testing.go",
],

View file

@ -341,6 +341,11 @@ func (compiler *baseCompiler) crateName() string {
return compiler.Properties.Crate_name
}
func (compiler *baseCompiler) everInstallable() bool {
// Most modules are installable, so return true by default.
return true
}
func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
dir := compiler.dir
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {

View file

@ -82,3 +82,8 @@ func (procMacro *procMacroDecorator) getStem(ctx ModuleContext) string {
func (procMacro *procMacroDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
return rlibAutoDep
}
func (procMacro *procMacroDecorator) everInstallable() bool {
// Proc_macros are never installed
return false
}

View file

@ -97,6 +97,7 @@ type BaseProperties struct {
PreventInstall bool
HideFromMake bool
Installable *bool
}
type Module struct {
@ -143,6 +144,10 @@ func (mod *Module) SetHideFromMake() {
mod.Properties.HideFromMake = true
}
func (c *Module) HiddenFromMake() bool {
return c.Properties.HideFromMake
}
func (mod *Module) SanitizePropDefined() bool {
// Because compiler is not set for some Rust modules where sanitize might be set, check that compiler is also not
// nil since we need compiler to actually sanitize.
@ -210,6 +215,38 @@ func (mod *Module) Shared() bool {
return false
}
func (mod *Module) Dylib() bool {
if mod.compiler != nil {
if library, ok := mod.compiler.(libraryInterface); ok {
return library.dylib()
}
}
return false
}
func (mod *Module) Rlib() bool {
if mod.compiler != nil {
if library, ok := mod.compiler.(libraryInterface); ok {
return library.rlib()
}
}
return false
}
func (mod *Module) Binary() bool {
if mod.compiler != nil {
if _, ok := mod.compiler.(*binaryDecorator); ok {
return true
}
}
return false
}
func (mod *Module) Object() bool {
// Rust has no modules which produce only object files.
return false
}
func (mod *Module) Toc() android.OptionalPath {
if mod.compiler != nil {
if _, ok := mod.compiler.(libraryInterface); ok {
@ -223,12 +260,13 @@ func (mod *Module) UseSdk() bool {
return false
}
// Returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64.
// "product" and "vendor" variant modules return true for this function.
// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
// "soc_specific: true" and more vendor installed modules are included here.
// When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "vendor_available: true" or
// "product_specific: true" modules are included here.
func (mod *Module) RelativeInstallPath() string {
if mod.compiler != nil {
return mod.compiler.relativeInstallPath()
}
return ""
}
func (mod *Module) UseVndk() bool {
return mod.Properties.VndkVersion != ""
}
@ -250,6 +288,10 @@ func (mod *Module) IsVndkExt() bool {
return false
}
func (mod *Module) IsVndkSp() bool {
return false
}
func (c *Module) IsVndkPrivate() bool {
return false
}
@ -274,6 +316,14 @@ func (m *Module) NeedsVendorPublicLibraryVariants() bool {
return false
}
func (mod *Module) HasLlndkStubs() bool {
return false
}
func (mod *Module) StubsVersion() string {
panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", mod.BaseModuleName()))
}
func (mod *Module) SdkVersion() string {
return ""
}
@ -362,6 +412,7 @@ type compiler interface {
inData() bool
install(ctx ModuleContext)
relativeInstallPath() string
everInstallable() bool
nativeCoverage() bool
@ -423,8 +474,12 @@ func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
}
func (mod *Module) PreventInstall() {
mod.Properties.PreventInstall = true
func (mod *Module) VndkVersion() string {
return mod.Properties.VndkVersion
}
func (mod *Module) PreventInstall() bool {
return mod.Properties.PreventInstall
}
func (mod *Module) HideFromMake() {
@ -676,6 +731,16 @@ func (mod *Module) nativeCoverage() bool {
return mod.compiler != nil && mod.compiler.nativeCoverage()
}
func (mod *Module) EverInstallable() bool {
return mod.compiler != nil &&
// Check to see whether the module is actually ever installable.
mod.compiler.everInstallable()
}
func (mod *Module) Installable() *bool {
return mod.Properties.Installable
}
func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain {
if mod.cachedToolchain == nil {
mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())

View file

@ -189,6 +189,22 @@ func (sanitize *sanitize) SetSanitizer(t cc.SanitizerType, b bool) {
}
}
func (m *Module) UbsanRuntimeNeeded() bool {
return false
}
func (m *Module) MinimalRuntimeNeeded() bool {
return false
}
func (m *Module) UbsanRuntimeDep() bool {
return false
}
func (m *Module) MinimalRuntimeDep() bool {
return false
}
// Check if the sanitizer is explicitly disabled (as opposed to nil by
// virtue of not being set).
func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t cc.SanitizerType) bool {

54
rust/snapshot_utils.go Normal file
View file

@ -0,0 +1,54 @@
// 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"
)
func (mod *Module) ExcludeFromVendorSnapshot() bool {
// TODO Rust does not yet support snapshotting
return true
}
func (mod *Module) ExcludeFromRecoverySnapshot() bool {
// TODO Rust does not yet support snapshotting
return true
}
func (mod *Module) IsSnapshotLibrary() bool {
// TODO Rust does not yet support snapshotting
return false
}
func (mod *Module) SnapshotRuntimeLibs() []string {
// TODO Rust does not yet support a runtime libs notion similar to CC
return []string{}
}
func (mod *Module) SnapshotSharedLibs() []string {
// TODO Rust does not yet support snapshotting
return []string{}
}
func (mod *Module) Symlinks() []string {
// TODO update this to return the list of symlinks when Rust supports defining symlinks
return nil
}
func (m *Module) SnapshotHeaders() android.Paths {
// TODO Rust does not yet support snapshotting
return android.Paths{}
}