cc: Create a common image mutator interface
As part of adding Vendor support to Rust, refactor the image mutator in
CC to a new common image mutator interface so this logic can be reused
across both CC and Rust.
Bug: 184042776
Test: m nothing
Change-Id: Ia55d5ad840db7cf1a64d6c65ed86487230cb8742
diff --git a/cc/cc.go b/cc/cc.go
index 9176bc3..4413df0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1113,16 +1113,33 @@
return inList(c.BaseModuleName(), *getNDKKnownLibs(config))
}
-// isLLndk returns true for both LLNDK (public) and LLNDK-private libs.
func (c *Module) IsLlndk() bool {
return c.VendorProperties.IsLLNDK
}
-// IsLlndkPublic returns true only for LLNDK (public) libs.
func (c *Module) IsLlndkPublic() bool {
return c.VendorProperties.IsLLNDK && !c.VendorProperties.IsVNDKPrivate
}
+func (c *Module) IsLlndkHeaders() bool {
+ if _, ok := c.linker.(*llndkHeadersDecorator); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) IsLlndkLibrary() bool {
+ if _, ok := c.linker.(*llndkStubDecorator); ok {
+ return true
+ }
+ return false
+}
+
+func (m *Module) HasLlndkStubs() bool {
+ lib := moduleLibraryInterface(m)
+ return lib != nil && lib.hasLLNDKStubs()
+}
+
// 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 {
@@ -1246,7 +1263,7 @@
return c.linker != nil && c.linker.nativeCoverage()
}
-func (c *Module) isSnapshotPrebuilt() bool {
+func (c *Module) IsSnapshotPrebuilt() bool {
if p, ok := c.linker.(snapshotInterface); ok {
return p.isSnapshotPrebuilt()
}
diff --git a/cc/image.go b/cc/image.go
index afe6a0e..cb8589d 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -187,40 +187,73 @@
return true
}
+// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules.
+type ImageMutatableModule interface {
+ android.Module
+ LinkableInterface
+
+ // AndroidModuleBase returns the android.ModuleBase for this module
+ AndroidModuleBase() *android.ModuleBase
+
+ // VendorAvailable returns true if this module is available on the vendor image.
+ VendorAvailable() bool
+
+ // OdmAvailable returns true if this module is available on the odm image.
+ OdmAvailable() bool
+
+ // ProductAvailable returns true if this module is available on the product image.
+ ProductAvailable() bool
+
+ // RamdiskAvailable returns true if this module is available on the ramdisk image.
+ RamdiskAvailable() bool
+
+ // RecoveryAvailable returns true if this module is available on the recovery image.
+ RecoveryAvailable() bool
+
+ // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
+ VendorRamdiskAvailable() bool
+
+ // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
+ IsSnapshotPrebuilt() bool
+
+ // SnapshotVersion returns the snapshot version for this module.
+ SnapshotVersion(mctx android.BaseModuleContext) string
+
+ // SdkVersion returns the SDK version for this module.
+ SdkVersion() string
+
+ // ExtraVariants returns the list of extra variants this module requires.
+ ExtraVariants() []string
+
+ // AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
+ AppendExtraVariant(extraVariant string)
+
+ // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
+ SetRamdiskVariantNeeded(b bool)
+
+ // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
+ SetVendorRamdiskVariantNeeded(b bool)
+
+ // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
+ SetRecoveryVariantNeeded(b bool)
+
+ // SetCoreVariantNeeded sets whether the Core Variant is needed.
+ SetCoreVariantNeeded(b bool)
+}
+
+var _ ImageMutatableModule = (*Module)(nil)
+
func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
- // Validation check
+ m.CheckVndkProperties(mctx)
+ MutateImage(mctx, m)
+}
+
+// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
+// If properties are not set correctly, results in a module context property error.
+func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
productSpecific := mctx.ProductSpecific()
- if Bool(m.VendorProperties.Vendor_available) {
- if vendorSpecific {
- mctx.PropertyErrorf("vendor_available",
- "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
- }
- if Bool(m.VendorProperties.Odm_available) {
- mctx.PropertyErrorf("vendor_available",
- "doesn't make sense at the same time as `odm_available: true`")
- }
- }
-
- if Bool(m.VendorProperties.Odm_available) {
- if vendorSpecific {
- mctx.PropertyErrorf("odm_available",
- "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
- }
- }
-
- if Bool(m.VendorProperties.Product_available) {
- if productSpecific {
- mctx.PropertyErrorf("product_available",
- "doesn't make sense at the same time as `product_specific: true`")
- }
- if vendorSpecific {
- mctx.PropertyErrorf("product_available",
- "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
- }
- }
-
if vndkdep := m.vndkdep; vndkdep != nil {
if vndkdep.isVndk() {
if vendorSpecific || productSpecific {
@@ -265,6 +298,111 @@
}
}
}
+}
+
+func (m *Module) VendorAvailable() bool {
+ return Bool(m.VendorProperties.Vendor_available)
+}
+
+func (m *Module) OdmAvailable() bool {
+ return Bool(m.VendorProperties.Odm_available)
+}
+
+func (m *Module) ProductAvailable() bool {
+ return Bool(m.VendorProperties.Product_available)
+}
+
+func (m *Module) RamdiskAvailable() bool {
+ return Bool(m.Properties.Ramdisk_available)
+}
+
+func (m *Module) VendorRamdiskAvailable() bool {
+ return Bool(m.Properties.Vendor_ramdisk_available)
+}
+
+func (m *Module) AndroidModuleBase() *android.ModuleBase {
+ return &m.ModuleBase
+}
+
+func (m *Module) RecoveryAvailable() bool {
+ return Bool(m.Properties.Recovery_available)
+}
+
+func (m *Module) ExtraVariants() []string {
+ return m.Properties.ExtraVariants
+}
+
+func (m *Module) AppendExtraVariant(extraVariant string) {
+ m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, extraVariant)
+}
+
+func (m *Module) SetRamdiskVariantNeeded(b bool) {
+ m.Properties.RamdiskVariantNeeded = b
+}
+
+func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
+ m.Properties.VendorRamdiskVariantNeeded = b
+}
+
+func (m *Module) SetRecoveryVariantNeeded(b bool) {
+ m.Properties.RecoveryVariantNeeded = b
+}
+
+func (m *Module) SetCoreVariantNeeded(b bool) {
+ m.Properties.CoreVariantNeeded = b
+}
+
+func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
+ if snapshot, ok := m.linker.(snapshotInterface); ok {
+ return snapshot.version()
+ } else {
+ mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
+ // Should we be panicking here instead?
+ return ""
+ }
+}
+
+func (m *Module) KernelHeadersDecorator() bool {
+ if _, ok := m.linker.(*kernelHeadersDecorator); ok {
+ return true
+ }
+ return false
+}
+
+// MutateImage handles common image mutations for ImageMutatableModule interfaces.
+func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
+ // Validation check
+ vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
+ productSpecific := mctx.ProductSpecific()
+
+ if m.VendorAvailable() {
+ if vendorSpecific {
+ mctx.PropertyErrorf("vendor_available",
+ "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
+ }
+ if m.OdmAvailable() {
+ mctx.PropertyErrorf("vendor_available",
+ "doesn't make sense at the same time as `odm_available: true`")
+ }
+ }
+
+ if m.OdmAvailable() {
+ if vendorSpecific {
+ mctx.PropertyErrorf("odm_available",
+ "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
+ }
+ }
+
+ if m.ProductAvailable() {
+ if productSpecific {
+ mctx.PropertyErrorf("product_available",
+ "doesn't make sense at the same time as `product_specific: true`")
+ }
+ if vendorSpecific {
+ mctx.PropertyErrorf("product_available",
+ "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
+ }
+ }
var coreVariantNeeded bool = false
var ramdiskVariantNeeded bool = false
@@ -287,18 +425,13 @@
productVndkVersion = platformVndkVersion
}
- _, isLLNDKLibrary := m.linker.(*llndkStubDecorator)
- _, isLLNDKHeaders := m.linker.(*llndkHeadersDecorator)
- lib := moduleLibraryInterface(m)
- hasLLNDKStubs := lib != nil && lib.hasLLNDKStubs()
-
- if isLLNDKLibrary || isLLNDKHeaders || hasLLNDKStubs {
+ if m.IsLlndkLibrary() || m.IsLlndkHeaders() || m.HasLlndkStubs() {
// This is an LLNDK library. The implementation of the library will be on /system,
// and vendor and product variants will be created with LLNDK stubs.
// The LLNDK libraries need vendor variants even if there is no VNDK.
// The obsolete llndk_library and llndk_headers modules also need the vendor variants
// so the cc_library LLNDK stubs can depend on them.
- if hasLLNDKStubs {
+ if m.HasLlndkStubs() {
coreVariantNeeded = true
}
if platformVndkVersion != "" {
@@ -315,17 +448,13 @@
// If the device isn't compiling against the VNDK, we always
// use the core mode.
coreVariantNeeded = true
- } else if m.isSnapshotPrebuilt() {
+ } else if m.IsSnapshotPrebuilt() {
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS.
- if snapshot, ok := m.linker.(snapshotInterface); ok {
- if m.InstallInRecovery() {
- recoveryVariantNeeded = true
- } else {
- vendorVariants = append(vendorVariants, snapshot.version())
- }
+ if m.InstallInRecovery() {
+ recoveryVariantNeeded = true
} else {
- mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
+ vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
}
} else if m.HasNonSystemVariants() && !m.IsVndkExt() {
// This will be available to /system unless it is product_specific
@@ -351,7 +480,7 @@
productVariants = append(productVariants, productVndkVersion)
}
}
- } else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
+ } else if vendorSpecific && m.SdkVersion() == "" {
// This will be available in /vendor (or /odm) only
// kernel_headers is a special module type whose exported headers
@@ -360,7 +489,7 @@
// For other modules, we assume that modules under proprietary
// paths are compatible for BOARD_VNDK_VERSION. The other modules
// are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
- if _, ok := m.linker.(*kernelHeadersDecorator); ok {
+ if m.KernelHeadersDecorator() {
vendorVariants = append(vendorVariants,
platformVndkVersion,
boardVndkVersion,
@@ -378,7 +507,7 @@
}
if boardVndkVersion != "" && productVndkVersion != "" {
- if coreVariantNeeded && productSpecific && String(m.Properties.Sdk_version) == "" {
+ if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
// The module has "product_specific: true" that does not create core variant.
coreVariantNeeded = false
productVariants = append(productVariants, productVndkVersion)
@@ -390,60 +519,60 @@
productVariants = []string{}
}
- if Bool(m.Properties.Ramdisk_available) {
+ if m.RamdiskAvailable() {
ramdiskVariantNeeded = true
}
- if m.ModuleBase.InstallInRamdisk() {
+ if m.AndroidModuleBase().InstallInRamdisk() {
ramdiskVariantNeeded = true
coreVariantNeeded = false
}
- if Bool(m.Properties.Vendor_ramdisk_available) {
+ if m.VendorRamdiskAvailable() {
vendorRamdiskVariantNeeded = true
}
- if m.ModuleBase.InstallInVendorRamdisk() {
+ if m.AndroidModuleBase().InstallInVendorRamdisk() {
vendorRamdiskVariantNeeded = true
coreVariantNeeded = false
}
- if Bool(m.Properties.Recovery_available) {
+ if m.RecoveryAvailable() {
recoveryVariantNeeded = true
}
- if m.ModuleBase.InstallInRecovery() {
+ if m.AndroidModuleBase().InstallInRecovery() {
recoveryVariantNeeded = true
coreVariantNeeded = false
}
// If using a snapshot, the recovery variant under AOSP directories is not needed,
// except for kernel headers, which needs all variants.
- if _, ok := m.linker.(*kernelHeadersDecorator); !ok &&
- !m.isSnapshotPrebuilt() &&
+ if m.KernelHeadersDecorator() &&
+ !m.IsSnapshotPrebuilt() &&
usingRecoverySnapshot &&
!isRecoveryProprietaryModule(mctx) {
recoveryVariantNeeded = false
}
for _, variant := range android.FirstUniqueStrings(vendorVariants) {
- m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, VendorVariationPrefix+variant)
+ m.AppendExtraVariant(VendorVariationPrefix + variant)
}
for _, variant := range android.FirstUniqueStrings(productVariants) {
- m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant)
+ m.AppendExtraVariant(ProductVariationPrefix + variant)
}
- m.Properties.RamdiskVariantNeeded = ramdiskVariantNeeded
- m.Properties.VendorRamdiskVariantNeeded = vendorRamdiskVariantNeeded
- m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded
- m.Properties.CoreVariantNeeded = coreVariantNeeded
+ m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
+ m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
+ m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
+ m.SetCoreVariantNeeded(coreVariantNeeded)
// Disable the module if no variants are needed.
if !ramdiskVariantNeeded &&
!recoveryVariantNeeded &&
!coreVariantNeeded &&
- len(m.Properties.ExtraVariants) == 0 {
+ len(m.ExtraVariants()) == 0 {
m.Disable()
}
}
diff --git a/cc/linkable.go b/cc/linkable.go
index 6aa238b..17bafcc 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -98,10 +98,24 @@
InVendor() bool
UseSdk() bool
+
+ // IsLlndk returns true for both LLNDK (public) and LLNDK-private libs.
+ IsLlndk() bool
+
+ // IsLlndkPublic returns true only for LLNDK (public) libs.
+ IsLlndkPublic() bool
+
+ // IsLlndkHeaders returns true if this module is an LLNDK headers module.
+ IsLlndkHeaders() bool
+
+ // IsLlndkLibrary returns true if this module is an LLNDK library module.
+ IsLlndkLibrary() bool
+
+ // HasLlndkStubs returns true if this module has LLNDK stubs.
+ HasLlndkStubs() bool
+
UseVndk() bool
MustUseVendorVariant() bool
- IsLlndk() bool
- IsLlndkPublic() bool
IsVndk() bool
IsVndkExt() bool
IsVndkPrivate() bool
@@ -121,6 +135,10 @@
SetPreventInstall()
// SetHideFromMake sets the HideFromMake property to 'true' for this module.
SetHideFromMake()
+
+ // 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
}
var (
diff --git a/cc/sabi.go b/cc/sabi.go
index 4a1ba3c..c0eb57c 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -141,7 +141,7 @@
}
// Don't create ABI dump for prebuilts.
- if m.Prebuilt() != nil || m.isSnapshotPrebuilt() {
+ if m.Prebuilt() != nil || m.IsSnapshotPrebuilt() {
return false
}
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 3437d77..2f68cca 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -173,7 +173,7 @@
return false
}
// the module must be installed in target image
- if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !image.inImage(m)() {
+ if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.inImage(m)() {
return false
}
// skip kernel_headers which always depend on vendor
diff --git a/cc/vndk.go b/cc/vndk.go
index b7047e9..1a8a454 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -609,8 +609,8 @@
}
// !inVendor: There's product/vendor variants for VNDK libs. We only care about vendor variants.
// !installable: Snapshot only cares about "installable" modules.
- // isSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
- if !m.InVendor() || !m.installable(apexInfo) || m.isSnapshotPrebuilt() {
+ // IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
+ if !m.InVendor() || !m.installable(apexInfo) || m.IsSnapshotPrebuilt() {
return nil, "", false
}
l, ok := m.linker.(snapshotLibraryInterface)
diff --git a/rust/rust.go b/rust/rust.go
index 34e197a..f0da2ce 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -255,6 +255,22 @@
return false
}
+func (m *Module) IsLlndkHeaders() bool {
+ return false
+}
+
+func (m *Module) IsLlndkLibrary() bool {
+ return false
+}
+
+func (mod *Module) KernelHeadersDecorator() bool {
+ return false
+}
+
+func (m *Module) HasLlndkStubs() bool {
+ return false
+}
+
func (mod *Module) SdkVersion() string {
return ""
}