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
diff --git a/rust/rust.go b/rust/rust.go
index 5cc8845..8cf2e6d 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -40,6 +40,7 @@
 	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 @@
 	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 @@
 	AndroidMkSharedLibs    []string
 	AndroidMkStaticLibs    []string
 	SubName                string `blueprint:"mutated"`
+	PreventInstall         bool
+	HideFromMake           bool
 }
 
 type Module struct {
@@ -72,6 +76,7 @@
 	multilib android.Multilib
 
 	compiler         compiler
+	coverage         *coverage
 	cachedToolchain  config.Toolchain
 	subAndroidMkOnce map[subAndroidMkProvider]bool
 	outputFile       android.OptionalPath
@@ -224,6 +229,8 @@
 	depFlags   []string
 	//ReexportedDeps android.Paths
 
+	coverageFiles android.Paths
+
 	CrtBegin android.OptionalPath
 	CrtEnd   android.OptionalPath
 }
@@ -245,6 +252,34 @@
 	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 @@
 		&ProcMacroCompilerProperties{},
 		&PrebuiltProperties{},
 		&TestProperties{},
+		&cc.CoverageProperties{},
 	)
 
 	android.InitDefaultsModule(module)
@@ -395,6 +431,18 @@
 	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 @@
 	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 newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
 	module := newBaseModule(hod, multilib)
+	module.coverage = &coverage{}
 	return module
 }
 
@@ -454,6 +507,7 @@
 	toolchain() config.Toolchain
 	baseModuleName() string
 	CrateName() string
+	nativeCoverage() bool
 }
 
 type depsContext struct {
@@ -466,6 +520,14 @@
 	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 @@
 
 	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 @@
 		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 @@
 	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 @@
 					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 @@
 				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 @@
 	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 {