Support recovery and recovery_available
`recovery: true` installs a module to the recovery partition.
`recovery_available: true` makes a module to be available to other
`recovery:true` or `recovery_available: true` modules.
These to are very similar to vendor, vendor_available properties, except
for the target partition.
Bug: 67916654
Bug: 64960723
Test: m -j, toybox_recovery is installed to the recovery/root/sbin
Change-Id: Iaebe0593de16c69fa70de251a61f4d018a251509
diff --git a/cc/cc.go b/cc/cc.go
index 9c3de09..a885c91 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -34,7 +34,7 @@
android.RegisterModuleType("cc_defaults", defaultsFactory)
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("image", vendorMutator).Parallel()
+ ctx.BottomUp("image", imageMutator).Parallel()
ctx.BottomUp("link", linkageMutator).Parallel()
ctx.BottomUp("vndk", vndkMutator).Parallel()
ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
@@ -175,6 +175,11 @@
// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
// file
Logtags []string
+
+ // Make this module available when building for recovery
+ Recovery_available *bool
+
+ InRecovery bool `blueprint:"mutated"`
}
type VendorProperties struct {
@@ -217,6 +222,7 @@
isVndk() bool
isVndkSp() bool
isVndkExt() bool
+ inRecovery() bool
createVndkSourceAbiDump() bool
selectedStl() string
baseModuleName() string
@@ -453,6 +459,14 @@
return c.isVndk() || Bool(c.VendorProperties.Vendor_available)
}
+func (c *Module) inRecovery() bool {
+ return c.Properties.InRecovery || c.ModuleBase.InstallInRecovery()
+}
+
+func (c *Module) onlyInRecovery() bool {
+ return c.ModuleBase.InstallInRecovery()
+}
+
type baseModuleContext struct {
android.BaseContext
moduleContextImpl
@@ -500,7 +514,7 @@
}
func (ctx *moduleContextImpl) useSdk() bool {
- if ctx.ctx.Device() && !ctx.useVndk() {
+ if ctx.ctx.Device() && !ctx.useVndk() && !ctx.inRecovery() {
return String(ctx.mod.Properties.Sdk_version) != ""
}
return false
@@ -544,6 +558,10 @@
return ctx.mod.isVndkExt()
}
+func (ctx *moduleContextImpl) inRecovery() bool {
+ return ctx.mod.inRecovery()
+}
+
// Create source abi dumps if the module belongs to the list of VndkLibraries.
func (ctx *moduleContextImpl) createVndkSourceAbiDump() bool {
skipAbiChecks := ctx.ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS")
@@ -1069,6 +1087,10 @@
// Platform code can link to anything
return
}
+ if from.inRecovery() {
+ // Recovery code is not NDK
+ return
+ }
if _, ok := to.linker.(*toolchainLibraryDecorator); ok {
// These are always allowed
return
@@ -1360,6 +1382,8 @@
return libName + vendorSuffix
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
return libName + vendorPublicLibrarySuffix
+ } else if ccDep.inRecovery() && !ccDep.onlyInRecovery() {
+ return libName + recoverySuffix
} else {
return libName
}
@@ -1411,6 +1435,10 @@
return c.installer.inSanitizerDir()
}
+func (c *Module) InstallInRecovery() bool {
+ return c.inRecovery()
+}
+
func (c *Module) HostToolPath() android.OptionalPath {
if c.installer == nil {
return android.OptionalPath{}
@@ -1496,6 +1524,8 @@
// vendorMode is the variant used for /vendor code that compiles
// against the VNDK.
vendorMode = "vendor"
+
+ recoveryMode = "recovery"
)
func squashVendorSrcs(m *Module) {
@@ -1508,7 +1538,17 @@
}
}
-func vendorMutator(mctx android.BottomUpMutatorContext) {
+func squashRecoverySrcs(m *Module) {
+ if lib, ok := m.compiler.(*libraryDecorator); ok {
+ lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
+ lib.baseCompiler.Properties.Target.Recovery.Srcs...)
+
+ lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
+ lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
+ }
+}
+
+func imageMutator(mctx android.BottomUpMutatorContext) {
if mctx.Os() != android.Android {
return
}
@@ -1577,43 +1617,70 @@
}
}
+ var coreVariantNeeded bool = false
+ var vendorVariantNeeded bool = false
+ var recoveryVariantNeeded bool = false
+
if mctx.DeviceConfig().VndkVersion() == "" {
// If the device isn't compiling against the VNDK, we always
// use the core mode.
- mctx.CreateVariations(coreMode)
+ coreVariantNeeded = true
} else if _, ok := m.linker.(*llndkStubDecorator); ok {
// LL-NDK stubs only exist in the vendor variant, since the
// real libraries will be used in the core variant.
- mctx.CreateVariations(vendorMode)
+ vendorVariantNeeded = true
} else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
// ... and LL-NDK headers as well
- mod := mctx.CreateVariations(vendorMode)
- vendor := mod[0].(*Module)
- vendor.Properties.UseVndk = true
+ vendorVariantNeeded = true
} else if _, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS.
- mod := mctx.CreateVariations(vendorMode)
- vendor := mod[0].(*Module)
- vendor.Properties.UseVndk = true
+ vendorVariantNeeded = true
} else if m.hasVendorVariant() && !vendorSpecific {
// This will be available in both /system and /vendor
// or a /system directory that is available to vendor.
- mod := mctx.CreateVariations(coreMode, vendorMode)
- vendor := mod[1].(*Module)
- vendor.Properties.UseVndk = true
- squashVendorSrcs(vendor)
+ coreVariantNeeded = true
+ vendorVariantNeeded = true
} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
// This will be available in /vendor (or /odm) only
- mod := mctx.CreateVariations(vendorMode)
- vendor := mod[0].(*Module)
- vendor.Properties.UseVndk = true
- squashVendorSrcs(vendor)
+ vendorVariantNeeded = true
} else {
// This is either in /system (or similar: /data), or is a
// modules built with the NDK. Modules built with the NDK
// will be restricted using the existing link type checks.
- mctx.CreateVariations(coreMode)
+ coreVariantNeeded = true
+ }
+
+ if Bool(m.Properties.Recovery_available) {
+ recoveryVariantNeeded = true
+ }
+
+ if m.ModuleBase.InstallInRecovery() {
+ recoveryVariantNeeded = true
+ coreVariantNeeded = false
+ }
+
+ var variants []string
+ if coreVariantNeeded {
+ variants = append(variants, coreMode)
+ }
+ if vendorVariantNeeded {
+ variants = append(variants, vendorMode)
+ }
+ if recoveryVariantNeeded {
+ variants = append(variants, recoveryMode)
+ }
+ mod := mctx.CreateVariations(variants...)
+ for i, v := range variants {
+ if v == vendorMode {
+ m := mod[i].(*Module)
+ m.Properties.UseVndk = true
+ squashVendorSrcs(m)
+ } else if v == recoveryMode {
+ m := mod[i].(*Module)
+ m.Properties.InRecovery = true
+ squashRecoverySrcs(m)
+ }
}
}