Add gcov coverage support to Rust modules.
This adds gcov coverage support for Rust device library and binary modules (including test modules). Support is provided to pass Rust static library gcno files to CC modules and visa versa. Additional changes: * Begin mutator added for Rust modules. * SuffixInList added to android package. * CoverageEnabled added to Coverage interface. * CoverageFiles added to LinkableLibrary interface. * Fix in coverage mutator for non-CC modules which marked the wrong variant as the coverage variant. * Added coverage libraries to the cc.GatherRequiredDepsForTest. Bug: 146448203 Test: NATIVE_COVERAGE=true COVERAGE_PATHS='*' m -j <rust_module> Change-Id: If20728bdde42a1dd544a35a40f0d981b80a5835f
This commit is contained in:
107
rust/rust.go
107
rust/rust.go
@@ -40,6 +40,7 @@ func init() {
|
||||
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||
ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
|
||||
ctx.BottomUp("rust_unit_tests", TestPerSrcMutator).Parallel()
|
||||
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
|
||||
})
|
||||
pctx.Import("android/soong/rust/config")
|
||||
}
|
||||
@@ -51,6 +52,7 @@ type Flags struct {
|
||||
LinkFlags []string // Flags that apply to linker
|
||||
RustFlagsDeps android.Paths // Files depended on by compiler flags
|
||||
Toolchain config.Toolchain
|
||||
Coverage bool
|
||||
}
|
||||
|
||||
type BaseProperties struct {
|
||||
@@ -60,6 +62,8 @@ type BaseProperties struct {
|
||||
AndroidMkSharedLibs []string
|
||||
AndroidMkStaticLibs []string
|
||||
SubName string `blueprint:"mutated"`
|
||||
PreventInstall bool
|
||||
HideFromMake bool
|
||||
}
|
||||
|
||||
type Module struct {
|
||||
@@ -72,6 +76,7 @@ type Module struct {
|
||||
multilib android.Multilib
|
||||
|
||||
compiler compiler
|
||||
coverage *coverage
|
||||
cachedToolchain config.Toolchain
|
||||
subAndroidMkOnce map[subAndroidMkProvider]bool
|
||||
outputFile android.OptionalPath
|
||||
@@ -224,6 +229,8 @@ type PathDeps struct {
|
||||
depFlags []string
|
||||
//ReexportedDeps android.Paths
|
||||
|
||||
coverageFiles android.Paths
|
||||
|
||||
CrtBegin android.OptionalPath
|
||||
CrtEnd android.OptionalPath
|
||||
}
|
||||
@@ -245,6 +252,34 @@ type compiler interface {
|
||||
inData() bool
|
||||
install(ctx ModuleContext, path android.Path)
|
||||
relativeInstallPath() string
|
||||
|
||||
nativeCoverage() bool
|
||||
}
|
||||
|
||||
func (mod *Module) isCoverageVariant() bool {
|
||||
return mod.coverage.Properties.IsCoverageVariant
|
||||
}
|
||||
|
||||
var _ cc.Coverage = (*Module)(nil)
|
||||
|
||||
func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
|
||||
return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
|
||||
}
|
||||
|
||||
func (mod *Module) PreventInstall() {
|
||||
mod.Properties.PreventInstall = true
|
||||
}
|
||||
|
||||
func (mod *Module) HideFromMake() {
|
||||
mod.Properties.HideFromMake = true
|
||||
}
|
||||
|
||||
func (mod *Module) MarkAsCoverageVariant(coverage bool) {
|
||||
mod.coverage.Properties.IsCoverageVariant = coverage
|
||||
}
|
||||
|
||||
func (mod *Module) EnableCoverageIfNeeded() {
|
||||
mod.coverage.Properties.CoverageEnabled = mod.coverage.Properties.NeedCoverageBuild
|
||||
}
|
||||
|
||||
func defaultsFactory() android.Module {
|
||||
@@ -268,6 +303,7 @@ func DefaultsFactory(props ...interface{}) android.Module {
|
||||
&ProcMacroCompilerProperties{},
|
||||
&PrebuiltProperties{},
|
||||
&TestProperties{},
|
||||
&cc.CoverageProperties{},
|
||||
)
|
||||
|
||||
android.InitDefaultsModule(module)
|
||||
@@ -395,6 +431,18 @@ func (mod *Module) HasStaticVariant() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (mod *Module) CoverageFiles() android.Paths {
|
||||
if mod.compiler != nil {
|
||||
if library, ok := mod.compiler.(*libraryDecorator); ok {
|
||||
if library.coverageFile != nil {
|
||||
return android.Paths{library.coverageFile}
|
||||
}
|
||||
return android.Paths{}
|
||||
}
|
||||
}
|
||||
panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName()))
|
||||
}
|
||||
|
||||
var _ cc.LinkableInterface = (*Module)(nil)
|
||||
|
||||
func (mod *Module) Init() android.Module {
|
||||
@@ -403,6 +451,10 @@ func (mod *Module) Init() android.Module {
|
||||
if mod.compiler != nil {
|
||||
mod.AddProperties(mod.compiler.compilerProps()...)
|
||||
}
|
||||
if mod.coverage != nil {
|
||||
mod.AddProperties(mod.coverage.props()...)
|
||||
}
|
||||
|
||||
android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
|
||||
|
||||
android.InitDefaultableModule(mod)
|
||||
@@ -432,6 +484,7 @@ func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib)
|
||||
}
|
||||
func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
|
||||
module := newBaseModule(hod, multilib)
|
||||
module.coverage = &coverage{}
|
||||
return module
|
||||
}
|
||||
|
||||
@@ -454,6 +507,7 @@ type ModuleContextIntf interface {
|
||||
toolchain() config.Toolchain
|
||||
baseModuleName() string
|
||||
CrateName() string
|
||||
nativeCoverage() bool
|
||||
}
|
||||
|
||||
type depsContext struct {
|
||||
@@ -466,6 +520,14 @@ type moduleContext struct {
|
||||
moduleContextImpl
|
||||
}
|
||||
|
||||
func (ctx *moduleContextImpl) nativeCoverage() bool {
|
||||
return ctx.mod.nativeCoverage()
|
||||
}
|
||||
|
||||
func (mod *Module) nativeCoverage() bool {
|
||||
return mod.compiler != nil && mod.compiler.nativeCoverage()
|
||||
}
|
||||
|
||||
type moduleContextImpl struct {
|
||||
mod *Module
|
||||
ctx BaseModuleContext
|
||||
@@ -508,9 +570,17 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
||||
|
||||
if mod.compiler != nil {
|
||||
flags = mod.compiler.compilerFlags(ctx, flags)
|
||||
}
|
||||
if mod.coverage != nil {
|
||||
flags, deps = mod.coverage.flags(ctx, flags, deps)
|
||||
}
|
||||
|
||||
if mod.compiler != nil {
|
||||
outputFile := mod.compiler.compile(ctx, flags, deps)
|
||||
mod.outputFile = android.OptionalPathForPath(outputFile)
|
||||
mod.compiler.install(ctx, mod.outputFile.Path())
|
||||
if !mod.Properties.PreventInstall {
|
||||
mod.compiler.install(ctx, mod.outputFile.Path())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,6 +591,10 @@ func (mod *Module) deps(ctx DepsContext) Deps {
|
||||
deps = mod.compiler.compilerDeps(ctx, deps)
|
||||
}
|
||||
|
||||
if mod.coverage != nil {
|
||||
deps = mod.coverage.deps(ctx, deps)
|
||||
}
|
||||
|
||||
deps.Rlibs = android.LastUniqueStrings(deps.Rlibs)
|
||||
deps.Dylibs = android.LastUniqueStrings(deps.Dylibs)
|
||||
deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros)
|
||||
@@ -553,6 +627,12 @@ var (
|
||||
testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"}
|
||||
)
|
||||
|
||||
func (mod *Module) begin(ctx BaseModuleContext) {
|
||||
if mod.coverage != nil {
|
||||
mod.coverage.begin(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||
var depPaths PathDeps
|
||||
|
||||
@@ -588,6 +668,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||
ctx.ModuleErrorf("mod %q not an rlib library", depName)
|
||||
return
|
||||
}
|
||||
depPaths.coverageFiles = append(depPaths.coverageFiles, rustDep.CoverageFiles()...)
|
||||
directRlibDeps = append(directRlibDeps, rustDep)
|
||||
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, depName)
|
||||
case procMacroDepTag:
|
||||
@@ -642,6 +723,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||
depFlag = "-lstatic=" + libName
|
||||
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
|
||||
depPaths.depFlags = append(depPaths.depFlags, depFlag)
|
||||
depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...)
|
||||
directStaticLibDeps = append(directStaticLibDeps, ccDep)
|
||||
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
|
||||
case cc.SharedDepTag:
|
||||
@@ -772,6 +854,29 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||
actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
|
||||
}
|
||||
|
||||
func BeginMutator(ctx android.BottomUpMutatorContext) {
|
||||
if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() {
|
||||
mod.beginMutator(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type baseModuleContext struct {
|
||||
android.BaseModuleContext
|
||||
moduleContextImpl
|
||||
}
|
||||
|
||||
func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) {
|
||||
ctx := &baseModuleContext{
|
||||
BaseModuleContext: actx,
|
||||
moduleContextImpl: moduleContextImpl{
|
||||
mod: mod,
|
||||
},
|
||||
}
|
||||
ctx.ctx = ctx
|
||||
|
||||
mod.begin(ctx)
|
||||
}
|
||||
|
||||
func (mod *Module) Name() string {
|
||||
name := mod.ModuleBase.Name()
|
||||
if p, ok := mod.compiler.(interface {
|
||||
|
Reference in New Issue
Block a user