xref: /aosp_15_r20/build/soong/cc/coverage.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage cc
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"strconv"
19*333d2b36SAndroid Build Coastguard Worker
20*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
23*333d2b36SAndroid Build Coastguard Worker)
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Workervar (
26*333d2b36SAndroid Build Coastguard Worker	clangCoverageHostLdFlags = []string{
27*333d2b36SAndroid Build Coastguard Worker		"-Wl,--no-as-needed",
28*333d2b36SAndroid Build Coastguard Worker		"-Wl,--wrap,open",
29*333d2b36SAndroid Build Coastguard Worker	}
30*333d2b36SAndroid Build Coastguard Worker	clangContinuousCoverageFlags = []string{
31*333d2b36SAndroid Build Coastguard Worker		"-mllvm",
32*333d2b36SAndroid Build Coastguard Worker		"-runtime-counter-relocation",
33*333d2b36SAndroid Build Coastguard Worker	}
34*333d2b36SAndroid Build Coastguard Worker	clangCoverageCFlags = []string{
35*333d2b36SAndroid Build Coastguard Worker		"-Wno-frame-larger-than=",
36*333d2b36SAndroid Build Coastguard Worker	}
37*333d2b36SAndroid Build Coastguard Worker	clangCoverageCommonFlags = []string{
38*333d2b36SAndroid Build Coastguard Worker		"-fcoverage-mapping",
39*333d2b36SAndroid Build Coastguard Worker		"-Wno-pass-failed",
40*333d2b36SAndroid Build Coastguard Worker		"-D__ANDROID_CLANG_COVERAGE__",
41*333d2b36SAndroid Build Coastguard Worker	}
42*333d2b36SAndroid Build Coastguard Worker	clangCoverageHWASanFlags = []string{
43*333d2b36SAndroid Build Coastguard Worker		"-mllvm",
44*333d2b36SAndroid Build Coastguard Worker		"-hwasan-globals=0",
45*333d2b36SAndroid Build Coastguard Worker	}
46*333d2b36SAndroid Build Coastguard Worker)
47*333d2b36SAndroid Build Coastguard Worker
48*333d2b36SAndroid Build Coastguard Workerconst profileInstrFlag = "-fprofile-instr-generate=/data/misc/trace/clang-%p-%m.profraw"
49*333d2b36SAndroid Build Coastguard Worker
50*333d2b36SAndroid Build Coastguard Workertype CoverageProperties struct {
51*333d2b36SAndroid Build Coastguard Worker	Native_coverage *bool
52*333d2b36SAndroid Build Coastguard Worker
53*333d2b36SAndroid Build Coastguard Worker	NeedCoverageVariant bool `blueprint:"mutated"`
54*333d2b36SAndroid Build Coastguard Worker	NeedCoverageBuild   bool `blueprint:"mutated"`
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Worker	CoverageEnabled   bool `blueprint:"mutated"`
57*333d2b36SAndroid Build Coastguard Worker	IsCoverageVariant bool `blueprint:"mutated"`
58*333d2b36SAndroid Build Coastguard Worker}
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Workertype coverage struct {
61*333d2b36SAndroid Build Coastguard Worker	Properties CoverageProperties
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker	// Whether binaries containing this module need --coverage added to their ldflags
64*333d2b36SAndroid Build Coastguard Worker	linkCoverage bool
65*333d2b36SAndroid Build Coastguard Worker}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Workerfunc (cov *coverage) props() []interface{} {
68*333d2b36SAndroid Build Coastguard Worker	return []interface{}{&cov.Properties}
69*333d2b36SAndroid Build Coastguard Worker}
70*333d2b36SAndroid Build Coastguard Worker
71*333d2b36SAndroid Build Coastguard Workerfunc getGcovProfileLibraryName(ctx ModuleContextIntf) string {
72*333d2b36SAndroid Build Coastguard Worker	// This function should only ever be called for a cc.Module, so the
73*333d2b36SAndroid Build Coastguard Worker	// following statement should always succeed.
74*333d2b36SAndroid Build Coastguard Worker	// LINT.IfChange
75*333d2b36SAndroid Build Coastguard Worker	if ctx.useSdk() {
76*333d2b36SAndroid Build Coastguard Worker		return "libprofile-extras_ndk"
77*333d2b36SAndroid Build Coastguard Worker	} else {
78*333d2b36SAndroid Build Coastguard Worker		return "libprofile-extras"
79*333d2b36SAndroid Build Coastguard Worker	}
80*333d2b36SAndroid Build Coastguard Worker}
81*333d2b36SAndroid Build Coastguard Worker
82*333d2b36SAndroid Build Coastguard Workerfunc getClangProfileLibraryName(ctx ModuleContextIntf) string {
83*333d2b36SAndroid Build Coastguard Worker	if ctx.useSdk() {
84*333d2b36SAndroid Build Coastguard Worker		return "libprofile-clang-extras_ndk"
85*333d2b36SAndroid Build Coastguard Worker	} else if ctx.isCfiAssemblySupportEnabled() {
86*333d2b36SAndroid Build Coastguard Worker		return "libprofile-clang-extras_cfi_support"
87*333d2b36SAndroid Build Coastguard Worker	} else {
88*333d2b36SAndroid Build Coastguard Worker		return "libprofile-clang-extras"
89*333d2b36SAndroid Build Coastguard Worker	}
90*333d2b36SAndroid Build Coastguard Worker	// LINT.ThenChange(library.go)
91*333d2b36SAndroid Build Coastguard Worker}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workerfunc (cov *coverage) deps(ctx DepsContext, deps Deps) Deps {
94*333d2b36SAndroid Build Coastguard Worker	if cov.Properties.NeedCoverageVariant && ctx.Device() {
95*333d2b36SAndroid Build Coastguard Worker		ctx.AddVariationDependencies([]blueprint.Variation{
96*333d2b36SAndroid Build Coastguard Worker			{Mutator: "link", Variation: "static"},
97*333d2b36SAndroid Build Coastguard Worker		}, CoverageDepTag, getGcovProfileLibraryName(ctx))
98*333d2b36SAndroid Build Coastguard Worker		ctx.AddVariationDependencies([]blueprint.Variation{
99*333d2b36SAndroid Build Coastguard Worker			{Mutator: "link", Variation: "static"},
100*333d2b36SAndroid Build Coastguard Worker		}, CoverageDepTag, getClangProfileLibraryName(ctx))
101*333d2b36SAndroid Build Coastguard Worker	}
102*333d2b36SAndroid Build Coastguard Worker	return deps
103*333d2b36SAndroid Build Coastguard Worker}
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Workerfunc EnableContinuousCoverage(ctx android.BaseModuleContext) bool {
106*333d2b36SAndroid Build Coastguard Worker	return ctx.DeviceConfig().ClangCoverageContinuousMode()
107*333d2b36SAndroid Build Coastguard Worker}
108*333d2b36SAndroid Build Coastguard Worker
109*333d2b36SAndroid Build Coastguard Workerfunc (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) {
110*333d2b36SAndroid Build Coastguard Worker	clangCoverage := ctx.DeviceConfig().ClangCoverageEnabled()
111*333d2b36SAndroid Build Coastguard Worker	gcovCoverage := ctx.DeviceConfig().GcovCoverageEnabled()
112*333d2b36SAndroid Build Coastguard Worker
113*333d2b36SAndroid Build Coastguard Worker	if !gcovCoverage && !clangCoverage {
114*333d2b36SAndroid Build Coastguard Worker		return flags, deps
115*333d2b36SAndroid Build Coastguard Worker	}
116*333d2b36SAndroid Build Coastguard Worker
117*333d2b36SAndroid Build Coastguard Worker	if cov.Properties.CoverageEnabled {
118*333d2b36SAndroid Build Coastguard Worker		cov.linkCoverage = true
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Worker		if gcovCoverage {
121*333d2b36SAndroid Build Coastguard Worker			flags.GcovCoverage = true
122*333d2b36SAndroid Build Coastguard Worker			flags.Local.CommonFlags = append(flags.Local.CommonFlags, "--coverage", "-O0")
123*333d2b36SAndroid Build Coastguard Worker
124*333d2b36SAndroid Build Coastguard Worker			// Override -Wframe-larger-than and non-default optimization
125*333d2b36SAndroid Build Coastguard Worker			// flags that the module may use.
126*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-Wno-frame-larger-than=", "-O0")
127*333d2b36SAndroid Build Coastguard Worker		} else if clangCoverage {
128*333d2b36SAndroid Build Coastguard Worker			flags.Local.CommonFlags = append(flags.Local.CommonFlags, profileInstrFlag)
129*333d2b36SAndroid Build Coastguard Worker			flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangCoverageCommonFlags...)
130*333d2b36SAndroid Build Coastguard Worker			// Override -Wframe-larger-than.  We can expect frame size increase after
131*333d2b36SAndroid Build Coastguard Worker			// coverage instrumentation.
132*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, clangCoverageCFlags...)
133*333d2b36SAndroid Build Coastguard Worker			if EnableContinuousCoverage(ctx) {
134*333d2b36SAndroid Build Coastguard Worker				flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangContinuousCoverageFlags...)
135*333d2b36SAndroid Build Coastguard Worker			}
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Worker			// http://b/248022906, http://b/247941801  enabling coverage and hwasan-globals
138*333d2b36SAndroid Build Coastguard Worker			// instrumentation together causes duplicate-symbol errors for __llvm_profile_filename.
139*333d2b36SAndroid Build Coastguard Worker			if c, ok := ctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(Hwasan) {
140*333d2b36SAndroid Build Coastguard Worker				flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangCoverageHWASanFlags...)
141*333d2b36SAndroid Build Coastguard Worker			}
142*333d2b36SAndroid Build Coastguard Worker		}
143*333d2b36SAndroid Build Coastguard Worker	}
144*333d2b36SAndroid Build Coastguard Worker
145*333d2b36SAndroid Build Coastguard Worker	// Even if we don't have coverage enabled, if any of our object files were compiled
146*333d2b36SAndroid Build Coastguard Worker	// with coverage, then we need to add --coverage to our ldflags.
147*333d2b36SAndroid Build Coastguard Worker	if !cov.linkCoverage {
148*333d2b36SAndroid Build Coastguard Worker		if ctx.static() && !ctx.staticBinary() {
149*333d2b36SAndroid Build Coastguard Worker			// For static libraries, the only thing that changes our object files
150*333d2b36SAndroid Build Coastguard Worker			// are included whole static libraries, so check to see if any of
151*333d2b36SAndroid Build Coastguard Worker			// those have coverage enabled.
152*333d2b36SAndroid Build Coastguard Worker			ctx.VisitDirectDeps(func(m android.Module) {
153*333d2b36SAndroid Build Coastguard Worker				if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
154*333d2b36SAndroid Build Coastguard Worker					if depTag.static() && depTag.wholeStatic {
155*333d2b36SAndroid Build Coastguard Worker						if cc, ok := m.(*Module); ok && cc.coverage != nil {
156*333d2b36SAndroid Build Coastguard Worker							if cc.coverage.linkCoverage {
157*333d2b36SAndroid Build Coastguard Worker								cov.linkCoverage = true
158*333d2b36SAndroid Build Coastguard Worker							}
159*333d2b36SAndroid Build Coastguard Worker						}
160*333d2b36SAndroid Build Coastguard Worker					}
161*333d2b36SAndroid Build Coastguard Worker				}
162*333d2b36SAndroid Build Coastguard Worker			})
163*333d2b36SAndroid Build Coastguard Worker		} else {
164*333d2b36SAndroid Build Coastguard Worker			// For executables and shared libraries, we need to check all of
165*333d2b36SAndroid Build Coastguard Worker			// our static dependencies.
166*333d2b36SAndroid Build Coastguard Worker			ctx.VisitDirectDeps(func(m android.Module) {
167*333d2b36SAndroid Build Coastguard Worker				cc, ok := m.(*Module)
168*333d2b36SAndroid Build Coastguard Worker				if !ok || cc.coverage == nil {
169*333d2b36SAndroid Build Coastguard Worker					return
170*333d2b36SAndroid Build Coastguard Worker				}
171*333d2b36SAndroid Build Coastguard Worker
172*333d2b36SAndroid Build Coastguard Worker				if static, ok := cc.linker.(libraryInterface); !ok || !static.static() {
173*333d2b36SAndroid Build Coastguard Worker					return
174*333d2b36SAndroid Build Coastguard Worker				}
175*333d2b36SAndroid Build Coastguard Worker
176*333d2b36SAndroid Build Coastguard Worker				if cc.coverage.linkCoverage {
177*333d2b36SAndroid Build Coastguard Worker					cov.linkCoverage = true
178*333d2b36SAndroid Build Coastguard Worker				}
179*333d2b36SAndroid Build Coastguard Worker			})
180*333d2b36SAndroid Build Coastguard Worker		}
181*333d2b36SAndroid Build Coastguard Worker	}
182*333d2b36SAndroid Build Coastguard Worker
183*333d2b36SAndroid Build Coastguard Worker	if cov.linkCoverage {
184*333d2b36SAndroid Build Coastguard Worker		if gcovCoverage {
185*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "--coverage")
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Worker			if ctx.Device() {
188*333d2b36SAndroid Build Coastguard Worker				coverage := ctx.GetDirectDepWithTag(getGcovProfileLibraryName(ctx), CoverageDepTag).(*Module)
189*333d2b36SAndroid Build Coastguard Worker				deps.WholeStaticLibs = append(deps.WholeStaticLibs, coverage.OutputFile().Path())
190*333d2b36SAndroid Build Coastguard Worker				flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--wrap,getenv")
191*333d2b36SAndroid Build Coastguard Worker			}
192*333d2b36SAndroid Build Coastguard Worker		} else if clangCoverage {
193*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, profileInstrFlag)
194*333d2b36SAndroid Build Coastguard Worker			if EnableContinuousCoverage(ctx) {
195*333d2b36SAndroid Build Coastguard Worker				flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm=-runtime-counter-relocation")
196*333d2b36SAndroid Build Coastguard Worker			}
197*333d2b36SAndroid Build Coastguard Worker
198*333d2b36SAndroid Build Coastguard Worker			if ctx.Device() {
199*333d2b36SAndroid Build Coastguard Worker				coverage := ctx.GetDirectDepWithTag(getClangProfileLibraryName(ctx), CoverageDepTag).(*Module)
200*333d2b36SAndroid Build Coastguard Worker				deps.WholeStaticLibs = append(deps.WholeStaticLibs, coverage.OutputFile().Path())
201*333d2b36SAndroid Build Coastguard Worker				flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--wrap,open")
202*333d2b36SAndroid Build Coastguard Worker			}
203*333d2b36SAndroid Build Coastguard Worker		}
204*333d2b36SAndroid Build Coastguard Worker	}
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Worker	return flags, deps
207*333d2b36SAndroid Build Coastguard Worker}
208*333d2b36SAndroid Build Coastguard Worker
209*333d2b36SAndroid Build Coastguard Workerfunc (cov *coverage) begin(ctx BaseModuleContext) {
210*333d2b36SAndroid Build Coastguard Worker	if ctx.Host() && !ctx.Os().Linux() {
211*333d2b36SAndroid Build Coastguard Worker		// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
212*333d2b36SAndroid Build Coastguard Worker		// Just turn off for now.
213*333d2b36SAndroid Build Coastguard Worker	} else {
214*333d2b36SAndroid Build Coastguard Worker		cov.Properties = SetCoverageProperties(ctx, cov.Properties, ctx.nativeCoverage(), ctx.useSdk(), ctx.sdkVersion())
215*333d2b36SAndroid Build Coastguard Worker	}
216*333d2b36SAndroid Build Coastguard Worker}
217*333d2b36SAndroid Build Coastguard Worker
218*333d2b36SAndroid Build Coastguard Workerfunc SetCoverageProperties(ctx android.BaseModuleContext, properties CoverageProperties, moduleTypeHasCoverage bool,
219*333d2b36SAndroid Build Coastguard Worker	useSdk bool, sdkVersion string) CoverageProperties {
220*333d2b36SAndroid Build Coastguard Worker	// Coverage is disabled globally
221*333d2b36SAndroid Build Coastguard Worker	if !ctx.DeviceConfig().NativeCoverageEnabled() {
222*333d2b36SAndroid Build Coastguard Worker		return properties
223*333d2b36SAndroid Build Coastguard Worker	}
224*333d2b36SAndroid Build Coastguard Worker
225*333d2b36SAndroid Build Coastguard Worker	var needCoverageVariant bool
226*333d2b36SAndroid Build Coastguard Worker	var needCoverageBuild bool
227*333d2b36SAndroid Build Coastguard Worker
228*333d2b36SAndroid Build Coastguard Worker	if moduleTypeHasCoverage {
229*333d2b36SAndroid Build Coastguard Worker		// Check if Native_coverage is set to false.  This property defaults to true.
230*333d2b36SAndroid Build Coastguard Worker		needCoverageVariant = BoolDefault(properties.Native_coverage, true)
231*333d2b36SAndroid Build Coastguard Worker		if useSdk && sdkVersion != "current" {
232*333d2b36SAndroid Build Coastguard Worker			// Native coverage is not supported for SDK versions < 23
233*333d2b36SAndroid Build Coastguard Worker			if fromApi, err := strconv.Atoi(sdkVersion); err == nil && fromApi < 23 {
234*333d2b36SAndroid Build Coastguard Worker				needCoverageVariant = false
235*333d2b36SAndroid Build Coastguard Worker			}
236*333d2b36SAndroid Build Coastguard Worker		}
237*333d2b36SAndroid Build Coastguard Worker
238*333d2b36SAndroid Build Coastguard Worker		if needCoverageVariant {
239*333d2b36SAndroid Build Coastguard Worker			// Coverage variant is actually built with coverage if enabled for its module path
240*333d2b36SAndroid Build Coastguard Worker			needCoverageBuild = ctx.DeviceConfig().NativeCoverageEnabledForPath(ctx.ModuleDir())
241*333d2b36SAndroid Build Coastguard Worker		}
242*333d2b36SAndroid Build Coastguard Worker	}
243*333d2b36SAndroid Build Coastguard Worker
244*333d2b36SAndroid Build Coastguard Worker	properties.NeedCoverageBuild = needCoverageBuild
245*333d2b36SAndroid Build Coastguard Worker	properties.NeedCoverageVariant = needCoverageVariant
246*333d2b36SAndroid Build Coastguard Worker
247*333d2b36SAndroid Build Coastguard Worker	return properties
248*333d2b36SAndroid Build Coastguard Worker}
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard Workertype IsNativeCoverageNeededContext interface {
251*333d2b36SAndroid Build Coastguard Worker	Config() android.Config
252*333d2b36SAndroid Build Coastguard Worker	DeviceConfig() android.DeviceConfig
253*333d2b36SAndroid Build Coastguard Worker	Device() bool
254*333d2b36SAndroid Build Coastguard Worker}
255*333d2b36SAndroid Build Coastguard Worker
256*333d2b36SAndroid Build Coastguard Workervar _ IsNativeCoverageNeededContext = android.IncomingTransitionContext(nil)
257*333d2b36SAndroid Build Coastguard Workervar _ IsNativeCoverageNeededContext = android.BaseModuleContext(nil)
258*333d2b36SAndroid Build Coastguard Workervar _ IsNativeCoverageNeededContext = android.BottomUpMutatorContext(nil)
259*333d2b36SAndroid Build Coastguard Worker
260*333d2b36SAndroid Build Coastguard Workertype UseCoverage interface {
261*333d2b36SAndroid Build Coastguard Worker	android.Module
262*333d2b36SAndroid Build Coastguard Worker	IsNativeCoverageNeeded(ctx IsNativeCoverageNeededContext) bool
263*333d2b36SAndroid Build Coastguard Worker}
264*333d2b36SAndroid Build Coastguard Worker
265*333d2b36SAndroid Build Coastguard Worker// Coverage is an interface for non-CC modules to implement to be mutated for coverage
266*333d2b36SAndroid Build Coastguard Workertype Coverage interface {
267*333d2b36SAndroid Build Coastguard Worker	UseCoverage
268*333d2b36SAndroid Build Coastguard Worker	SetPreventInstall()
269*333d2b36SAndroid Build Coastguard Worker	HideFromMake()
270*333d2b36SAndroid Build Coastguard Worker	MarkAsCoverageVariant(bool)
271*333d2b36SAndroid Build Coastguard Worker	EnableCoverageIfNeeded()
272*333d2b36SAndroid Build Coastguard Worker}
273*333d2b36SAndroid Build Coastguard Worker
274*333d2b36SAndroid Build Coastguard Workertype coverageTransitionMutator struct{}
275*333d2b36SAndroid Build Coastguard Worker
276*333d2b36SAndroid Build Coastguard Workervar _ android.TransitionMutator = (*coverageTransitionMutator)(nil)
277*333d2b36SAndroid Build Coastguard Worker
278*333d2b36SAndroid Build Coastguard Workerfunc (c coverageTransitionMutator) Split(ctx android.BaseModuleContext) []string {
279*333d2b36SAndroid Build Coastguard Worker	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
280*333d2b36SAndroid Build Coastguard Worker		if c.coverage.Properties.NeedCoverageVariant {
281*333d2b36SAndroid Build Coastguard Worker			return []string{"", "cov"}
282*333d2b36SAndroid Build Coastguard Worker		}
283*333d2b36SAndroid Build Coastguard Worker	} else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
284*333d2b36SAndroid Build Coastguard Worker		// APEX and Rust modules fall here
285*333d2b36SAndroid Build Coastguard Worker
286*333d2b36SAndroid Build Coastguard Worker		// Note: variant "" is also created because an APEX can be depended on by another
287*333d2b36SAndroid Build Coastguard Worker		// module which are split into "" and "cov" variants. e.g. when cc_test refers
288*333d2b36SAndroid Build Coastguard Worker		// to an APEX via 'data' property.
289*333d2b36SAndroid Build Coastguard Worker		return []string{"", "cov"}
290*333d2b36SAndroid Build Coastguard Worker	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
291*333d2b36SAndroid Build Coastguard Worker		// Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
292*333d2b36SAndroid Build Coastguard Worker		// deps.
293*333d2b36SAndroid Build Coastguard Worker		return []string{"cov"}
294*333d2b36SAndroid Build Coastguard Worker	}
295*333d2b36SAndroid Build Coastguard Worker
296*333d2b36SAndroid Build Coastguard Worker	return []string{""}
297*333d2b36SAndroid Build Coastguard Worker}
298*333d2b36SAndroid Build Coastguard Worker
299*333d2b36SAndroid Build Coastguard Workerfunc (c coverageTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
300*333d2b36SAndroid Build Coastguard Worker	return sourceVariation
301*333d2b36SAndroid Build Coastguard Worker}
302*333d2b36SAndroid Build Coastguard Worker
303*333d2b36SAndroid Build Coastguard Workerfunc (c coverageTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
304*333d2b36SAndroid Build Coastguard Worker	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
305*333d2b36SAndroid Build Coastguard Worker		if !c.coverage.Properties.NeedCoverageVariant {
306*333d2b36SAndroid Build Coastguard Worker			return ""
307*333d2b36SAndroid Build Coastguard Worker		}
308*333d2b36SAndroid Build Coastguard Worker	} else if cov, ok := ctx.Module().(Coverage); ok {
309*333d2b36SAndroid Build Coastguard Worker		if !cov.IsNativeCoverageNeeded(ctx) {
310*333d2b36SAndroid Build Coastguard Worker			return ""
311*333d2b36SAndroid Build Coastguard Worker		}
312*333d2b36SAndroid Build Coastguard Worker	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
313*333d2b36SAndroid Build Coastguard Worker		// Module only has a "cov" variation, so all incoming variations should use "cov".
314*333d2b36SAndroid Build Coastguard Worker		return "cov"
315*333d2b36SAndroid Build Coastguard Worker	} else {
316*333d2b36SAndroid Build Coastguard Worker		return ""
317*333d2b36SAndroid Build Coastguard Worker	}
318*333d2b36SAndroid Build Coastguard Worker
319*333d2b36SAndroid Build Coastguard Worker	return incomingVariation
320*333d2b36SAndroid Build Coastguard Worker}
321*333d2b36SAndroid Build Coastguard Worker
322*333d2b36SAndroid Build Coastguard Workerfunc (c coverageTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
323*333d2b36SAndroid Build Coastguard Worker	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
324*333d2b36SAndroid Build Coastguard Worker		if variation == "" && c.coverage.Properties.NeedCoverageVariant {
325*333d2b36SAndroid Build Coastguard Worker			// Setup the non-coverage version and set HideFromMake and
326*333d2b36SAndroid Build Coastguard Worker			// PreventInstall to true.
327*333d2b36SAndroid Build Coastguard Worker			c.coverage.Properties.CoverageEnabled = false
328*333d2b36SAndroid Build Coastguard Worker			c.coverage.Properties.IsCoverageVariant = false
329*333d2b36SAndroid Build Coastguard Worker			c.Properties.HideFromMake = true
330*333d2b36SAndroid Build Coastguard Worker			c.Properties.PreventInstall = true
331*333d2b36SAndroid Build Coastguard Worker		} else if variation == "cov" {
332*333d2b36SAndroid Build Coastguard Worker			// The coverage-enabled version inherits HideFromMake,
333*333d2b36SAndroid Build Coastguard Worker			// PreventInstall from the original module.
334*333d2b36SAndroid Build Coastguard Worker			c.coverage.Properties.CoverageEnabled = c.coverage.Properties.NeedCoverageBuild
335*333d2b36SAndroid Build Coastguard Worker			c.coverage.Properties.IsCoverageVariant = true
336*333d2b36SAndroid Build Coastguard Worker		}
337*333d2b36SAndroid Build Coastguard Worker	} else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
338*333d2b36SAndroid Build Coastguard Worker		// APEX and Rust modules fall here
339*333d2b36SAndroid Build Coastguard Worker
340*333d2b36SAndroid Build Coastguard Worker		// Note: variant "" is also created because an APEX can be depended on by another
341*333d2b36SAndroid Build Coastguard Worker		// module which are split into "" and "cov" variants. e.g. when cc_test refers
342*333d2b36SAndroid Build Coastguard Worker		// to an APEX via 'data' property.
343*333d2b36SAndroid Build Coastguard Worker		if variation == "" {
344*333d2b36SAndroid Build Coastguard Worker			cov.MarkAsCoverageVariant(false)
345*333d2b36SAndroid Build Coastguard Worker			cov.SetPreventInstall()
346*333d2b36SAndroid Build Coastguard Worker			cov.HideFromMake()
347*333d2b36SAndroid Build Coastguard Worker		} else if variation == "cov" {
348*333d2b36SAndroid Build Coastguard Worker			cov.MarkAsCoverageVariant(true)
349*333d2b36SAndroid Build Coastguard Worker			cov.EnableCoverageIfNeeded()
350*333d2b36SAndroid Build Coastguard Worker		}
351*333d2b36SAndroid Build Coastguard Worker	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
352*333d2b36SAndroid Build Coastguard Worker		// Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
353*333d2b36SAndroid Build Coastguard Worker		// deps.
354*333d2b36SAndroid Build Coastguard Worker	}
355*333d2b36SAndroid Build Coastguard Worker}
356*333d2b36SAndroid Build Coastguard Worker
357*333d2b36SAndroid Build Coastguard Workerfunc parseSymbolFileForAPICoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
358*333d2b36SAndroid Build Coastguard Worker	apiLevelsJson := android.GetApiLevelsJson(ctx)
359*333d2b36SAndroid Build Coastguard Worker	symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
360*333d2b36SAndroid Build Coastguard Worker	outputFile := ctx.baseModuleName() + ".xml"
361*333d2b36SAndroid Build Coastguard Worker	parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFile)
362*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
363*333d2b36SAndroid Build Coastguard Worker	rule.Command().
364*333d2b36SAndroid Build Coastguard Worker		BuiltTool("ndk_api_coverage_parser").
365*333d2b36SAndroid Build Coastguard Worker		Input(symbolFilePath).
366*333d2b36SAndroid Build Coastguard Worker		Output(parsedApiCoveragePath).
367*333d2b36SAndroid Build Coastguard Worker		Implicit(apiLevelsJson).
368*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("--api-map ", apiLevelsJson.String())
369*333d2b36SAndroid Build Coastguard Worker	rule.Build("native_library_api_list", "Generate native API list based on symbol files for coverage measurement")
370*333d2b36SAndroid Build Coastguard Worker	return parsedApiCoveragePath
371*333d2b36SAndroid Build Coastguard Worker}
372