Merge "cc: Create a common image mutator interface" am: e8dfbdfb59

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

Change-Id: I685bf242e928ee922737dac799bb476d00bcdfb7
This commit is contained in:
Ivan Lozano
2021-04-14 19:12:26 +00:00
committed by Automerger Merge Worker
7 changed files with 252 additions and 72 deletions

View File

@@ -1113,16 +1113,33 @@ func (c *Module) IsNdk(config android.Config) bool {
return inList(c.BaseModuleName(), *getNDKKnownLibs(config)) return inList(c.BaseModuleName(), *getNDKKnownLibs(config))
} }
// isLLndk returns true for both LLNDK (public) and LLNDK-private libs.
func (c *Module) IsLlndk() bool { func (c *Module) IsLlndk() bool {
return c.VendorProperties.IsLLNDK return c.VendorProperties.IsLLNDK
} }
// IsLlndkPublic returns true only for LLNDK (public) libs.
func (c *Module) IsLlndkPublic() bool { func (c *Module) IsLlndkPublic() bool {
return c.VendorProperties.IsLLNDK && !c.VendorProperties.IsVNDKPrivate 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 // 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 {
@@ -1246,7 +1263,7 @@ func (c *Module) nativeCoverage() bool {
return c.linker != nil && c.linker.nativeCoverage() return c.linker != nil && c.linker.nativeCoverage()
} }
func (c *Module) isSnapshotPrebuilt() bool { func (c *Module) IsSnapshotPrebuilt() bool {
if p, ok := c.linker.(snapshotInterface); ok { if p, ok := c.linker.(snapshotInterface); ok {
return p.isSnapshotPrebuilt() return p.isSnapshotPrebuilt()
} }

View File

@@ -199,40 +199,73 @@ func (c *Module) compareVendorAndProductProps() bool {
return true 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) { 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() vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
productSpecific := mctx.ProductSpecific() 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 := m.vndkdep; vndkdep != nil {
if vndkdep.isVndk() { if vndkdep.isVndk() {
if vendorSpecific || productSpecific { if vendorSpecific || productSpecific {
@@ -277,6 +310,111 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
} }
} }
} }
}
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 coreVariantNeeded bool = false
var ramdiskVariantNeeded bool = false var ramdiskVariantNeeded bool = false
@@ -299,18 +437,13 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
productVndkVersion = platformVndkVersion productVndkVersion = platformVndkVersion
} }
_, isLLNDKLibrary := m.linker.(*llndkStubDecorator) if m.IsLlndkLibrary() || m.IsLlndkHeaders() || m.HasLlndkStubs() {
_, isLLNDKHeaders := m.linker.(*llndkHeadersDecorator)
lib := moduleLibraryInterface(m)
hasLLNDKStubs := lib != nil && lib.hasLLNDKStubs()
if isLLNDKLibrary || isLLNDKHeaders || hasLLNDKStubs {
// This is an LLNDK library. The implementation of the library will be on /system, // 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. // and vendor and product variants will be created with LLNDK stubs.
// The LLNDK libraries need vendor variants even if there is no VNDK. // 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 // The obsolete llndk_library and llndk_headers modules also need the vendor variants
// so the cc_library LLNDK stubs can depend on them. // so the cc_library LLNDK stubs can depend on them.
if hasLLNDKStubs { if m.HasLlndkStubs() {
coreVariantNeeded = true coreVariantNeeded = true
} }
if platformVndkVersion != "" { if platformVndkVersion != "" {
@@ -327,17 +460,13 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
// If the device isn't compiling against the VNDK, we always // If the device isn't compiling against the VNDK, we always
// use the core mode. // use the core mode.
coreVariantNeeded = true coreVariantNeeded = true
} else if m.isSnapshotPrebuilt() { } else if m.IsSnapshotPrebuilt() {
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS. // PRODUCT_EXTRA_VNDK_VERSIONS.
if snapshot, ok := m.linker.(snapshotInterface); ok { if m.InstallInRecovery() {
if m.InstallInRecovery() { recoveryVariantNeeded = true
recoveryVariantNeeded = true
} else {
vendorVariants = append(vendorVariants, snapshot.version())
}
} else { } else {
mctx.ModuleErrorf("version is unknown for snapshot prebuilt") vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
} }
} else if m.HasNonSystemVariants() && !m.IsVndkExt() { } else if m.HasNonSystemVariants() && !m.IsVndkExt() {
// This will be available to /system unless it is product_specific // This will be available to /system unless it is product_specific
@@ -363,7 +492,7 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
productVariants = append(productVariants, productVndkVersion) 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 // This will be available in /vendor (or /odm) only
// kernel_headers is a special module type whose exported headers // kernel_headers is a special module type whose exported headers
@@ -372,7 +501,7 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
// For other modules, we assume that modules under proprietary // For other modules, we assume that modules under proprietary
// paths are compatible for BOARD_VNDK_VERSION. The other modules // paths are compatible for BOARD_VNDK_VERSION. The other modules
// are regarded as AOSP, which is PLATFORM_VNDK_VERSION. // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
if _, ok := m.linker.(*kernelHeadersDecorator); ok { if m.KernelHeadersDecorator() {
vendorVariants = append(vendorVariants, vendorVariants = append(vendorVariants,
platformVndkVersion, platformVndkVersion,
boardVndkVersion, boardVndkVersion,
@@ -390,7 +519,7 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
} }
if boardVndkVersion != "" && productVndkVersion != "" { 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. // The module has "product_specific: true" that does not create core variant.
coreVariantNeeded = false coreVariantNeeded = false
productVariants = append(productVariants, productVndkVersion) productVariants = append(productVariants, productVndkVersion)
@@ -402,60 +531,60 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
productVariants = []string{} productVariants = []string{}
} }
if Bool(m.Properties.Ramdisk_available) { if m.RamdiskAvailable() {
ramdiskVariantNeeded = true ramdiskVariantNeeded = true
} }
if m.ModuleBase.InstallInRamdisk() { if m.AndroidModuleBase().InstallInRamdisk() {
ramdiskVariantNeeded = true ramdiskVariantNeeded = true
coreVariantNeeded = false coreVariantNeeded = false
} }
if Bool(m.Properties.Vendor_ramdisk_available) { if m.VendorRamdiskAvailable() {
vendorRamdiskVariantNeeded = true vendorRamdiskVariantNeeded = true
} }
if m.ModuleBase.InstallInVendorRamdisk() { if m.AndroidModuleBase().InstallInVendorRamdisk() {
vendorRamdiskVariantNeeded = true vendorRamdiskVariantNeeded = true
coreVariantNeeded = false coreVariantNeeded = false
} }
if Bool(m.Properties.Recovery_available) { if m.RecoveryAvailable() {
recoveryVariantNeeded = true recoveryVariantNeeded = true
} }
if m.ModuleBase.InstallInRecovery() { if m.AndroidModuleBase().InstallInRecovery() {
recoveryVariantNeeded = true recoveryVariantNeeded = true
coreVariantNeeded = false coreVariantNeeded = false
} }
// If using a snapshot, the recovery variant under AOSP directories is not needed, // If using a snapshot, the recovery variant under AOSP directories is not needed,
// except for kernel headers, which needs all variants. // except for kernel headers, which needs all variants.
if _, ok := m.linker.(*kernelHeadersDecorator); !ok && if m.KernelHeadersDecorator() &&
!m.isSnapshotPrebuilt() && !m.IsSnapshotPrebuilt() &&
usingRecoverySnapshot && usingRecoverySnapshot &&
!isRecoveryProprietaryModule(mctx) { !isRecoveryProprietaryModule(mctx) {
recoveryVariantNeeded = false recoveryVariantNeeded = false
} }
for _, variant := range android.FirstUniqueStrings(vendorVariants) { 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) { for _, variant := range android.FirstUniqueStrings(productVariants) {
m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant) m.AppendExtraVariant(ProductVariationPrefix + variant)
} }
m.Properties.RamdiskVariantNeeded = ramdiskVariantNeeded m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
m.Properties.VendorRamdiskVariantNeeded = vendorRamdiskVariantNeeded m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
m.Properties.CoreVariantNeeded = coreVariantNeeded m.SetCoreVariantNeeded(coreVariantNeeded)
// Disable the module if no variants are needed. // Disable the module if no variants are needed.
if !ramdiskVariantNeeded && if !ramdiskVariantNeeded &&
!recoveryVariantNeeded && !recoveryVariantNeeded &&
!coreVariantNeeded && !coreVariantNeeded &&
len(m.Properties.ExtraVariants) == 0 { len(m.ExtraVariants()) == 0 {
m.Disable() m.Disable()
} }
} }

View File

@@ -98,10 +98,24 @@ type LinkableInterface interface {
InVendor() bool InVendor() bool
UseSdk() 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 UseVndk() bool
MustUseVendorVariant() bool MustUseVendorVariant() bool
IsLlndk() bool
IsLlndkPublic() bool
IsVndk() bool IsVndk() bool
IsVndkExt() bool IsVndkExt() bool
IsVndkPrivate() bool IsVndkPrivate() bool
@@ -121,6 +135,10 @@ type LinkableInterface interface {
SetPreventInstall() SetPreventInstall()
// SetHideFromMake sets the HideFromMake property to 'true' for this module. // SetHideFromMake sets the HideFromMake property to 'true' for this module.
SetHideFromMake() 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 ( var (

View File

@@ -141,7 +141,7 @@ func shouldCreateSourceAbiDumpForLibrary(ctx android.BaseModuleContext) bool {
} }
// Don't create ABI dump for prebuilts. // Don't create ABI dump for prebuilts.
if m.Prebuilt() != nil || m.isSnapshotPrebuilt() { if m.Prebuilt() != nil || m.IsSnapshotPrebuilt() {
return false return false
} }

View File

@@ -173,7 +173,7 @@ func isSnapshotAware(cfg android.DeviceConfig, m *Module, inProprietaryPath bool
return false return false
} }
// the module must be installed in target image // 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 return false
} }
// skip kernel_headers which always depend on vendor // skip kernel_headers which always depend on vendor

View File

@@ -609,8 +609,8 @@ func isVndkSnapshotAware(config android.DeviceConfig, m *Module,
} }
// !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.
// isSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense. // IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
if !m.InVendor() || !m.installable(apexInfo) || m.isSnapshotPrebuilt() { if !m.InVendor() || !m.installable(apexInfo) || m.IsSnapshotPrebuilt() {
return nil, "", false return nil, "", false
} }
l, ok := m.linker.(snapshotLibraryInterface) l, ok := m.linker.(snapshotLibraryInterface)

View File

@@ -255,6 +255,22 @@ func (c *Module) IsLlndkPublic() bool {
return false 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 { func (mod *Module) SdkVersion() string {
return "" return ""
} }