Convert coverageMutator to a TransitionMutator

Convert coverageMutator to a TransitionMutator as a step towards
variants-on-demand.

Bug: 319288033
Test: coverage_test.go
Test: treehugger coverage builds
Change-Id: Ic50c0040dea8b42c36b5d784221daa00b7b0d379
This commit is contained in:
Colin Cross 2024-01-19 15:41:48 -08:00
parent 4aa3e0ab81
commit f5f4ad3db6
7 changed files with 77 additions and 34 deletions

View file

@ -1418,7 +1418,7 @@ func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
var _ cc.Coverage = (*apexBundle)(nil) var _ cc.Coverage = (*apexBundle)(nil)
// Implements cc.Coverage // Implements cc.Coverage
func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { func (a *apexBundle) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
return ctx.DeviceConfig().NativeCoverageEnabled() return ctx.DeviceConfig().NativeCoverageEnabled()
} }

View file

@ -68,7 +68,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) {
ctx.TopDown("fuzz_deps", fuzzMutatorDeps) ctx.TopDown("fuzz_deps", fuzzMutatorDeps)
ctx.BottomUp("coverage", coverageMutator).Parallel() ctx.Transition("coverage", &coverageTransitionMutator{})
ctx.TopDown("afdo_deps", afdoDepsMutator) ctx.TopDown("afdo_deps", afdoDepsMutator)
ctx.BottomUp("afdo", afdoMutator).Parallel() ctx.BottomUp("afdo", afdoMutator).Parallel()

View file

@ -223,7 +223,7 @@ func SetCoverageProperties(ctx android.BaseModuleContext, properties CoveragePro
type UseCoverage interface { type UseCoverage interface {
android.Module android.Module
IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool
} }
// Coverage is an interface for non-CC modules to implement to be mutated for coverage // Coverage is an interface for non-CC modules to implement to be mutated for coverage
@ -235,43 +235,86 @@ type Coverage interface {
EnableCoverageIfNeeded() EnableCoverageIfNeeded()
} }
func coverageMutator(mctx android.BottomUpMutatorContext) { type coverageTransitionMutator struct{}
if c, ok := mctx.Module().(*Module); ok && c.coverage != nil {
needCoverageVariant := c.coverage.Properties.NeedCoverageVariant
needCoverageBuild := c.coverage.Properties.NeedCoverageBuild
if needCoverageVariant {
m := mctx.CreateVariations("", "cov")
// Setup the non-coverage version and set HideFromMake and var _ android.TransitionMutator = (*coverageTransitionMutator)(nil)
// PreventInstall to 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, func (c coverageTransitionMutator) Split(ctx android.BaseModuleContext) []string {
// PreventInstall from the original module. if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
m[1].(*Module).coverage.Properties.CoverageEnabled = needCoverageBuild if c.coverage.Properties.NeedCoverageVariant {
m[1].(*Module).coverage.Properties.IsCoverageVariant = true return []string{"", "cov"}
} }
} else if cov, ok := mctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(mctx) { } else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
// APEX and Rust modules fall here // APEX and Rust modules fall here
// Note: variant "" is also created because an APEX can be depended on by another // Note: variant "" is also created because an APEX can be depended on by another
// module which are split into "" and "cov" variants. e.g. when cc_test refers // module which are split into "" and "cov" variants. e.g. when cc_test refers
// to an APEX via 'data' property. // to an APEX via 'data' property.
m := mctx.CreateVariations("", "cov") return []string{"", "cov"}
m[0].(Coverage).MarkAsCoverageVariant(false) } else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
m[0].(Coverage).SetPreventInstall() // Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
m[0].(Coverage).HideFromMake() // deps.
return []string{"cov"}
m[1].(Coverage).MarkAsCoverageVariant(true) }
m[1].(Coverage).EnableCoverageIfNeeded()
} else if cov, ok := mctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(mctx) { return []string{""}
}
func (c coverageTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
return sourceVariation
}
func (c coverageTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
if !c.coverage.Properties.NeedCoverageVariant {
return ""
}
} else if cov, ok := ctx.Module().(Coverage); ok {
if !cov.IsNativeCoverageNeeded(ctx) {
return ""
}
} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
// Module only has a "cov" variation, so all incoming variations should use "cov".
return "cov"
} else {
return ""
}
return incomingVariation
}
func (c coverageTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
if variation == "" && c.coverage.Properties.NeedCoverageVariant {
// Setup the non-coverage version and set HideFromMake and
// PreventInstall to true.
c.coverage.Properties.CoverageEnabled = false
c.coverage.Properties.IsCoverageVariant = false
c.Properties.HideFromMake = true
c.Properties.PreventInstall = true
} else if variation == "cov" {
// The coverage-enabled version inherits HideFromMake,
// PreventInstall from the original module.
c.coverage.Properties.CoverageEnabled = c.coverage.Properties.NeedCoverageBuild
c.coverage.Properties.IsCoverageVariant = true
}
} else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
// APEX and Rust modules fall here
// Note: variant "" is also created because an APEX can be depended on by another
// module which are split into "" and "cov" variants. e.g. when cc_test refers
// to an APEX via 'data' property.
if variation == "" {
cov.MarkAsCoverageVariant(false)
cov.SetPreventInstall()
cov.HideFromMake()
} else if variation == "cov" {
cov.MarkAsCoverageVariant(true)
cov.EnableCoverageIfNeeded()
}
} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
// Module itself doesn't have to have "cov" variant, but it should use "cov" variants of // Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
// deps. // deps.
mctx.CreateVariations("cov")
mctx.AliasVariation("cov")
} }
} }

View file

@ -512,6 +512,6 @@ func sha1sum(values []string) string {
var _ cc.UseCoverage = (*filesystem)(nil) var _ cc.UseCoverage = (*filesystem)(nil)
func (*filesystem) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { func (*filesystem) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled() return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
} }

View file

@ -1108,7 +1108,7 @@ func (a *AndroidApp) Privileged() bool {
return Bool(a.appProperties.Privileged) return Bool(a.appProperties.Privileged)
} }
func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled() return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
} }

View file

@ -1084,7 +1084,7 @@ func (j *JavaTestImport) InstallInTestcases() bool {
return true return true
} }
func (j *TestHost) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { func (j *TestHost) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
return ctx.DeviceConfig().NativeCoverageEnabled() return ctx.DeviceConfig().NativeCoverageEnabled()
} }

View file

@ -535,7 +535,7 @@ func (mod *Module) isCoverageVariant() bool {
var _ cc.Coverage = (*Module)(nil) var _ cc.Coverage = (*Module)(nil)
func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { func (mod *Module) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
} }