diff --git a/apex/apex.go b/apex/apex.go index 2c0df2785..24af85df0 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1256,7 +1256,7 @@ func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool } // Implements cc.Coverage -func (a *apexBundle) PreventInstall() { +func (a *apexBundle) SetPreventInstall() { a.properties.PreventInstall = true } diff --git a/cc/cc.go b/cc/cc.go index 16a49d343..2520705fd 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -841,6 +841,10 @@ func (c *Module) SetHideFromMake() { c.Properties.HideFromMake = true } +func (c *Module) HiddenFromMake() bool { + return c.Properties.HideFromMake +} + func (c *Module) Toc() android.OptionalPath { if c.linker != nil { if library, ok := c.linker.(libraryInterface); ok { @@ -1088,12 +1092,6 @@ func (c *Module) IsDependencyRoot() bool { return false } -// Returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64. -// "product" and "vendor" variant modules return true for this function. -// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true", -// "soc_specific: true" and more vendor installed modules are included here. -// When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "product_available: true" or -// "product_specific: true" modules are included here. func (c *Module) UseVndk() bool { return c.Properties.VndkVersion != "" } @@ -1141,6 +1139,18 @@ func (c *Module) IsVendorPublicLibrary() bool { return c.VendorProperties.IsVendorPublicLibrary } +func (c *Module) HasLlndkStubs() bool { + lib := moduleLibraryInterface(c) + return lib != nil && lib.hasLLNDKStubs() +} + +func (c *Module) StubsVersion() string { + if lib, ok := c.linker.(versionedInterface); ok { + return lib.stubsVersion() + } + panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", c.BaseModuleName())) +} + // isImplementationForLLNDKPublic returns true for any variant of a cc_library that has LLNDK stubs // and does not set llndk.vendor_available: false. func (c *Module) isImplementationForLLNDKPublic() bool { @@ -1185,7 +1195,7 @@ func (c *Module) isNDKStubLibrary() bool { return false } -func (c *Module) isVndkSp() bool { +func (c *Module) IsVndkSp() bool { if vndkdep := c.vndkdep; vndkdep != nil { return vndkdep.isVndkSp() } @@ -1204,7 +1214,7 @@ func (c *Module) SubName() string { } func (c *Module) MustUseVendorVariant() bool { - return c.isVndkSp() || c.Properties.MustUseVendorVariant + return c.IsVndkSp() || c.Properties.MustUseVendorVariant } func (c *Module) getVndkExtendsModuleName() string { @@ -1343,11 +1353,11 @@ func (ctx *moduleContextImpl) header() bool { } func (ctx *moduleContextImpl) binary() bool { - return ctx.mod.binary() + return ctx.mod.Binary() } func (ctx *moduleContextImpl) object() bool { - return ctx.mod.object() + return ctx.mod.Object() } func (ctx *moduleContextImpl) canUseSdk() bool { @@ -1445,7 +1455,7 @@ func (ctx *moduleContextImpl) isNDKStubLibrary() bool { } func (ctx *moduleContextImpl) isVndkSp() bool { - return ctx.mod.isVndkSp() + return ctx.mod.IsVndkSp() } func (ctx *moduleContextImpl) IsVndkExt() bool { @@ -1786,7 +1796,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or // RECOVERY_SNAPSHOT_VERSION is current. if i, ok := c.linker.(snapshotLibraryInterface); ok { - if shouldCollectHeadersForSnapshot(ctx, c, apexInfo) { + if ShouldCollectHeadersForSnapshot(ctx, c, apexInfo) { i.collectHeadersForSnapshot(ctx) } } @@ -1799,7 +1809,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { // modules can be hidden from make as some are needed for resolving make side // dependencies. c.HideFromMake() - } else if !c.installable(apexInfo) { + } else if !installable(c, apexInfo) { c.SkipInstall() } @@ -2451,7 +2461,7 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) { return true } - if to.isVndkSp() || to.IsLlndk() { + if to.IsVndkSp() || to.IsLlndk() { return false } @@ -3064,7 +3074,7 @@ func (c *Module) Header() bool { return false } -func (c *Module) binary() bool { +func (c *Module) Binary() bool { if b, ok := c.linker.(interface { binary() bool }); ok { @@ -3073,7 +3083,7 @@ func (c *Module) binary() bool { return false } -func (c *Module) object() bool { +func (c *Module) Object() bool { if o, ok := c.linker.(interface { object() bool }); ok { @@ -3155,18 +3165,25 @@ func (c *Module) UniqueApexVariations() bool { } } -// Return true if the module is ever installable. func (c *Module) EverInstallable() bool { return c.installer != nil && // Check to see whether the module is actually ever installable. c.installer.everInstallable() } -func (c *Module) installable(apexInfo android.ApexInfo) bool { +func (c *Module) PreventInstall() bool { + return c.Properties.PreventInstall +} + +func (c *Module) Installable() *bool { + return c.Properties.Installable +} + +func installable(c LinkableInterface, apexInfo android.ApexInfo) bool { ret := c.EverInstallable() && // Check to see whether the module has been configured to not be installed. - proptools.BoolDefault(c.Properties.Installable, true) && - !c.Properties.PreventInstall && c.outputFile.Valid() + proptools.BoolDefault(c.Installable(), true) && + !c.PreventInstall() && c.OutputFile().Valid() // The platform variant doesn't need further condition. Apex variants however might not // be installable because it will likely to be included in the APEX and won't appear diff --git a/cc/cc_test.go b/cc/cc_test.go index e9daf33fc..d82619a04 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -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. diff --git a/cc/coverage.go b/cc/coverage.go index 5b5ccf2f0..b2788ecc6 100644 --- a/cc/coverage.go +++ b/cc/coverage.go @@ -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) diff --git a/cc/linkable.go b/cc/linkable.go index 40a9d8b04..b583b69e7 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -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 ( diff --git a/cc/sabi.go b/cc/sabi.go index c0eb57cc3..384dcc165 100644 --- a/cc/sabi.go +++ b/cc/sabi.go @@ -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 { diff --git a/cc/sanitize.go b/cc/sanitize.go index 397121ef5..605a8d094 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -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) || diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index 885a0ce6d..0b1147ef2 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -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() } diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go index c32fa364f..8eb616448 100644 --- a/cc/snapshot_utils.go +++ b/cc/snapshot_utils.go @@ -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() } diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index 9ad51ad77..4e59a95f8 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -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 { diff --git a/cc/vndk.go b/cc/vndk.go index 8b3788bbb..0254edc66 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -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()...) } }) diff --git a/java/app.go b/java/app.go index 5695022f9..fc1ace07b 100755 --- a/java/app.go +++ b/java/app.go @@ -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 } diff --git a/rust/Android.bp b/rust/Android.bp index f45404ff2..b611672d4 100644 --- a/rust/Android.bp +++ b/rust/Android.bp @@ -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", ], diff --git a/rust/compiler.go b/rust/compiler.go index a3f02c0d4..1598ebf9a 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -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 != "" { diff --git a/rust/proc_macro.go b/rust/proc_macro.go index 4eead3267..c217959cd 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -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 +} diff --git a/rust/rust.go b/rust/rust.go index bb971420e..f068b3d7b 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -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()) diff --git a/rust/sanitize.go b/rust/sanitize.go index 0a53f989f..3d14d512f 100644 --- a/rust/sanitize.go +++ b/rust/sanitize.go @@ -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 { diff --git a/rust/snapshot_utils.go b/rust/snapshot_utils.go new file mode 100644 index 000000000..e0ed1f711 --- /dev/null +++ b/rust/snapshot_utils.go @@ -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{} +}