74d255698b
Dependencies of makefile modules are being redirected according to SOONG_CFI_STATIC_LIBRARIES and SOONG_HWASAN_STATIC_LIBRARIES. But the variables are shared among all variants (e.g. core, vendor, product, arch), which can cause build error. This splits the Makefile variables into several lists, one list per each arch and each image variant, to correctly make the redirection. Bug: 162476652 Test: build and inspect ninja Change-Id: Icc753382f1c53de8468cc85243a6954e1986297a
348 lines
11 KiB
Go
348 lines
11 KiB
Go
// Copyright 2020 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 cc
|
|
|
|
// This file contains image variant related things, including image mutator functions, utility
|
|
// functions to determine where a module is installed, etc.
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"android/soong/android"
|
|
)
|
|
|
|
var _ android.ImageInterface = (*Module)(nil)
|
|
|
|
type imageVariantType string
|
|
|
|
const (
|
|
coreImageVariant imageVariantType = "core"
|
|
vendorImageVariant imageVariantType = "vendor"
|
|
productImageVariant imageVariantType = "product"
|
|
ramdiskImageVariant imageVariantType = "ramdisk"
|
|
recoveryImageVariant imageVariantType = "recovery"
|
|
hostImageVariant imageVariantType = "host"
|
|
)
|
|
|
|
func (c *Module) getImageVariantType() imageVariantType {
|
|
if c.Host() {
|
|
return hostImageVariant
|
|
} else if c.inVendor() {
|
|
return vendorImageVariant
|
|
} else if c.inProduct() {
|
|
return productImageVariant
|
|
} else if c.InRamdisk() {
|
|
return ramdiskImageVariant
|
|
} else if c.InRecovery() {
|
|
return recoveryImageVariant
|
|
} else {
|
|
return coreImageVariant
|
|
}
|
|
}
|
|
|
|
const (
|
|
// VendorVariationPrefix is the variant prefix used for /vendor code that compiles
|
|
// against the VNDK.
|
|
VendorVariationPrefix = "vendor."
|
|
|
|
// ProductVariationPrefix is the variant prefix used for /product code that compiles
|
|
// against the VNDK.
|
|
ProductVariationPrefix = "product."
|
|
)
|
|
|
|
func (ctx *moduleContext) ProductSpecific() bool {
|
|
return ctx.ModuleContext.ProductSpecific() ||
|
|
(ctx.mod.HasVendorVariant() && ctx.mod.inProduct() && !ctx.mod.IsVndk())
|
|
}
|
|
|
|
func (ctx *moduleContext) SocSpecific() bool {
|
|
return ctx.ModuleContext.SocSpecific() ||
|
|
(ctx.mod.HasVendorVariant() && ctx.mod.inVendor() && !ctx.mod.IsVndk())
|
|
}
|
|
|
|
func (ctx *moduleContextImpl) inProduct() bool {
|
|
return ctx.mod.inProduct()
|
|
}
|
|
|
|
func (ctx *moduleContextImpl) inVendor() bool {
|
|
return ctx.mod.inVendor()
|
|
}
|
|
|
|
func (ctx *moduleContextImpl) inRamdisk() bool {
|
|
return ctx.mod.InRamdisk()
|
|
}
|
|
|
|
func (ctx *moduleContextImpl) inRecovery() bool {
|
|
return ctx.mod.InRecovery()
|
|
}
|
|
|
|
// Returns true only when this module is configured to have core, product and vendor
|
|
// variants.
|
|
func (c *Module) HasVendorVariant() bool {
|
|
return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
|
|
}
|
|
|
|
// Returns true if the module is "product" variant. Usually these modules are installed in /product
|
|
func (c *Module) inProduct() bool {
|
|
return c.Properties.ImageVariationPrefix == ProductVariationPrefix
|
|
}
|
|
|
|
// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
|
|
func (c *Module) inVendor() bool {
|
|
return c.Properties.ImageVariationPrefix == VendorVariationPrefix
|
|
}
|
|
|
|
func (c *Module) InRamdisk() bool {
|
|
return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
|
|
}
|
|
|
|
func (c *Module) InRecovery() bool {
|
|
return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
|
|
}
|
|
|
|
func (c *Module) OnlyInRamdisk() bool {
|
|
return c.ModuleBase.InstallInRamdisk()
|
|
}
|
|
|
|
func (c *Module) OnlyInRecovery() bool {
|
|
return c.ModuleBase.InstallInRecovery()
|
|
}
|
|
|
|
func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
|
// Validation check
|
|
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
|
|
productSpecific := mctx.ProductSpecific()
|
|
|
|
if m.VendorProperties.Vendor_available != nil && vendorSpecific {
|
|
mctx.PropertyErrorf("vendor_available",
|
|
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
|
|
}
|
|
|
|
if vndkdep := m.vndkdep; vndkdep != nil {
|
|
if vndkdep.isVndk() {
|
|
if vendorSpecific || productSpecific {
|
|
if !vndkdep.isVndkExt() {
|
|
mctx.PropertyErrorf("vndk",
|
|
"must set `extends: \"...\"` to vndk extension")
|
|
} else if m.VendorProperties.Vendor_available != nil {
|
|
mctx.PropertyErrorf("vendor_available",
|
|
"must not set at the same time as `vndk: {extends: \"...\"}`")
|
|
}
|
|
} else {
|
|
if vndkdep.isVndkExt() {
|
|
mctx.PropertyErrorf("vndk",
|
|
"must set `vendor: true` or `product_specific: true` to set `extends: %q`",
|
|
m.getVndkExtendsModuleName())
|
|
}
|
|
if m.VendorProperties.Vendor_available == nil {
|
|
mctx.PropertyErrorf("vndk",
|
|
"vendor_available must be set to either true or false when `vndk: {enabled: true}`")
|
|
}
|
|
}
|
|
} else {
|
|
if vndkdep.isVndkSp() {
|
|
mctx.PropertyErrorf("vndk",
|
|
"must set `enabled: true` to set `support_system_process: true`")
|
|
}
|
|
if vndkdep.isVndkExt() {
|
|
mctx.PropertyErrorf("vndk",
|
|
"must set `enabled: true` to set `extends: %q`",
|
|
m.getVndkExtendsModuleName())
|
|
}
|
|
}
|
|
}
|
|
|
|
var coreVariantNeeded bool = false
|
|
var ramdiskVariantNeeded bool = false
|
|
var recoveryVariantNeeded bool = false
|
|
|
|
var vendorVariants []string
|
|
var productVariants []string
|
|
|
|
platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
|
|
boardVndkVersion := mctx.DeviceConfig().VndkVersion()
|
|
productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
|
|
if boardVndkVersion == "current" {
|
|
boardVndkVersion = platformVndkVersion
|
|
}
|
|
if productVndkVersion == "current" {
|
|
productVndkVersion = platformVndkVersion
|
|
}
|
|
|
|
if boardVndkVersion == "" {
|
|
// If the device isn't compiling against the VNDK, we always
|
|
// use the core mode.
|
|
coreVariantNeeded = true
|
|
} else if _, ok := m.linker.(*llndkStubDecorator); ok {
|
|
// LL-NDK stubs only exist in the vendor and product variants,
|
|
// since the real libraries will be used in the core variant.
|
|
vendorVariants = append(vendorVariants,
|
|
platformVndkVersion,
|
|
boardVndkVersion,
|
|
)
|
|
productVariants = append(productVariants,
|
|
platformVndkVersion,
|
|
productVndkVersion,
|
|
)
|
|
} else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
|
|
// ... and LL-NDK headers as well
|
|
vendorVariants = append(vendorVariants,
|
|
platformVndkVersion,
|
|
boardVndkVersion,
|
|
)
|
|
productVariants = append(productVariants,
|
|
platformVndkVersion,
|
|
productVndkVersion,
|
|
)
|
|
} 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.(interface {
|
|
version() string
|
|
}); ok {
|
|
vendorVariants = append(vendorVariants, snapshot.version())
|
|
} else {
|
|
mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
|
|
}
|
|
} else if m.HasVendorVariant() && !m.isVndkExt() {
|
|
// This will be available in /system, /vendor and /product
|
|
// or a /system directory that is available to vendor and product.
|
|
coreVariantNeeded = true
|
|
|
|
// We assume that modules under proprietary paths are compatible for
|
|
// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
|
|
// PLATFORM_VNDK_VERSION.
|
|
if isVendorProprietaryPath(mctx.ModuleDir()) {
|
|
vendorVariants = append(vendorVariants, boardVndkVersion)
|
|
} else {
|
|
vendorVariants = append(vendorVariants, platformVndkVersion)
|
|
}
|
|
|
|
// vendor_available modules are also available to /product.
|
|
productVariants = append(productVariants, platformVndkVersion)
|
|
// VNDK is always PLATFORM_VNDK_VERSION
|
|
if !m.IsVndk() {
|
|
productVariants = append(productVariants, productVndkVersion)
|
|
}
|
|
} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
|
|
// This will be available in /vendor (or /odm) only
|
|
|
|
// kernel_headers is a special module type whose exported headers
|
|
// are coming from DeviceKernelHeaders() which is always vendor
|
|
// dependent. They'll always have both vendor variants.
|
|
// 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 {
|
|
vendorVariants = append(vendorVariants,
|
|
platformVndkVersion,
|
|
boardVndkVersion,
|
|
)
|
|
} else if isVendorProprietaryPath(mctx.ModuleDir()) {
|
|
vendorVariants = append(vendorVariants, boardVndkVersion)
|
|
} else {
|
|
vendorVariants = append(vendorVariants, platformVndkVersion)
|
|
}
|
|
} 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.
|
|
coreVariantNeeded = true
|
|
}
|
|
|
|
if boardVndkVersion != "" && productVndkVersion != "" {
|
|
if coreVariantNeeded && productSpecific && String(m.Properties.Sdk_version) == "" {
|
|
// The module has "product_specific: true" that does not create core variant.
|
|
coreVariantNeeded = false
|
|
productVariants = append(productVariants, productVndkVersion)
|
|
}
|
|
} else {
|
|
// Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
|
|
// restriction to use system libs.
|
|
// No product variants defined in this case.
|
|
productVariants = []string{}
|
|
}
|
|
|
|
if Bool(m.Properties.Ramdisk_available) {
|
|
ramdiskVariantNeeded = true
|
|
}
|
|
|
|
if m.ModuleBase.InstallInRamdisk() {
|
|
ramdiskVariantNeeded = true
|
|
coreVariantNeeded = false
|
|
}
|
|
|
|
if Bool(m.Properties.Recovery_available) {
|
|
recoveryVariantNeeded = true
|
|
}
|
|
|
|
if m.ModuleBase.InstallInRecovery() {
|
|
recoveryVariantNeeded = true
|
|
coreVariantNeeded = false
|
|
}
|
|
|
|
for _, variant := range android.FirstUniqueStrings(vendorVariants) {
|
|
m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, VendorVariationPrefix+variant)
|
|
}
|
|
|
|
for _, variant := range android.FirstUniqueStrings(productVariants) {
|
|
m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant)
|
|
}
|
|
|
|
m.Properties.RamdiskVariantNeeded = ramdiskVariantNeeded
|
|
m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded
|
|
m.Properties.CoreVariantNeeded = coreVariantNeeded
|
|
}
|
|
|
|
func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
return c.Properties.CoreVariantNeeded
|
|
}
|
|
|
|
func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
return c.Properties.RamdiskVariantNeeded
|
|
}
|
|
|
|
func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
return c.Properties.RecoveryVariantNeeded
|
|
}
|
|
|
|
func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
|
|
return c.Properties.ExtraVariants
|
|
}
|
|
|
|
func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
|
|
m := module.(*Module)
|
|
if variant == android.RamdiskVariation {
|
|
m.MakeAsPlatform()
|
|
} else if variant == android.RecoveryVariation {
|
|
m.MakeAsPlatform()
|
|
squashRecoverySrcs(m)
|
|
} else if strings.HasPrefix(variant, VendorVariationPrefix) {
|
|
m.Properties.ImageVariationPrefix = VendorVariationPrefix
|
|
m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
|
|
squashVendorSrcs(m)
|
|
|
|
// Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
|
|
// Hide other vendor variants to avoid collision.
|
|
vndkVersion := ctx.DeviceConfig().VndkVersion()
|
|
if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
|
|
m.Properties.HideFromMake = true
|
|
m.SkipInstall()
|
|
}
|
|
} else if strings.HasPrefix(variant, ProductVariationPrefix) {
|
|
m.Properties.ImageVariationPrefix = ProductVariationPrefix
|
|
m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
|
|
squashVendorSrcs(m)
|
|
}
|
|
}
|