Merge "Refactor vendor snapshot to use LinkableInterface." am: 7ce2dee09e
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1680606 Change-Id: I1d53688de1f994c9f2c83b723e433c3f02aea2a9
This commit is contained in:
@@ -1256,7 +1256,7 @@ func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implements cc.Coverage
|
// Implements cc.Coverage
|
||||||
func (a *apexBundle) PreventInstall() {
|
func (a *apexBundle) SetPreventInstall() {
|
||||||
a.properties.PreventInstall = true
|
a.properties.PreventInstall = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
cc/cc.go
57
cc/cc.go
@@ -841,6 +841,10 @@ func (c *Module) SetHideFromMake() {
|
|||||||
c.Properties.HideFromMake = true
|
c.Properties.HideFromMake = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Module) HiddenFromMake() bool {
|
||||||
|
return c.Properties.HideFromMake
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Module) Toc() android.OptionalPath {
|
func (c *Module) Toc() android.OptionalPath {
|
||||||
if c.linker != nil {
|
if c.linker != nil {
|
||||||
if library, ok := c.linker.(libraryInterface); ok {
|
if library, ok := c.linker.(libraryInterface); ok {
|
||||||
@@ -1088,12 +1092,6 @@ func (c *Module) IsDependencyRoot() bool {
|
|||||||
return false
|
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 {
|
func (c *Module) UseVndk() bool {
|
||||||
return c.Properties.VndkVersion != ""
|
return c.Properties.VndkVersion != ""
|
||||||
}
|
}
|
||||||
@@ -1141,6 +1139,18 @@ func (c *Module) IsVendorPublicLibrary() bool {
|
|||||||
return c.VendorProperties.IsVendorPublicLibrary
|
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
|
// isImplementationForLLNDKPublic returns true for any variant of a cc_library that has LLNDK stubs
|
||||||
// and does not set llndk.vendor_available: false.
|
// and does not set llndk.vendor_available: false.
|
||||||
func (c *Module) isImplementationForLLNDKPublic() bool {
|
func (c *Module) isImplementationForLLNDKPublic() bool {
|
||||||
@@ -1185,7 +1195,7 @@ func (c *Module) isNDKStubLibrary() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) isVndkSp() bool {
|
func (c *Module) IsVndkSp() bool {
|
||||||
if vndkdep := c.vndkdep; vndkdep != nil {
|
if vndkdep := c.vndkdep; vndkdep != nil {
|
||||||
return vndkdep.isVndkSp()
|
return vndkdep.isVndkSp()
|
||||||
}
|
}
|
||||||
@@ -1204,7 +1214,7 @@ func (c *Module) SubName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) MustUseVendorVariant() bool {
|
func (c *Module) MustUseVendorVariant() bool {
|
||||||
return c.isVndkSp() || c.Properties.MustUseVendorVariant
|
return c.IsVndkSp() || c.Properties.MustUseVendorVariant
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) getVndkExtendsModuleName() string {
|
func (c *Module) getVndkExtendsModuleName() string {
|
||||||
@@ -1343,11 +1353,11 @@ func (ctx *moduleContextImpl) header() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *moduleContextImpl) binary() bool {
|
func (ctx *moduleContextImpl) binary() bool {
|
||||||
return ctx.mod.binary()
|
return ctx.mod.Binary()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *moduleContextImpl) object() bool {
|
func (ctx *moduleContextImpl) object() bool {
|
||||||
return ctx.mod.object()
|
return ctx.mod.Object()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *moduleContextImpl) canUseSdk() bool {
|
func (ctx *moduleContextImpl) canUseSdk() bool {
|
||||||
@@ -1445,7 +1455,7 @@ func (ctx *moduleContextImpl) isNDKStubLibrary() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *moduleContextImpl) isVndkSp() bool {
|
func (ctx *moduleContextImpl) isVndkSp() bool {
|
||||||
return ctx.mod.isVndkSp()
|
return ctx.mod.IsVndkSp()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *moduleContextImpl) IsVndkExt() bool {
|
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
|
// glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
|
||||||
// RECOVERY_SNAPSHOT_VERSION is current.
|
// RECOVERY_SNAPSHOT_VERSION is current.
|
||||||
if i, ok := c.linker.(snapshotLibraryInterface); ok {
|
if i, ok := c.linker.(snapshotLibraryInterface); ok {
|
||||||
if shouldCollectHeadersForSnapshot(ctx, c, apexInfo) {
|
if ShouldCollectHeadersForSnapshot(ctx, c, apexInfo) {
|
||||||
i.collectHeadersForSnapshot(ctx)
|
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
|
// modules can be hidden from make as some are needed for resolving make side
|
||||||
// dependencies.
|
// dependencies.
|
||||||
c.HideFromMake()
|
c.HideFromMake()
|
||||||
} else if !c.installable(apexInfo) {
|
} else if !installable(c, apexInfo) {
|
||||||
c.SkipInstall()
|
c.SkipInstall()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2451,7 +2461,7 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if to.isVndkSp() || to.IsLlndk() {
|
if to.IsVndkSp() || to.IsLlndk() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3064,7 +3074,7 @@ func (c *Module) Header() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) binary() bool {
|
func (c *Module) Binary() bool {
|
||||||
if b, ok := c.linker.(interface {
|
if b, ok := c.linker.(interface {
|
||||||
binary() bool
|
binary() bool
|
||||||
}); ok {
|
}); ok {
|
||||||
@@ -3073,7 +3083,7 @@ func (c *Module) binary() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) object() bool {
|
func (c *Module) Object() bool {
|
||||||
if o, ok := c.linker.(interface {
|
if o, ok := c.linker.(interface {
|
||||||
object() bool
|
object() bool
|
||||||
}); ok {
|
}); ok {
|
||||||
@@ -3155,18 +3165,25 @@ func (c *Module) UniqueApexVariations() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the module is ever installable.
|
|
||||||
func (c *Module) EverInstallable() bool {
|
func (c *Module) EverInstallable() bool {
|
||||||
return c.installer != nil &&
|
return c.installer != nil &&
|
||||||
// Check to see whether the module is actually ever installable.
|
// Check to see whether the module is actually ever installable.
|
||||||
c.installer.everInstallable()
|
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() &&
|
ret := c.EverInstallable() &&
|
||||||
// Check to see whether the module has been configured to not be installed.
|
// Check to see whether the module has been configured to not be installed.
|
||||||
proptools.BoolDefault(c.Properties.Installable, true) &&
|
proptools.BoolDefault(c.Installable(), true) &&
|
||||||
!c.Properties.PreventInstall && c.outputFile.Valid()
|
!c.PreventInstall() && c.OutputFile().Valid()
|
||||||
|
|
||||||
// The platform variant doesn't need further condition. Apex variants however might not
|
// 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
|
// be installable because it will likely to be included in the APEX and won't appear
|
||||||
|
@@ -381,8 +381,8 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string
|
|||||||
if !mod.IsVndk() {
|
if !mod.IsVndk() {
|
||||||
t.Errorf("%q IsVndk() must equal to true", name)
|
t.Errorf("%q IsVndk() must equal to true", name)
|
||||||
}
|
}
|
||||||
if mod.isVndkSp() != isVndkSp {
|
if mod.IsVndkSp() != isVndkSp {
|
||||||
t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
|
t.Errorf("%q IsVndkSp() must equal to %t", name, isVndkSp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check VNDK extension properties.
|
// Check VNDK extension properties.
|
||||||
|
@@ -203,7 +203,7 @@ func SetCoverageProperties(ctx android.BaseModuleContext, properties CoveragePro
|
|||||||
type Coverage interface {
|
type Coverage interface {
|
||||||
android.Module
|
android.Module
|
||||||
IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
|
IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
|
||||||
PreventInstall()
|
SetPreventInstall()
|
||||||
HideFromMake()
|
HideFromMake()
|
||||||
MarkAsCoverageVariant(bool)
|
MarkAsCoverageVariant(bool)
|
||||||
EnableCoverageIfNeeded()
|
EnableCoverageIfNeeded()
|
||||||
@@ -236,7 +236,7 @@ func coverageMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
// to an APEX via 'data' property.
|
// to an APEX via 'data' property.
|
||||||
m := mctx.CreateVariations("", "cov")
|
m := mctx.CreateVariations("", "cov")
|
||||||
m[0].(Coverage).MarkAsCoverageVariant(false)
|
m[0].(Coverage).MarkAsCoverageVariant(false)
|
||||||
m[0].(Coverage).PreventInstall()
|
m[0].(Coverage).SetPreventInstall()
|
||||||
m[0].(Coverage).HideFromMake()
|
m[0].(Coverage).HideFromMake()
|
||||||
|
|
||||||
m[1].(Coverage).MarkAsCoverageVariant(true)
|
m[1].(Coverage).MarkAsCoverageVariant(true)
|
||||||
|
106
cc/linkable.go
106
cc/linkable.go
@@ -48,6 +48,20 @@ type PlatformSanitizeable interface {
|
|||||||
// SanitizerSupported returns true if a sanitizer type is supported by this modules compiler.
|
// SanitizerSupported returns true if a sanitizer type is supported by this modules compiler.
|
||||||
SanitizerSupported(t SanitizerType) bool
|
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 returns a SantizableDependencyTagChecker function type.
|
||||||
SanitizableDepTagChecker() SantizableDependencyTagChecker
|
SanitizableDepTagChecker() SantizableDependencyTagChecker
|
||||||
}
|
}
|
||||||
@@ -60,14 +74,42 @@ type PlatformSanitizeable interface {
|
|||||||
// implementation should handle tags from both.
|
// implementation should handle tags from both.
|
||||||
type SantizableDependencyTagChecker func(tag blueprint.DependencyTag) bool
|
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.
|
// LinkableInterface is an interface for a type of module that is linkable in a C++ library.
|
||||||
type LinkableInterface interface {
|
type LinkableInterface interface {
|
||||||
android.Module
|
android.Module
|
||||||
|
Snapshottable
|
||||||
|
|
||||||
Module() android.Module
|
Module() android.Module
|
||||||
CcLibrary() bool
|
CcLibrary() bool
|
||||||
CcLibraryInterface() bool
|
CcLibraryInterface() bool
|
||||||
|
|
||||||
|
// BaseModuleName returns the android.ModuleBase.BaseModuleName() value for this module.
|
||||||
|
BaseModuleName() string
|
||||||
|
|
||||||
OutputFile() android.OptionalPath
|
OutputFile() android.OptionalPath
|
||||||
CoverageFiles() android.Paths
|
CoverageFiles() android.Paths
|
||||||
|
|
||||||
@@ -79,9 +121,6 @@ type LinkableInterface interface {
|
|||||||
BuildSharedVariant() bool
|
BuildSharedVariant() bool
|
||||||
SetStatic()
|
SetStatic()
|
||||||
SetShared()
|
SetShared()
|
||||||
Static() bool
|
|
||||||
Shared() bool
|
|
||||||
Header() bool
|
|
||||||
IsPrebuilt() bool
|
IsPrebuilt() bool
|
||||||
Toc() android.OptionalPath
|
Toc() android.OptionalPath
|
||||||
|
|
||||||
@@ -106,13 +145,29 @@ type LinkableInterface interface {
|
|||||||
// IsLlndkPublic returns true only for LLNDK (public) libs.
|
// IsLlndkPublic returns true only for LLNDK (public) libs.
|
||||||
IsLlndkPublic() bool
|
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 returns true if this module has LLNDK stubs or provides LLNDK headers.
|
||||||
NeedsLlndkVariants() bool
|
NeedsLlndkVariants() bool
|
||||||
|
|
||||||
// NeedsVendorPublicLibraryVariants returns true if this module has vendor public library stubs.
|
// NeedsVendorPublicLibraryVariants returns true if this module has vendor public library stubs.
|
||||||
NeedsVendorPublicLibraryVariants() bool
|
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
|
UseVndk() bool
|
||||||
|
|
||||||
|
// IsVndkSp returns true if this is a VNDK-SP module.
|
||||||
|
IsVndkSp() bool
|
||||||
|
|
||||||
MustUseVendorVariant() bool
|
MustUseVendorVariant() bool
|
||||||
IsVndk() bool
|
IsVndk() bool
|
||||||
IsVndkExt() bool
|
IsVndkExt() bool
|
||||||
@@ -140,6 +195,51 @@ type LinkableInterface interface {
|
|||||||
// KernelHeadersDecorator returns true if this is a kernel headers decorator module.
|
// 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.
|
// This is specific to cc and should always return false for all other packages.
|
||||||
KernelHeadersDecorator() bool
|
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 (
|
var (
|
||||||
|
@@ -84,7 +84,7 @@ func classifySourceAbiDump(ctx android.BaseModuleContext) string {
|
|||||||
return "LLNDK"
|
return "LLNDK"
|
||||||
}
|
}
|
||||||
if m.UseVndk() && m.IsVndk() && !m.IsVndkPrivate() {
|
if m.UseVndk() && m.IsVndk() && !m.IsVndkPrivate() {
|
||||||
if m.isVndkSp() {
|
if m.IsVndkSp() {
|
||||||
if m.IsVndkExt() {
|
if m.IsVndkExt() {
|
||||||
return "VNDK-SP-ext"
|
return "VNDK-SP-ext"
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1075,7 +1075,7 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
sanitizers = append(sanitizers, "shadow-call-stack")
|
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"
|
noteDep := "note_memtag_heap_async"
|
||||||
if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
|
if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
|
||||||
noteDep = "note_memtag_heap_sync"
|
noteDep = "note_memtag_heap_sync"
|
||||||
@@ -1208,6 +1208,14 @@ type Sanitizeable interface {
|
|||||||
AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string)
|
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 {
|
func (c *Module) SanitizePropDefined() bool {
|
||||||
return c.sanitize != nil
|
return c.sanitize != nil
|
||||||
}
|
}
|
||||||
@@ -1441,6 +1449,14 @@ func enableMinimalRuntime(sanitize *sanitize) bool {
|
|||||||
return false
|
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 {
|
func enableUbsanRuntime(sanitize *sanitize) bool {
|
||||||
return Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
|
return Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
|
||||||
Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||
|
Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||
|
||||||
|
@@ -35,12 +35,12 @@ type snapshotImage interface {
|
|||||||
// Function that returns true if the module is included in this image.
|
// Function that returns true if the module is included in this image.
|
||||||
// Using a function return instead of a value to prevent early
|
// Using a function return instead of a value to prevent early
|
||||||
// evalution of a function that may be not be defined.
|
// 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
|
// 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
|
// snapshot. For example VNDK-private modules must return true for the
|
||||||
// vendor snapshots. But false for the recovery snapshots.
|
// 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
|
// Returns true if a dir under source tree is an SoC-owned proprietary
|
||||||
// directory, such as device/, vendor/, etc.
|
// directory, such as device/, vendor/, etc.
|
||||||
@@ -56,7 +56,7 @@ type snapshotImage interface {
|
|||||||
// Whether a given module has been explicitly excluded from the
|
// Whether a given module has been explicitly excluded from the
|
||||||
// snapshot, e.g., using the exclude_from_vendor_snapshot or
|
// snapshot, e.g., using the exclude_from_vendor_snapshot or
|
||||||
// exclude_from_recovery_snapshot properties.
|
// 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.
|
// Returns true if the build is using a snapshot for this image.
|
||||||
isUsingSnapshot(cfg android.DeviceConfig) bool
|
isUsingSnapshot(cfg android.DeviceConfig) bool
|
||||||
@@ -125,11 +125,11 @@ func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext)
|
|||||||
return ctx.DeviceConfig().VndkVersion() == "current"
|
return ctx.DeviceConfig().VndkVersion() == "current"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vendorSnapshotImage) inImage(m *Module) func() bool {
|
func (vendorSnapshotImage) inImage(m LinkableInterface) func() bool {
|
||||||
return m.InVendor
|
return m.InVendor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vendorSnapshotImage) private(m *Module) bool {
|
func (vendorSnapshotImage) private(m LinkableInterface) bool {
|
||||||
return m.IsVndkPrivate()
|
return m.IsVndkPrivate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ func (vendorSnapshotImage) includeVndk() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vendorSnapshotImage) excludeFromSnapshot(m *Module) bool {
|
func (vendorSnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
|
||||||
return m.ExcludeFromVendorSnapshot()
|
return m.ExcludeFromVendorSnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,12 +206,12 @@ func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext
|
|||||||
return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
|
return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (recoverySnapshotImage) inImage(m *Module) func() bool {
|
func (recoverySnapshotImage) inImage(m LinkableInterface) func() bool {
|
||||||
return m.InRecovery
|
return m.InRecovery
|
||||||
}
|
}
|
||||||
|
|
||||||
// recovery snapshot does not have private libraries.
|
// recovery snapshot does not have private libraries.
|
||||||
func (recoverySnapshotImage) private(m *Module) bool {
|
func (recoverySnapshotImage) private(m LinkableInterface) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ func (recoverySnapshotImage) includeVndk() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (recoverySnapshotImage) excludeFromSnapshot(m *Module) bool {
|
func (recoverySnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
|
||||||
return m.ExcludeFromRecoverySnapshot()
|
return m.ExcludeFromRecoverySnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,6 +23,36 @@ var (
|
|||||||
headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
|
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.
|
// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
|
||||||
type snapshotLibraryInterface interface {
|
type snapshotLibraryInterface interface {
|
||||||
libraryInterface
|
libraryInterface
|
||||||
@@ -68,14 +98,14 @@ func (s *snapshotMap) get(name string, arch android.ArchType) (snapshot string,
|
|||||||
return snapshot, found
|
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.
|
// 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" &&
|
if ctx.DeviceConfig().VndkVersion() != "current" &&
|
||||||
ctx.DeviceConfig().RecoverySnapshotVersion() != "current" {
|
ctx.DeviceConfig().RecoverySnapshotVersion() != "current" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if _, _, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo); ok {
|
if _, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo); ok {
|
||||||
return ctx.Config().VndkSnapshotBuildArtifacts()
|
return ctx.Config().VndkSnapshotBuildArtifacts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -115,7 +115,7 @@ func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
|
|||||||
// still be a vendor proprietary module. This happens for cc modules
|
// still be a vendor proprietary module. This happens for cc modules
|
||||||
// that are excluded from the vendor snapshot, and it means that the
|
// that are excluded from the vendor snapshot, and it means that the
|
||||||
// vendor has assumed control of the framework-provided module.
|
// 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() {
|
if c.ExcludeFromVendorSnapshot() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
|
|||||||
// that are excluded from the recovery snapshot, and it means that the
|
// that are excluded from the recovery snapshot, and it means that the
|
||||||
// vendor has assumed control of the framework-provided module.
|
// 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() {
|
if c.ExcludeFromRecoverySnapshot() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -147,8 +147,8 @@ func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determines if the module is a candidate for snapshot.
|
// Determines if the module is a candidate for snapshot.
|
||||||
func isSnapshotAware(cfg android.DeviceConfig, m *Module, 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.Properties.HideFromMake {
|
if !m.Enabled() || m.HiddenFromMake() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// When android/prebuilt.go selects between source and prebuilt, it sets
|
// 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
|
return false
|
||||||
}
|
}
|
||||||
// skip kernel_headers which always depend on vendor
|
// skip kernel_headers which always depend on vendor
|
||||||
if _, ok := m.linker.(*kernelHeadersDecorator); ok {
|
if m.KernelHeadersDecorator() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// skip LLNDK libraries which are backward compatible
|
|
||||||
if m.IsLlndk() {
|
if m.IsLlndk() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
if l, ok := m.linker.(snapshotLibraryInterface); ok {
|
if sanitizable, ok := m.(PlatformSanitizeable); ok && sanitizable.IsSnapshotLibrary() {
|
||||||
if m.sanitize != nil {
|
if sanitizable.SanitizePropDefined() {
|
||||||
// scs and hwasan export both sanitized and unsanitized variants for static and header
|
// scs and hwasan export both sanitized and unsanitized variants for static and header
|
||||||
// Always use unsanitized variants of them.
|
// Always use unsanitized variants of them.
|
||||||
for _, t := range []SanitizerType{scs, Hwasan} {
|
for _, t := range []SanitizerType{scs, Hwasan} {
|
||||||
if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
|
if !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(t) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// cfi also exports both variants. But for static, we capture both.
|
// 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,
|
// 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.
|
// 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
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if l.static() {
|
if sanitizable.Static() {
|
||||||
return m.outputFile.Valid() && !image.private(m)
|
return sanitizable.OutputFile().Valid() && !image.private(m)
|
||||||
}
|
}
|
||||||
if l.shared() {
|
if sanitizable.Shared() {
|
||||||
if !m.outputFile.Valid() {
|
if !sanitizable.OutputFile().Valid() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if image.includeVndk() {
|
if image.includeVndk() {
|
||||||
if !m.IsVndk() {
|
if !sanitizable.IsVndk() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return m.IsVndkExt()
|
return sanitizable.IsVndkExt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binaries and Objects
|
// Binaries and Objects
|
||||||
if m.binary() || m.object() {
|
if m.Binary() || m.Object() {
|
||||||
return m.outputFile.Valid()
|
return m.OutputFile().Valid()
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
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.
|
// installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
|
||||||
// For executables, init_rc and vintf_fragments files are also copied.
|
// 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()
|
targetArch := "arch-" + m.Target().Arch.ArchType.String()
|
||||||
if m.Target().Arch.ArchVariant != "" {
|
if m.Target().Arch.ArchVariant != "" {
|
||||||
targetArch += "-" + 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)
|
prop.ModuleName = ctx.ModuleName(m)
|
||||||
if c.supportsVndkExt && m.IsVndkExt() {
|
if c.supportsVndkExt && m.IsVndkExt() {
|
||||||
// vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
|
// vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
|
||||||
if m.isVndkSp() {
|
if m.IsVndkSp() {
|
||||||
prop.RelativeInstallPath = "vndk-sp"
|
prop.RelativeInstallPath = "vndk-sp"
|
||||||
} else {
|
} else {
|
||||||
prop.RelativeInstallPath = "vndk"
|
prop.RelativeInstallPath = "vndk"
|
||||||
@@ -345,7 +345,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
} else {
|
} else {
|
||||||
prop.RelativeInstallPath = m.RelativeInstallPath()
|
prop.RelativeInstallPath = m.RelativeInstallPath()
|
||||||
}
|
}
|
||||||
prop.RuntimeLibs = m.Properties.SnapshotRuntimeLibs
|
prop.RuntimeLibs = m.SnapshotRuntimeLibs()
|
||||||
prop.Required = m.RequiredModuleNames()
|
prop.Required = m.RequiredModuleNames()
|
||||||
for _, path := range m.InitRc() {
|
for _, path := range m.InitRc() {
|
||||||
prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
|
prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
|
||||||
@@ -365,8 +365,8 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
|
|
||||||
var propOut string
|
var propOut string
|
||||||
|
|
||||||
if l, ok := m.linker.(snapshotLibraryInterface); ok {
|
if m.IsSnapshotLibrary() {
|
||||||
exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
|
exporterInfo := ctx.ModuleProvider(m.Module(), FlagExporterInfoProvider).(FlagExporterInfo)
|
||||||
|
|
||||||
// library flags
|
// library flags
|
||||||
prop.ExportedFlags = exporterInfo.Flags
|
prop.ExportedFlags = exporterInfo.Flags
|
||||||
@@ -376,19 +376,22 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
for _, dir := range exporterInfo.SystemIncludeDirs {
|
for _, dir := range exporterInfo.SystemIncludeDirs {
|
||||||
prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
|
prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared libs dependencies aren't meaningful on static or header libs
|
// shared libs dependencies aren't meaningful on static or header libs
|
||||||
if l.shared() {
|
if m.Shared() {
|
||||||
prop.SharedLibs = m.Properties.SnapshotSharedLibs
|
prop.SharedLibs = m.SnapshotSharedLibs()
|
||||||
|
}
|
||||||
|
if sanitizable, ok := m.(PlatformSanitizeable); ok {
|
||||||
|
if sanitizable.Static() && sanitizable.SanitizePropDefined() {
|
||||||
|
prop.SanitizeMinimalDep = sanitizable.MinimalRuntimeDep() || sanitizable.MinimalRuntimeNeeded()
|
||||||
|
prop.SanitizeUbsanDep = sanitizable.UbsanRuntimeDep() || sanitizable.UbsanRuntimeNeeded()
|
||||||
}
|
}
|
||||||
if l.static() && m.sanitize != nil {
|
|
||||||
prop.SanitizeMinimalDep = m.sanitize.Properties.MinimalRuntimeDep || enableMinimalRuntime(m.sanitize)
|
|
||||||
prop.SanitizeUbsanDep = m.sanitize.Properties.UbsanRuntimeDep || enableUbsanRuntime(m.sanitize)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var libType string
|
var libType string
|
||||||
if l.static() {
|
if m.Static() {
|
||||||
libType = "static"
|
libType = "static"
|
||||||
} else if l.shared() {
|
} else if m.Shared() {
|
||||||
libType = "shared"
|
libType = "shared"
|
||||||
} else {
|
} else {
|
||||||
libType = "header"
|
libType = "header"
|
||||||
@@ -398,9 +401,10 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
|
|
||||||
// install .a or .so
|
// install .a or .so
|
||||||
if libType != "header" {
|
if libType != "header" {
|
||||||
libPath := m.outputFile.Path()
|
libPath := m.OutputFile().Path()
|
||||||
stem = libPath.Base()
|
stem = libPath.Base()
|
||||||
if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(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.
|
// both cfi and non-cfi variant for static libraries can exist.
|
||||||
// attach .cfi to distinguish between cfi and non-cfi.
|
// attach .cfi to distinguish between cfi and non-cfi.
|
||||||
// e.g. libbase.a -> libbase.cfi.a
|
// e.g. libbase.a -> libbase.cfi.a
|
||||||
@@ -409,6 +413,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
prop.Sanitize = "cfi"
|
prop.Sanitize = "cfi"
|
||||||
prop.ModuleName += ".cfi"
|
prop.ModuleName += ".cfi"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
|
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
|
||||||
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut, fake))
|
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut, fake))
|
||||||
} else {
|
} else {
|
||||||
@@ -416,20 +421,20 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
|
propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
|
||||||
} else if m.binary() {
|
} else if m.Binary() {
|
||||||
// binary flags
|
// binary flags
|
||||||
prop.Symlinks = m.Symlinks()
|
prop.Symlinks = m.Symlinks()
|
||||||
prop.SharedLibs = m.Properties.SnapshotSharedLibs
|
prop.SharedLibs = m.SnapshotSharedLibs()
|
||||||
|
|
||||||
// install bin
|
// install bin
|
||||||
binPath := m.outputFile.Path()
|
binPath := m.OutputFile().Path()
|
||||||
snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
|
snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
|
||||||
ret = append(ret, copyFile(ctx, binPath, snapshotBinOut, fake))
|
ret = append(ret, copyFile(ctx, binPath, snapshotBinOut, fake))
|
||||||
propOut = snapshotBinOut + ".json"
|
propOut = snapshotBinOut + ".json"
|
||||||
} else if m.object() {
|
} else if m.Object() {
|
||||||
// object files aren't installed to the device, so their names can conflict.
|
// object files aren't installed to the device, so their names can conflict.
|
||||||
// Use module name as stem.
|
// Use module name as stem.
|
||||||
objPath := m.outputFile.Path()
|
objPath := m.OutputFile().Path()
|
||||||
snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
|
snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
|
||||||
ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
|
ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
|
||||||
ret = append(ret, copyFile(ctx, objPath, snapshotObjOut, fake))
|
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) {
|
ctx.VisitAllModules(func(module android.Module) {
|
||||||
m, ok := module.(*Module)
|
m, ok := module.(LinkableInterface)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -484,8 +489,8 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
// installSnapshot installs prebuilts and json flag files
|
// installSnapshot installs prebuilts and json flag files
|
||||||
snapshotOutputs = append(snapshotOutputs, installSnapshot(m, installAsFake)...)
|
snapshotOutputs = append(snapshotOutputs, installSnapshot(m, installAsFake)...)
|
||||||
// just gather headers and notice files here, because they are to be deduplicated
|
// just gather headers and notice files here, because they are to be deduplicated
|
||||||
if l, ok := m.linker.(snapshotLibraryInterface); ok {
|
if m.IsSnapshotLibrary() {
|
||||||
headers = append(headers, l.snapshotHeaders()...)
|
headers = append(headers, m.SnapshotHeaders()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(m.NoticeFiles()) > 0 {
|
if len(m.NoticeFiles()) > 0 {
|
||||||
|
33
cc/vndk.go
33
cc/vndk.go
@@ -372,7 +372,7 @@ func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
|
|||||||
if mctx.ModuleName() == "libz" {
|
if mctx.ModuleName() == "libz" {
|
||||||
return false
|
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() &&
|
useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
|
||||||
@@ -574,38 +574,37 @@ type vndkSnapshotSingleton struct {
|
|||||||
vndkSnapshotZipFile android.OptionalPath
|
vndkSnapshotZipFile android.OptionalPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func isVndkSnapshotAware(config android.DeviceConfig, m *Module,
|
func isVndkSnapshotAware(config android.DeviceConfig, m LinkableInterface,
|
||||||
apexInfo android.ApexInfo) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
|
apexInfo android.ApexInfo) (vndkType string, isVndkSnapshotLib bool) {
|
||||||
|
|
||||||
if m.Target().NativeBridge == android.NativeBridgeEnabled {
|
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.
|
// !inVendor: There's product/vendor variants for VNDK libs. We only care about vendor variants.
|
||||||
// !installable: Snapshot only cares about "installable" modules.
|
// !installable: Snapshot only cares about "installable" modules.
|
||||||
// !m.IsLlndk: llndk stubs are required for building against snapshots.
|
// !m.IsLlndk: llndk stubs are required for building against snapshots.
|
||||||
// IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
|
// IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
|
||||||
// !outputFile.Valid: Snapshot requires valid output file.
|
// !outputFile.Valid: Snapshot requires valid output file.
|
||||||
if !m.InVendor() || (!m.installable(apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.outputFile.Valid() {
|
if !m.InVendor() || (!installable(m, apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.OutputFile().Valid() {
|
||||||
return nil, "", false
|
return "", false
|
||||||
}
|
}
|
||||||
l, ok := m.linker.(snapshotLibraryInterface)
|
if !m.IsSnapshotLibrary() || !m.Shared() {
|
||||||
if !ok || !l.shared() {
|
return "", false
|
||||||
return nil, "", false
|
|
||||||
}
|
}
|
||||||
if m.VndkVersion() == config.PlatformVndkVersion() {
|
if m.VndkVersion() == config.PlatformVndkVersion() {
|
||||||
if m.IsVndk() && !m.IsVndkExt() {
|
if m.IsVndk() && !m.IsVndkExt() {
|
||||||
if m.isVndkSp() {
|
if m.IsVndkSp() {
|
||||||
return l, "vndk-sp", true
|
return "vndk-sp", true
|
||||||
} else {
|
} 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.
|
// 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) {
|
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)
|
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 {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -761,7 +760,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Config().VndkSnapshotBuildArtifacts() {
|
if ctx.Config().VndkSnapshotBuildArtifacts() {
|
||||||
headers = append(headers, l.snapshotHeaders()...)
|
headers = append(headers, m.SnapshotHeaders()...)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -893,7 +893,7 @@ func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
|
|||||||
return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
|
return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) PreventInstall() {
|
func (a *AndroidApp) SetPreventInstall() {
|
||||||
a.appProperties.PreventInstall = true
|
a.appProperties.PreventInstall = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,8 +31,9 @@ bootstrap_go_package {
|
|||||||
"protobuf.go",
|
"protobuf.go",
|
||||||
"rust.go",
|
"rust.go",
|
||||||
"sanitize.go",
|
"sanitize.go",
|
||||||
"strip.go",
|
|
||||||
"source_provider.go",
|
"source_provider.go",
|
||||||
|
"snapshot_utils.go",
|
||||||
|
"strip.go",
|
||||||
"test.go",
|
"test.go",
|
||||||
"testing.go",
|
"testing.go",
|
||||||
],
|
],
|
||||||
|
@@ -341,6 +341,11 @@ func (compiler *baseCompiler) crateName() string {
|
|||||||
return compiler.Properties.Crate_name
|
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 {
|
func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
|
||||||
dir := compiler.dir
|
dir := compiler.dir
|
||||||
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
|
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
|
||||||
|
@@ -82,3 +82,8 @@ func (procMacro *procMacroDecorator) getStem(ctx ModuleContext) string {
|
|||||||
func (procMacro *procMacroDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
|
func (procMacro *procMacroDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (procMacro *procMacroDecorator) everInstallable() bool {
|
||||||
|
// Proc_macros are never installed
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
81
rust/rust.go
81
rust/rust.go
@@ -97,6 +97,7 @@ type BaseProperties struct {
|
|||||||
|
|
||||||
PreventInstall bool
|
PreventInstall bool
|
||||||
HideFromMake bool
|
HideFromMake bool
|
||||||
|
Installable *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Module struct {
|
type Module struct {
|
||||||
@@ -143,6 +144,10 @@ func (mod *Module) SetHideFromMake() {
|
|||||||
mod.Properties.HideFromMake = true
|
mod.Properties.HideFromMake = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Module) HiddenFromMake() bool {
|
||||||
|
return c.Properties.HideFromMake
|
||||||
|
}
|
||||||
|
|
||||||
func (mod *Module) SanitizePropDefined() bool {
|
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
|
// 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.
|
// nil since we need compiler to actually sanitize.
|
||||||
@@ -210,6 +215,38 @@ func (mod *Module) Shared() bool {
|
|||||||
return false
|
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 {
|
func (mod *Module) Toc() android.OptionalPath {
|
||||||
if mod.compiler != nil {
|
if mod.compiler != nil {
|
||||||
if _, ok := mod.compiler.(libraryInterface); ok {
|
if _, ok := mod.compiler.(libraryInterface); ok {
|
||||||
@@ -223,12 +260,13 @@ func (mod *Module) UseSdk() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64.
|
func (mod *Module) RelativeInstallPath() string {
|
||||||
// "product" and "vendor" variant modules return true for this function.
|
if mod.compiler != nil {
|
||||||
// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
|
return mod.compiler.relativeInstallPath()
|
||||||
// "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
|
return ""
|
||||||
// "product_specific: true" modules are included here.
|
}
|
||||||
|
|
||||||
func (mod *Module) UseVndk() bool {
|
func (mod *Module) UseVndk() bool {
|
||||||
return mod.Properties.VndkVersion != ""
|
return mod.Properties.VndkVersion != ""
|
||||||
}
|
}
|
||||||
@@ -250,6 +288,10 @@ func (mod *Module) IsVndkExt() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mod *Module) IsVndkSp() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Module) IsVndkPrivate() bool {
|
func (c *Module) IsVndkPrivate() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -274,6 +316,14 @@ func (m *Module) NeedsVendorPublicLibraryVariants() bool {
|
|||||||
return false
|
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 {
|
func (mod *Module) SdkVersion() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -362,6 +412,7 @@ type compiler interface {
|
|||||||
inData() bool
|
inData() bool
|
||||||
install(ctx ModuleContext)
|
install(ctx ModuleContext)
|
||||||
relativeInstallPath() string
|
relativeInstallPath() string
|
||||||
|
everInstallable() bool
|
||||||
|
|
||||||
nativeCoverage() bool
|
nativeCoverage() bool
|
||||||
|
|
||||||
@@ -423,8 +474,12 @@ func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
|
|||||||
return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
|
return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) PreventInstall() {
|
func (mod *Module) VndkVersion() string {
|
||||||
mod.Properties.PreventInstall = true
|
return mod.Properties.VndkVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *Module) PreventInstall() bool {
|
||||||
|
return mod.Properties.PreventInstall
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) HideFromMake() {
|
func (mod *Module) HideFromMake() {
|
||||||
@@ -676,6 +731,16 @@ func (mod *Module) nativeCoverage() bool {
|
|||||||
return mod.compiler != nil && mod.compiler.nativeCoverage()
|
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 {
|
func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain {
|
||||||
if mod.cachedToolchain == nil {
|
if mod.cachedToolchain == nil {
|
||||||
mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
|
mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
|
||||||
|
@@ -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
|
// Check if the sanitizer is explicitly disabled (as opposed to nil by
|
||||||
// virtue of not being set).
|
// virtue of not being set).
|
||||||
func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t cc.SanitizerType) bool {
|
func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t cc.SanitizerType) bool {
|
||||||
|
54
rust/snapshot_utils.go
Normal file
54
rust/snapshot_utils.go
Normal 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{}
|
||||||
|
}
|
Reference in New Issue
Block a user