Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1acd4475 authored by Pirama Arumuga Nainar's avatar Pirama Arumuga Nainar
Browse files

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
parent c0907f19
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ func init() {
		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
		ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()

		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
		ctx.BottomUp("coverage", coverageMutator).Parallel()
		ctx.TopDown("vndk_deps", sabiDepsMutator)

		ctx.TopDown("lto_deps", ltoDepsMutator)
@@ -258,6 +258,7 @@ type ModuleContextIntf interface {
	baseModuleName() string
	getVndkExtendsModuleName() string
	isPgoCompile() bool
	isNDKStubLibrary() bool
	useClangLld(actx ModuleContext) bool
	apexName() string
	hasStubsVariants() bool
@@ -497,6 +498,10 @@ func (c *Module) useVndk() bool {
	return c.Properties.UseVndk
}

func (c *Module) isCoverageVariant() bool {
	return c.coverage.Properties.IsCoverageVariant
}

func (c *Module) isNdk() bool {
	return inList(c.Name(), ndkMigratedLibs)
}
@@ -530,6 +535,13 @@ func (c *Module) isPgoCompile() bool {
	return false
}

func (c *Module) isNDKStubLibrary() bool {
	if _, ok := c.compiler.(*stubDecorator); ok {
		return true
	}
	return false
}

func (c *Module) isVndkSp() bool {
	if vndkdep := c.vndkdep; vndkdep != nil {
		return vndkdep.isVndkSp()
@@ -675,6 +687,10 @@ func (ctx *moduleContextImpl) isPgoCompile() bool {
	return ctx.mod.isPgoCompile()
}

func (ctx *moduleContextImpl) isNDKStubLibrary() bool {
	return ctx.mod.isNDKStubLibrary()
}

func (ctx *moduleContextImpl) isVndkSp() bool {
	return ctx.mod.isVndkSp()
}
@@ -956,7 +972,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
		// module is marked with 'bootstrap: true').
		if c.HasStubsVariants() &&
			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
			// Note: this is still non-installable
		}
+47 −17
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
package cc

import (
	"strconv"

	"android/soong/android"
)

@@ -22,6 +24,7 @@ type CoverageProperties struct {
	Native_coverage *bool

	CoverageEnabled   bool `blueprint:"mutated"`
	IsCoverageVariant bool `blueprint:"mutated"`
}

type coverage struct {
@@ -93,27 +96,54 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags) Flags {
	return flags
}

func coverageLinkingMutator(mctx android.BottomUpMutatorContext) {
	if c, ok := mctx.Module().(*Module); ok && c.coverage != nil {
		var enabled bool

		if !mctx.DeviceConfig().NativeCoverageEnabled() {
func coverageMutator(mctx android.BottomUpMutatorContext) {
	// Coverage is disabled globally
		} else if mctx.Host() {
	if !mctx.DeviceConfig().NativeCoverageEnabled() {
		return
	}

	if c, ok := mctx.Module().(*Module); ok {
		var needCoverageVariant bool
		var needCoverageBuild bool

		if mctx.Host() {
			// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
			// Just turn off for now.
		} else if c.coverage.Properties.Native_coverage != nil {
			enabled = *c.coverage.Properties.Native_coverage
		} else {
			enabled = mctx.DeviceConfig().CoverageEnabledForPath(mctx.ModuleDir())
		} else if c.useVndk() || c.hasVendorVariant() {
			// Do not enable coverage for VNDK libraries
		} else if c.isNDKStubLibrary() {
			// 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 {
			// Create a variation so that we don't need to recompile objects
			// when turning on or off coverage. We'll still relink the necessary
			// binaries, since we don't know which ones those are until later.
			m := mctx.CreateLocalVariations("cov")
			m[0].(*Module).coverage.Properties.CoverageEnabled = true
		if needCoverageVariant {
			m := mctx.CreateVariations("", "cov")

			// 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

			// 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
		}
	}
}