Extend coverage mutator to allow variants with coverage on and off
Bug: http://b/116873221 This allows us to enable coverage for a module (typically static libraries) even if a dependent module cannot build with coverage. In this case, the dependent module can just pick the variant with coverage off. - Create the following variants from the coverage mutator: - "" (empty): Don't build with coverage and always pick the non-coverage variants for dependents. This variant is created for modules with 'native_coverage: false'. - "cov": If this module's path is covered by the COVERAGE_PATHS option, build this module with coverage. If not, build this module without coverage. In either case, pick coverage variants ("cov") for dependencies if available. - Do not enable coverage: - for NDK stub libraries - if sdk_version < 23 since libc doesn't export 'stderr' which is needed by the coverage/profile runtime library. - for VNDK libraries Test: In AOSP: m COVERAGE_PATHS=system/security NATIVE_COVERAGE=true nothing Change-Id: I4d08790d35cdeaf12fb3c4f999d69a870e65836a
This commit is contained in:
21
cc/cc.go
21
cc/cc.go
@@ -63,7 +63,7 @@ func init() {
|
|||||||
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
|
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
|
||||||
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
|
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
|
||||||
|
|
||||||
ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
|
ctx.BottomUp("coverage", coverageMutator).Parallel()
|
||||||
ctx.TopDown("vndk_deps", sabiDepsMutator)
|
ctx.TopDown("vndk_deps", sabiDepsMutator)
|
||||||
|
|
||||||
ctx.TopDown("lto_deps", ltoDepsMutator)
|
ctx.TopDown("lto_deps", ltoDepsMutator)
|
||||||
@@ -258,6 +258,7 @@ type ModuleContextIntf interface {
|
|||||||
baseModuleName() string
|
baseModuleName() string
|
||||||
getVndkExtendsModuleName() string
|
getVndkExtendsModuleName() string
|
||||||
isPgoCompile() bool
|
isPgoCompile() bool
|
||||||
|
isNDKStubLibrary() bool
|
||||||
useClangLld(actx ModuleContext) bool
|
useClangLld(actx ModuleContext) bool
|
||||||
apexName() string
|
apexName() string
|
||||||
hasStubsVariants() bool
|
hasStubsVariants() bool
|
||||||
@@ -497,6 +498,10 @@ func (c *Module) useVndk() bool {
|
|||||||
return c.Properties.UseVndk
|
return c.Properties.UseVndk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Module) isCoverageVariant() bool {
|
||||||
|
return c.coverage.Properties.IsCoverageVariant
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Module) isNdk() bool {
|
func (c *Module) isNdk() bool {
|
||||||
return inList(c.Name(), ndkMigratedLibs)
|
return inList(c.Name(), ndkMigratedLibs)
|
||||||
}
|
}
|
||||||
@@ -530,6 +535,13 @@ func (c *Module) isPgoCompile() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Module) isNDKStubLibrary() bool {
|
||||||
|
if _, ok := c.compiler.(*stubDecorator); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Module) isVndkSp() bool {
|
func (c *Module) isVndkSp() bool {
|
||||||
if vndkdep := c.vndkdep; vndkdep != nil {
|
if vndkdep := c.vndkdep; vndkdep != nil {
|
||||||
return vndkdep.isVndkSp()
|
return vndkdep.isVndkSp()
|
||||||
@@ -675,6 +687,10 @@ func (ctx *moduleContextImpl) isPgoCompile() bool {
|
|||||||
return ctx.mod.isPgoCompile()
|
return ctx.mod.isPgoCompile()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx *moduleContextImpl) isNDKStubLibrary() bool {
|
||||||
|
return ctx.mod.isNDKStubLibrary()
|
||||||
|
}
|
||||||
|
|
||||||
func (ctx *moduleContextImpl) isVndkSp() bool {
|
func (ctx *moduleContextImpl) isVndkSp() bool {
|
||||||
return ctx.mod.isVndkSp()
|
return ctx.mod.isVndkSp()
|
||||||
}
|
}
|
||||||
@@ -956,7 +972,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||||||
// module is marked with 'bootstrap: true').
|
// module is marked with 'bootstrap: true').
|
||||||
if c.HasStubsVariants() &&
|
if c.HasStubsVariants() &&
|
||||||
android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) &&
|
android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) &&
|
||||||
!c.inRecovery() && !c.useVndk() && !c.static() && c.IsStubs() {
|
!c.inRecovery() && !c.useVndk() && !c.static() && !c.isCoverageVariant() &&
|
||||||
|
c.IsStubs() {
|
||||||
c.Properties.HideFromMake = false // unhide
|
c.Properties.HideFromMake = false // unhide
|
||||||
// Note: this is still non-installable
|
// Note: this is still non-installable
|
||||||
}
|
}
|
||||||
|
@@ -15,13 +15,16 @@
|
|||||||
package cc
|
package cc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CoverageProperties struct {
|
type CoverageProperties struct {
|
||||||
Native_coverage *bool
|
Native_coverage *bool
|
||||||
|
|
||||||
CoverageEnabled bool `blueprint:"mutated"`
|
CoverageEnabled bool `blueprint:"mutated"`
|
||||||
|
IsCoverageVariant bool `blueprint:"mutated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type coverage struct {
|
type coverage struct {
|
||||||
@@ -93,27 +96,54 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func coverageLinkingMutator(mctx android.BottomUpMutatorContext) {
|
func coverageMutator(mctx android.BottomUpMutatorContext) {
|
||||||
if c, ok := mctx.Module().(*Module); ok && c.coverage != nil {
|
// Coverage is disabled globally
|
||||||
var enabled bool
|
if !mctx.DeviceConfig().NativeCoverageEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !mctx.DeviceConfig().NativeCoverageEnabled() {
|
if c, ok := mctx.Module().(*Module); ok {
|
||||||
// Coverage is disabled globally
|
var needCoverageVariant bool
|
||||||
} else if mctx.Host() {
|
var needCoverageBuild bool
|
||||||
|
|
||||||
|
if mctx.Host() {
|
||||||
// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
|
// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
|
||||||
// Just turn off for now.
|
// Just turn off for now.
|
||||||
} else if c.coverage.Properties.Native_coverage != nil {
|
} else if c.useVndk() || c.hasVendorVariant() {
|
||||||
enabled = *c.coverage.Properties.Native_coverage
|
// Do not enable coverage for VNDK libraries
|
||||||
} else {
|
} else if c.isNDKStubLibrary() {
|
||||||
enabled = mctx.DeviceConfig().CoverageEnabledForPath(mctx.ModuleDir())
|
// Do not enable coverage for NDK stub libraries
|
||||||
|
} else if c.coverage != nil {
|
||||||
|
// Check if Native_coverage is set to false. This property defaults to true.
|
||||||
|
needCoverageVariant = BoolDefault(c.coverage.Properties.Native_coverage, true)
|
||||||
|
|
||||||
|
if sdk_version := String(c.Properties.Sdk_version); sdk_version != "current" {
|
||||||
|
// Native coverage is not supported for SDK versions < 23
|
||||||
|
if fromApi, err := strconv.Atoi(sdk_version); err == nil && fromApi < 23 {
|
||||||
|
needCoverageVariant = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if needCoverageVariant {
|
||||||
|
// Coverage variant is actually built with coverage if enabled for its module path
|
||||||
|
needCoverageBuild = mctx.DeviceConfig().CoverageEnabledForPath(mctx.ModuleDir())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if enabled {
|
if needCoverageVariant {
|
||||||
// Create a variation so that we don't need to recompile objects
|
m := mctx.CreateVariations("", "cov")
|
||||||
// when turning on or off coverage. We'll still relink the necessary
|
|
||||||
// binaries, since we don't know which ones those are until later.
|
// Setup the non-coverage version and set HideFromMake and
|
||||||
m := mctx.CreateLocalVariations("cov")
|
// PreventInstall to true.
|
||||||
m[0].(*Module).coverage.Properties.CoverageEnabled = true
|
m[0].(*Module).coverage.Properties.CoverageEnabled = false
|
||||||
|
m[0].(*Module).coverage.Properties.IsCoverageVariant = false
|
||||||
|
m[0].(*Module).Properties.HideFromMake = true
|
||||||
|
m[0].(*Module).Properties.PreventInstall = true
|
||||||
|
|
||||||
|
// The coverage-enabled version inherits HideFromMake,
|
||||||
|
// PreventInstall from the original module.
|
||||||
|
m[1].(*Module).coverage.Properties.CoverageEnabled = needCoverageBuild
|
||||||
|
m[1].(*Module).coverage.Properties.IsCoverageVariant = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user