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