Merge "Refactor vendor snapshot to use LinkableInterface." am: 7ce2dee09e am: 61c475060a am: 001c11e93a

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1680606

Change-Id: Ifff15886dba6bda0754d086456a1db3b7524e4ed
This commit is contained in:
Ivan Lozano 2021-05-12 21:13:41 +00:00 committed by Automerger Merge Worker
commit a072c5ae56
18 changed files with 429 additions and 116 deletions

View file

@ -1209,7 +1209,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
}
@ -3062,7 +3072,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 {
@ -3071,7 +3081,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 {
@ -3153,18 +3163,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{}
}