diff --git a/apex/apex.go b/apex/apex.go index 5b0def0d8..492431120 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1418,7 +1418,7 @@ func (a *apexBundle) TaggedOutputs() map[string]android.Paths { var _ cc.Coverage = (*apexBundle)(nil) // Implements cc.Coverage -func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { +func (a *apexBundle) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool { return ctx.DeviceConfig().NativeCoverageEnabled() } diff --git a/cc/cc.go b/cc/cc.go index c07e35850..41fea47fa 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -68,7 +68,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.TopDown("fuzz_deps", fuzzMutatorDeps) - ctx.BottomUp("coverage", coverageMutator).Parallel() + ctx.Transition("coverage", &coverageTransitionMutator{}) ctx.TopDown("afdo_deps", afdoDepsMutator) ctx.BottomUp("afdo", afdoMutator).Parallel() diff --git a/cc/coverage.go b/cc/coverage.go index 393a8a6b4..43f5e0762 100644 --- a/cc/coverage.go +++ b/cc/coverage.go @@ -246,7 +246,7 @@ func SetCoverageProperties(ctx android.BaseModuleContext, properties CoveragePro type UseCoverage interface { 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 @@ -258,43 +258,86 @@ type Coverage interface { EnableCoverageIfNeeded() } -func coverageMutator(mctx android.BottomUpMutatorContext) { - 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") +type coverageTransitionMutator struct{} - // Setup the non-coverage version and set HideFromMake and - // 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 +var _ android.TransitionMutator = (*coverageTransitionMutator)(nil) - // 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 +func (c coverageTransitionMutator) Split(ctx android.BaseModuleContext) []string { + if c, ok := ctx.Module().(*Module); ok && c.coverage != nil { + if c.coverage.Properties.NeedCoverageVariant { + 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 // 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. - m := mctx.CreateVariations("", "cov") - m[0].(Coverage).MarkAsCoverageVariant(false) - m[0].(Coverage).SetPreventInstall() - m[0].(Coverage).HideFromMake() - - m[1].(Coverage).MarkAsCoverageVariant(true) - m[1].(Coverage).EnableCoverageIfNeeded() - } else if cov, ok := mctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(mctx) { + return []string{"", "cov"} + } 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 + // deps. + return []string{"cov"} + } + + 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 // deps. - mctx.CreateVariations("cov") - mctx.AliasVariation("cov") } } diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 7b207d6ce..2f6476c82 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -512,6 +512,6 @@ func sha1sum(values []string) string { 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() } diff --git a/java/app.go b/java/app.go index cb05807b8..cbb24506d 100755 --- a/java/app.go +++ b/java/app.go @@ -1108,7 +1108,7 @@ func (a *AndroidApp) Privileged() bool { 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() } diff --git a/java/java.go b/java/java.go index d18d915cc..d5d309fa4 100644 --- a/java/java.go +++ b/java/java.go @@ -1084,7 +1084,7 @@ func (j *JavaTestImport) InstallInTestcases() bool { return true } -func (j *TestHost) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { +func (j *TestHost) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool { return ctx.DeviceConfig().NativeCoverageEnabled() } diff --git a/rust/rust.go b/rust/rust.go index 34ce4c545..245ed2e8e 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -535,7 +535,7 @@ func (mod *Module) isCoverageVariant() bool { 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 }