1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 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 "fmt" 19*333d2b36SAndroid Build Coastguard Worker "path/filepath" 20*333d2b36SAndroid Build Coastguard Worker "runtime" 21*333d2b36SAndroid Build Coastguard Worker "strings" 22*333d2b36SAndroid Build Coastguard Worker "sync" 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 25*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 26*333d2b36SAndroid Build Coastguard Worker 27*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 28*333d2b36SAndroid Build Coastguard Worker "android/soong/cc/config" 29*333d2b36SAndroid Build Coastguard Worker) 30*333d2b36SAndroid Build Coastguard Worker 31*333d2b36SAndroid Build Coastguard Workerfunc init() { 32*333d2b36SAndroid Build Coastguard Worker pctx.HostBinToolVariable("ndkStubGenerator", "ndkstubgen") 33*333d2b36SAndroid Build Coastguard Worker pctx.HostBinToolVariable("stg", "stg") 34*333d2b36SAndroid Build Coastguard Worker pctx.HostBinToolVariable("stgdiff", "stgdiff") 35*333d2b36SAndroid Build Coastguard Worker} 36*333d2b36SAndroid Build Coastguard Worker 37*333d2b36SAndroid Build Coastguard Workervar ( 38*333d2b36SAndroid Build Coastguard Worker genStubSrc = pctx.AndroidStaticRule("genStubSrc", 39*333d2b36SAndroid Build Coastguard Worker blueprint.RuleParams{ 40*333d2b36SAndroid Build Coastguard Worker Command: "$ndkStubGenerator --arch $arch --api $apiLevel " + 41*333d2b36SAndroid Build Coastguard Worker "--api-map $apiMap $flags $in $out", 42*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"$ndkStubGenerator"}, 43*333d2b36SAndroid Build Coastguard Worker }, "arch", "apiLevel", "apiMap", "flags") 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker // $headersList should include paths to public headers. All types 46*333d2b36SAndroid Build Coastguard Worker // that are defined outside of public headers will be excluded from 47*333d2b36SAndroid Build Coastguard Worker // ABI monitoring. 48*333d2b36SAndroid Build Coastguard Worker // 49*333d2b36SAndroid Build Coastguard Worker // STG tool doesn't access content of files listed in $headersList, 50*333d2b36SAndroid Build Coastguard Worker // so there is no need to add them to dependencies. 51*333d2b36SAndroid Build Coastguard Worker stg = pctx.AndroidStaticRule("stg", 52*333d2b36SAndroid Build Coastguard Worker blueprint.RuleParams{ 53*333d2b36SAndroid Build Coastguard Worker Command: "$stg -S :$symbolList --file-filter :$headersList --elf $in -o $out", 54*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"$stg"}, 55*333d2b36SAndroid Build Coastguard Worker }, "symbolList", "headersList") 56*333d2b36SAndroid Build Coastguard Worker 57*333d2b36SAndroid Build Coastguard Worker stgdiff = pctx.AndroidStaticRule("stgdiff", 58*333d2b36SAndroid Build Coastguard Worker blueprint.RuleParams{ 59*333d2b36SAndroid Build Coastguard Worker // Need to create *some* output for ninja. We don't want to use tee 60*333d2b36SAndroid Build Coastguard Worker // because we don't want to spam the build output with "nothing 61*333d2b36SAndroid Build Coastguard Worker // changed" messages, so redirect output message to $out, and if 62*333d2b36SAndroid Build Coastguard Worker // changes were detected print the output and fail. 63*333d2b36SAndroid Build Coastguard Worker Command: "$stgdiff $args --stg $in -o $out || (cat $out && echo 'Run $$ANDROID_BUILD_TOP/development/tools/ndk/update_ndk_abi.sh to update the ABI dumps.' && false)", 64*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"$stgdiff"}, 65*333d2b36SAndroid Build Coastguard Worker }, "args") 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Worker ndkLibrarySuffix = ".ndk" 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Worker ndkKnownLibsKey = android.NewOnceKey("ndkKnownLibsKey") 70*333d2b36SAndroid Build Coastguard Worker // protects ndkKnownLibs writes during parallel BeginMutator. 71*333d2b36SAndroid Build Coastguard Worker ndkKnownLibsLock sync.Mutex 72*333d2b36SAndroid Build Coastguard Worker 73*333d2b36SAndroid Build Coastguard Worker stubImplementation = dependencyTag{name: "stubImplementation"} 74*333d2b36SAndroid Build Coastguard Worker) 75*333d2b36SAndroid Build Coastguard Worker 76*333d2b36SAndroid Build Coastguard Worker// The First_version and Unversioned_until properties of this struct should not 77*333d2b36SAndroid Build Coastguard Worker// be used directly, but rather through the ApiLevel returning methods 78*333d2b36SAndroid Build Coastguard Worker// firstVersion() and unversionedUntil(). 79*333d2b36SAndroid Build Coastguard Worker 80*333d2b36SAndroid Build Coastguard Worker// Creates a stub shared library based on the provided version file. 81*333d2b36SAndroid Build Coastguard Worker// 82*333d2b36SAndroid Build Coastguard Worker// Example: 83*333d2b36SAndroid Build Coastguard Worker// 84*333d2b36SAndroid Build Coastguard Worker// ndk_library { 85*333d2b36SAndroid Build Coastguard Worker// 86*333d2b36SAndroid Build Coastguard Worker// name: "libfoo", 87*333d2b36SAndroid Build Coastguard Worker// symbol_file: "libfoo.map.txt", 88*333d2b36SAndroid Build Coastguard Worker// first_version: "9", 89*333d2b36SAndroid Build Coastguard Worker// 90*333d2b36SAndroid Build Coastguard Worker// } 91*333d2b36SAndroid Build Coastguard Workertype libraryProperties struct { 92*333d2b36SAndroid Build Coastguard Worker // Relative path to the symbol map. 93*333d2b36SAndroid Build Coastguard Worker // An example file can be seen here: TODO(danalbert): Make an example. 94*333d2b36SAndroid Build Coastguard Worker Symbol_file *string `android:"path"` 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker // The first API level a library was available. A library will be generated 97*333d2b36SAndroid Build Coastguard Worker // for every API level beginning with this one. 98*333d2b36SAndroid Build Coastguard Worker First_version *string 99*333d2b36SAndroid Build Coastguard Worker 100*333d2b36SAndroid Build Coastguard Worker // The first API level that library should have the version script applied. 101*333d2b36SAndroid Build Coastguard Worker // This defaults to the value of first_version, and should almost never be 102*333d2b36SAndroid Build Coastguard Worker // used. This is only needed to work around platform bugs like 103*333d2b36SAndroid Build Coastguard Worker // https://github.com/android-ndk/ndk/issues/265. 104*333d2b36SAndroid Build Coastguard Worker Unversioned_until *string 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Worker // DO NOT USE THIS 107*333d2b36SAndroid Build Coastguard Worker // NDK libraries should not export their headers. Headers belonging to NDK 108*333d2b36SAndroid Build Coastguard Worker // libraries should be added to the NDK with an ndk_headers module. 109*333d2b36SAndroid Build Coastguard Worker Export_header_libs []string 110*333d2b36SAndroid Build Coastguard Worker 111*333d2b36SAndroid Build Coastguard Worker // Do not add other export_* properties without consulting with danalbert@. 112*333d2b36SAndroid Build Coastguard Worker // Consumers of ndk_library modules should emulate the typical NDK build 113*333d2b36SAndroid Build Coastguard Worker // behavior as closely as possible (that is, all NDK APIs are exposed to 114*333d2b36SAndroid Build Coastguard Worker // builds via --sysroot). Export behaviors used in Soong will not be present 115*333d2b36SAndroid Build Coastguard Worker // for app developers as they don't use Soong, and reliance on these export 116*333d2b36SAndroid Build Coastguard Worker // behaviors can mask issues with the NDK sysroot. 117*333d2b36SAndroid Build Coastguard Worker} 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Workertype stubDecorator struct { 120*333d2b36SAndroid Build Coastguard Worker *libraryDecorator 121*333d2b36SAndroid Build Coastguard Worker 122*333d2b36SAndroid Build Coastguard Worker properties libraryProperties 123*333d2b36SAndroid Build Coastguard Worker 124*333d2b36SAndroid Build Coastguard Worker versionScriptPath android.ModuleGenPath 125*333d2b36SAndroid Build Coastguard Worker parsedCoverageXmlPath android.ModuleOutPath 126*333d2b36SAndroid Build Coastguard Worker installPath android.Path 127*333d2b36SAndroid Build Coastguard Worker abiDumpPath android.OutputPath 128*333d2b36SAndroid Build Coastguard Worker hasAbiDump bool 129*333d2b36SAndroid Build Coastguard Worker abiDiffPaths android.Paths 130*333d2b36SAndroid Build Coastguard Worker 131*333d2b36SAndroid Build Coastguard Worker apiLevel android.ApiLevel 132*333d2b36SAndroid Build Coastguard Worker firstVersion android.ApiLevel 133*333d2b36SAndroid Build Coastguard Worker unversionedUntil android.ApiLevel 134*333d2b36SAndroid Build Coastguard Worker} 135*333d2b36SAndroid Build Coastguard Worker 136*333d2b36SAndroid Build Coastguard Workervar _ versionedInterface = (*stubDecorator)(nil) 137*333d2b36SAndroid Build Coastguard Worker 138*333d2b36SAndroid Build Coastguard Workerfunc shouldUseVersionScript(ctx BaseModuleContext, stub *stubDecorator) bool { 139*333d2b36SAndroid Build Coastguard Worker return stub.apiLevel.GreaterThanOrEqualTo(stub.unversionedUntil) 140*333d2b36SAndroid Build Coastguard Worker} 141*333d2b36SAndroid Build Coastguard Worker 142*333d2b36SAndroid Build Coastguard Workerfunc (stub *stubDecorator) implementationModuleName(name string) string { 143*333d2b36SAndroid Build Coastguard Worker return strings.TrimSuffix(name, ndkLibrarySuffix) 144*333d2b36SAndroid Build Coastguard Worker} 145*333d2b36SAndroid Build Coastguard Worker 146*333d2b36SAndroid Build Coastguard Workerfunc ndkLibraryVersions(ctx android.BaseModuleContext, from android.ApiLevel) []string { 147*333d2b36SAndroid Build Coastguard Worker versionStrs := []string{} 148*333d2b36SAndroid Build Coastguard Worker for _, version := range ctx.Config().FinalApiLevels() { 149*333d2b36SAndroid Build Coastguard Worker if version.GreaterThanOrEqualTo(from) { 150*333d2b36SAndroid Build Coastguard Worker versionStrs = append(versionStrs, version.String()) 151*333d2b36SAndroid Build Coastguard Worker } 152*333d2b36SAndroid Build Coastguard Worker } 153*333d2b36SAndroid Build Coastguard Worker versionStrs = append(versionStrs, android.FutureApiLevel.String()) 154*333d2b36SAndroid Build Coastguard Worker 155*333d2b36SAndroid Build Coastguard Worker return versionStrs 156*333d2b36SAndroid Build Coastguard Worker} 157*333d2b36SAndroid Build Coastguard Worker 158*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) stubsVersions(ctx android.BaseModuleContext) []string { 159*333d2b36SAndroid Build Coastguard Worker if !ctx.Module().Enabled(ctx) { 160*333d2b36SAndroid Build Coastguard Worker return nil 161*333d2b36SAndroid Build Coastguard Worker } 162*333d2b36SAndroid Build Coastguard Worker if ctx.Target().NativeBridge == android.NativeBridgeEnabled { 163*333d2b36SAndroid Build Coastguard Worker ctx.Module().Disable() 164*333d2b36SAndroid Build Coastguard Worker return nil 165*333d2b36SAndroid Build Coastguard Worker } 166*333d2b36SAndroid Build Coastguard Worker firstVersion, err := nativeApiLevelFromUser(ctx, 167*333d2b36SAndroid Build Coastguard Worker String(this.properties.First_version)) 168*333d2b36SAndroid Build Coastguard Worker if err != nil { 169*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("first_version", err.Error()) 170*333d2b36SAndroid Build Coastguard Worker return nil 171*333d2b36SAndroid Build Coastguard Worker } 172*333d2b36SAndroid Build Coastguard Worker return ndkLibraryVersions(ctx, firstVersion) 173*333d2b36SAndroid Build Coastguard Worker} 174*333d2b36SAndroid Build Coastguard Worker 175*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) initializeProperties(ctx BaseModuleContext) bool { 176*333d2b36SAndroid Build Coastguard Worker this.apiLevel = nativeApiLevelOrPanic(ctx, this.stubsVersion()) 177*333d2b36SAndroid Build Coastguard Worker 178*333d2b36SAndroid Build Coastguard Worker var err error 179*333d2b36SAndroid Build Coastguard Worker this.firstVersion, err = nativeApiLevelFromUser(ctx, 180*333d2b36SAndroid Build Coastguard Worker String(this.properties.First_version)) 181*333d2b36SAndroid Build Coastguard Worker if err != nil { 182*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("first_version", err.Error()) 183*333d2b36SAndroid Build Coastguard Worker return false 184*333d2b36SAndroid Build Coastguard Worker } 185*333d2b36SAndroid Build Coastguard Worker 186*333d2b36SAndroid Build Coastguard Worker str := proptools.StringDefault(this.properties.Unversioned_until, "minimum") 187*333d2b36SAndroid Build Coastguard Worker this.unversionedUntil, err = nativeApiLevelFromUser(ctx, str) 188*333d2b36SAndroid Build Coastguard Worker if err != nil { 189*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("unversioned_until", err.Error()) 190*333d2b36SAndroid Build Coastguard Worker return false 191*333d2b36SAndroid Build Coastguard Worker } 192*333d2b36SAndroid Build Coastguard Worker 193*333d2b36SAndroid Build Coastguard Worker return true 194*333d2b36SAndroid Build Coastguard Worker} 195*333d2b36SAndroid Build Coastguard Worker 196*333d2b36SAndroid Build Coastguard Workerfunc getNDKKnownLibs(config android.Config) *[]string { 197*333d2b36SAndroid Build Coastguard Worker return config.Once(ndkKnownLibsKey, func() interface{} { 198*333d2b36SAndroid Build Coastguard Worker return &[]string{} 199*333d2b36SAndroid Build Coastguard Worker }).(*[]string) 200*333d2b36SAndroid Build Coastguard Worker} 201*333d2b36SAndroid Build Coastguard Worker 202*333d2b36SAndroid Build Coastguard Workerfunc (c *stubDecorator) compilerInit(ctx BaseModuleContext) { 203*333d2b36SAndroid Build Coastguard Worker c.baseCompiler.compilerInit(ctx) 204*333d2b36SAndroid Build Coastguard Worker 205*333d2b36SAndroid Build Coastguard Worker name := ctx.baseModuleName() 206*333d2b36SAndroid Build Coastguard Worker if strings.HasSuffix(name, ndkLibrarySuffix) { 207*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("name", "Do not append %q manually, just use the base name", ndkLibrarySuffix) 208*333d2b36SAndroid Build Coastguard Worker } 209*333d2b36SAndroid Build Coastguard Worker 210*333d2b36SAndroid Build Coastguard Worker ndkKnownLibsLock.Lock() 211*333d2b36SAndroid Build Coastguard Worker defer ndkKnownLibsLock.Unlock() 212*333d2b36SAndroid Build Coastguard Worker ndkKnownLibs := getNDKKnownLibs(ctx.Config()) 213*333d2b36SAndroid Build Coastguard Worker for _, lib := range *ndkKnownLibs { 214*333d2b36SAndroid Build Coastguard Worker if lib == name { 215*333d2b36SAndroid Build Coastguard Worker return 216*333d2b36SAndroid Build Coastguard Worker } 217*333d2b36SAndroid Build Coastguard Worker } 218*333d2b36SAndroid Build Coastguard Worker *ndkKnownLibs = append(*ndkKnownLibs, name) 219*333d2b36SAndroid Build Coastguard Worker} 220*333d2b36SAndroid Build Coastguard Worker 221*333d2b36SAndroid Build Coastguard Workervar stubLibraryCompilerFlags = []string{ 222*333d2b36SAndroid Build Coastguard Worker // We're knowingly doing some otherwise unsightly things with builtin 223*333d2b36SAndroid Build Coastguard Worker // functions here. We're just generating stub libraries, so ignore it. 224*333d2b36SAndroid Build Coastguard Worker "-Wno-incompatible-library-redeclaration", 225*333d2b36SAndroid Build Coastguard Worker "-Wno-incomplete-setjmp-declaration", 226*333d2b36SAndroid Build Coastguard Worker "-Wno-builtin-requires-header", 227*333d2b36SAndroid Build Coastguard Worker "-Wno-invalid-noreturn", 228*333d2b36SAndroid Build Coastguard Worker "-Wall", 229*333d2b36SAndroid Build Coastguard Worker "-Werror", 230*333d2b36SAndroid Build Coastguard Worker // These libraries aren't actually used. Don't worry about unwinding 231*333d2b36SAndroid Build Coastguard Worker // (avoids the need to link an unwinder into a fake library). 232*333d2b36SAndroid Build Coastguard Worker "-fno-unwind-tables", 233*333d2b36SAndroid Build Coastguard Worker} 234*333d2b36SAndroid Build Coastguard Worker 235*333d2b36SAndroid Build Coastguard Workerfunc init() { 236*333d2b36SAndroid Build Coastguard Worker pctx.StaticVariable("StubLibraryCompilerFlags", strings.Join(stubLibraryCompilerFlags, " ")) 237*333d2b36SAndroid Build Coastguard Worker} 238*333d2b36SAndroid Build Coastguard Worker 239*333d2b36SAndroid Build Coastguard Workerfunc addStubLibraryCompilerFlags(flags Flags) Flags { 240*333d2b36SAndroid Build Coastguard Worker flags.Global.CFlags = append(flags.Global.CFlags, stubLibraryCompilerFlags...) 241*333d2b36SAndroid Build Coastguard Worker // All symbols in the stubs library should be visible. 242*333d2b36SAndroid Build Coastguard Worker if inList("-fvisibility=hidden", flags.Local.CFlags) { 243*333d2b36SAndroid Build Coastguard Worker flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default") 244*333d2b36SAndroid Build Coastguard Worker } 245*333d2b36SAndroid Build Coastguard Worker return flags 246*333d2b36SAndroid Build Coastguard Worker} 247*333d2b36SAndroid Build Coastguard Worker 248*333d2b36SAndroid Build Coastguard Workerfunc (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags { 249*333d2b36SAndroid Build Coastguard Worker flags = stub.baseCompiler.compilerFlags(ctx, flags, deps) 250*333d2b36SAndroid Build Coastguard Worker return addStubLibraryCompilerFlags(flags) 251*333d2b36SAndroid Build Coastguard Worker} 252*333d2b36SAndroid Build Coastguard Worker 253*333d2b36SAndroid Build Coastguard Workertype ndkApiOutputs struct { 254*333d2b36SAndroid Build Coastguard Worker stubSrc android.ModuleGenPath 255*333d2b36SAndroid Build Coastguard Worker versionScript android.ModuleGenPath 256*333d2b36SAndroid Build Coastguard Worker symbolList android.ModuleGenPath 257*333d2b36SAndroid Build Coastguard Worker} 258*333d2b36SAndroid Build Coastguard Worker 259*333d2b36SAndroid Build Coastguard Workerfunc parseNativeAbiDefinition(ctx ModuleContext, symbolFile string, 260*333d2b36SAndroid Build Coastguard Worker apiLevel android.ApiLevel, genstubFlags string) ndkApiOutputs { 261*333d2b36SAndroid Build Coastguard Worker 262*333d2b36SAndroid Build Coastguard Worker stubSrcPath := android.PathForModuleGen(ctx, "stub.c") 263*333d2b36SAndroid Build Coastguard Worker versionScriptPath := android.PathForModuleGen(ctx, "stub.map") 264*333d2b36SAndroid Build Coastguard Worker symbolFilePath := android.PathForModuleSrc(ctx, symbolFile) 265*333d2b36SAndroid Build Coastguard Worker symbolListPath := android.PathForModuleGen(ctx, "abi_symbol_list.txt") 266*333d2b36SAndroid Build Coastguard Worker apiLevelsJson := android.GetApiLevelsJson(ctx) 267*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 268*333d2b36SAndroid Build Coastguard Worker Rule: genStubSrc, 269*333d2b36SAndroid Build Coastguard Worker Description: "generate stubs " + symbolFilePath.Rel(), 270*333d2b36SAndroid Build Coastguard Worker Outputs: []android.WritablePath{stubSrcPath, versionScriptPath, 271*333d2b36SAndroid Build Coastguard Worker symbolListPath}, 272*333d2b36SAndroid Build Coastguard Worker Input: symbolFilePath, 273*333d2b36SAndroid Build Coastguard Worker Implicits: []android.Path{apiLevelsJson}, 274*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 275*333d2b36SAndroid Build Coastguard Worker "arch": ctx.Arch().ArchType.String(), 276*333d2b36SAndroid Build Coastguard Worker "apiLevel": apiLevel.String(), 277*333d2b36SAndroid Build Coastguard Worker "apiMap": apiLevelsJson.String(), 278*333d2b36SAndroid Build Coastguard Worker "flags": genstubFlags, 279*333d2b36SAndroid Build Coastguard Worker }, 280*333d2b36SAndroid Build Coastguard Worker }) 281*333d2b36SAndroid Build Coastguard Worker 282*333d2b36SAndroid Build Coastguard Worker return ndkApiOutputs{ 283*333d2b36SAndroid Build Coastguard Worker stubSrc: stubSrcPath, 284*333d2b36SAndroid Build Coastguard Worker versionScript: versionScriptPath, 285*333d2b36SAndroid Build Coastguard Worker symbolList: symbolListPath, 286*333d2b36SAndroid Build Coastguard Worker } 287*333d2b36SAndroid Build Coastguard Worker} 288*333d2b36SAndroid Build Coastguard Worker 289*333d2b36SAndroid Build Coastguard Workerfunc compileStubLibrary(ctx ModuleContext, flags Flags, src android.Path) Objects { 290*333d2b36SAndroid Build Coastguard Worker // libc/libm stubs libraries end up mismatching with clang's internal definition of these 291*333d2b36SAndroid Build Coastguard Worker // functions (which have noreturn attributes and other things). Because we just want to create a 292*333d2b36SAndroid Build Coastguard Worker // stub with symbol definitions, and types aren't important in C, ignore the mismatch. 293*333d2b36SAndroid Build Coastguard Worker flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, "-fno-builtin") 294*333d2b36SAndroid Build Coastguard Worker return compileObjs(ctx, flagsToBuilderFlags(flags), "", 295*333d2b36SAndroid Build Coastguard Worker android.Paths{src}, nil, nil, nil, nil) 296*333d2b36SAndroid Build Coastguard Worker} 297*333d2b36SAndroid Build Coastguard Worker 298*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path { 299*333d2b36SAndroid Build Coastguard Worker dep := ctx.GetDirectDepWithTag(strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix), 300*333d2b36SAndroid Build Coastguard Worker stubImplementation) 301*333d2b36SAndroid Build Coastguard Worker if dep == nil { 302*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("Could not find implementation for stub") 303*333d2b36SAndroid Build Coastguard Worker return nil 304*333d2b36SAndroid Build Coastguard Worker } 305*333d2b36SAndroid Build Coastguard Worker impl, ok := dep.(*Module) 306*333d2b36SAndroid Build Coastguard Worker if !ok { 307*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("Implementation for stub is not correct module type") 308*333d2b36SAndroid Build Coastguard Worker return nil 309*333d2b36SAndroid Build Coastguard Worker } 310*333d2b36SAndroid Build Coastguard Worker output := impl.UnstrippedOutputFile() 311*333d2b36SAndroid Build Coastguard Worker if output == nil { 312*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("implementation module (%s) has no output", impl) 313*333d2b36SAndroid Build Coastguard Worker return nil 314*333d2b36SAndroid Build Coastguard Worker } 315*333d2b36SAndroid Build Coastguard Worker 316*333d2b36SAndroid Build Coastguard Worker return output 317*333d2b36SAndroid Build Coastguard Worker} 318*333d2b36SAndroid Build Coastguard Worker 319*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) libraryName(ctx ModuleContext) string { 320*333d2b36SAndroid Build Coastguard Worker return strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix) 321*333d2b36SAndroid Build Coastguard Worker} 322*333d2b36SAndroid Build Coastguard Worker 323*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) findPrebuiltAbiDump(ctx ModuleContext, 324*333d2b36SAndroid Build Coastguard Worker apiLevel android.ApiLevel) android.OptionalPath { 325*333d2b36SAndroid Build Coastguard Worker 326*333d2b36SAndroid Build Coastguard Worker subpath := filepath.Join("prebuilts/abi-dumps/ndk", apiLevel.String(), 327*333d2b36SAndroid Build Coastguard Worker ctx.Arch().ArchType.String(), this.libraryName(ctx), "abi.stg") 328*333d2b36SAndroid Build Coastguard Worker return android.ExistentPathForSource(ctx, subpath) 329*333d2b36SAndroid Build Coastguard Worker} 330*333d2b36SAndroid Build Coastguard Worker 331*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) builtAbiDumpLocation(ctx ModuleContext, apiLevel android.ApiLevel) android.OutputPath { 332*333d2b36SAndroid Build Coastguard Worker return getNdkAbiDumpInstallBase(ctx).Join(ctx, 333*333d2b36SAndroid Build Coastguard Worker apiLevel.String(), ctx.Arch().ArchType.String(), 334*333d2b36SAndroid Build Coastguard Worker this.libraryName(ctx), "abi.stg") 335*333d2b36SAndroid Build Coastguard Worker} 336*333d2b36SAndroid Build Coastguard Worker 337*333d2b36SAndroid Build Coastguard Worker// Feature flag. 338*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) canDumpAbi(ctx ModuleContext) bool { 339*333d2b36SAndroid Build Coastguard Worker if runtime.GOOS == "darwin" { 340*333d2b36SAndroid Build Coastguard Worker return false 341*333d2b36SAndroid Build Coastguard Worker } 342*333d2b36SAndroid Build Coastguard Worker if strings.HasPrefix(ctx.ModuleDir(), "bionic/") { 343*333d2b36SAndroid Build Coastguard Worker // Bionic has enough uncommon implementation details like ifuncs and asm 344*333d2b36SAndroid Build Coastguard Worker // code that the ABI tracking here has a ton of false positives. That's 345*333d2b36SAndroid Build Coastguard Worker // causing pretty extreme friction for development there, so disabling 346*333d2b36SAndroid Build Coastguard Worker // it until the workflow can be improved. 347*333d2b36SAndroid Build Coastguard Worker // 348*333d2b36SAndroid Build Coastguard Worker // http://b/358653811 349*333d2b36SAndroid Build Coastguard Worker return false 350*333d2b36SAndroid Build Coastguard Worker } 351*333d2b36SAndroid Build Coastguard Worker 352*333d2b36SAndroid Build Coastguard Worker // http://b/156513478 353*333d2b36SAndroid Build Coastguard Worker return ctx.Config().ReleaseNdkAbiMonitored() 354*333d2b36SAndroid Build Coastguard Worker} 355*333d2b36SAndroid Build Coastguard Worker 356*333d2b36SAndroid Build Coastguard Worker// Feature flag to disable diffing against prebuilts. 357*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) canDiffAbi(config android.Config) bool { 358*333d2b36SAndroid Build Coastguard Worker if this.apiLevel.IsCurrent() { 359*333d2b36SAndroid Build Coastguard Worker // Diffs are performed from this to next, and there's nothing after 360*333d2b36SAndroid Build Coastguard Worker // current. 361*333d2b36SAndroid Build Coastguard Worker return false 362*333d2b36SAndroid Build Coastguard Worker } 363*333d2b36SAndroid Build Coastguard Worker 364*333d2b36SAndroid Build Coastguard Worker return config.ReleaseNdkAbiMonitored() 365*333d2b36SAndroid Build Coastguard Worker} 366*333d2b36SAndroid Build Coastguard Worker 367*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) dumpAbi(ctx ModuleContext, symbolList android.Path) { 368*333d2b36SAndroid Build Coastguard Worker implementationLibrary := this.findImplementationLibrary(ctx) 369*333d2b36SAndroid Build Coastguard Worker this.abiDumpPath = this.builtAbiDumpLocation(ctx, this.apiLevel) 370*333d2b36SAndroid Build Coastguard Worker this.hasAbiDump = true 371*333d2b36SAndroid Build Coastguard Worker headersList := getNdkABIHeadersFile(ctx) 372*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 373*333d2b36SAndroid Build Coastguard Worker Rule: stg, 374*333d2b36SAndroid Build Coastguard Worker Description: fmt.Sprintf("stg %s", implementationLibrary), 375*333d2b36SAndroid Build Coastguard Worker Input: implementationLibrary, 376*333d2b36SAndroid Build Coastguard Worker Implicits: []android.Path{ 377*333d2b36SAndroid Build Coastguard Worker symbolList, 378*333d2b36SAndroid Build Coastguard Worker headersList, 379*333d2b36SAndroid Build Coastguard Worker }, 380*333d2b36SAndroid Build Coastguard Worker Output: this.abiDumpPath, 381*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 382*333d2b36SAndroid Build Coastguard Worker "symbolList": symbolList.String(), 383*333d2b36SAndroid Build Coastguard Worker "headersList": headersList.String(), 384*333d2b36SAndroid Build Coastguard Worker }, 385*333d2b36SAndroid Build Coastguard Worker }) 386*333d2b36SAndroid Build Coastguard Worker} 387*333d2b36SAndroid Build Coastguard Worker 388*333d2b36SAndroid Build Coastguard Workerfunc findNextApiLevel(ctx ModuleContext, apiLevel android.ApiLevel) *android.ApiLevel { 389*333d2b36SAndroid Build Coastguard Worker apiLevels := append(ctx.Config().FinalApiLevels(), 390*333d2b36SAndroid Build Coastguard Worker android.FutureApiLevel) 391*333d2b36SAndroid Build Coastguard Worker for _, api := range apiLevels { 392*333d2b36SAndroid Build Coastguard Worker if api.GreaterThan(apiLevel) { 393*333d2b36SAndroid Build Coastguard Worker return &api 394*333d2b36SAndroid Build Coastguard Worker } 395*333d2b36SAndroid Build Coastguard Worker } 396*333d2b36SAndroid Build Coastguard Worker return nil 397*333d2b36SAndroid Build Coastguard Worker} 398*333d2b36SAndroid Build Coastguard Worker 399*333d2b36SAndroid Build Coastguard Workerfunc (this *stubDecorator) diffAbi(ctx ModuleContext) { 400*333d2b36SAndroid Build Coastguard Worker // Catch any ABI changes compared to the checked-in definition of this API 401*333d2b36SAndroid Build Coastguard Worker // level. 402*333d2b36SAndroid Build Coastguard Worker abiDiffPath := android.PathForModuleOut(ctx, "stgdiff.timestamp") 403*333d2b36SAndroid Build Coastguard Worker prebuiltAbiDump := this.findPrebuiltAbiDump(ctx, this.apiLevel) 404*333d2b36SAndroid Build Coastguard Worker missingPrebuiltErrorTemplate := 405*333d2b36SAndroid Build Coastguard Worker "Did not find prebuilt ABI dump for %q (%q). Generate with " + 406*333d2b36SAndroid Build Coastguard Worker "//development/tools/ndk/update_ndk_abi.sh." 407*333d2b36SAndroid Build Coastguard Worker missingPrebuiltError := fmt.Sprintf( 408*333d2b36SAndroid Build Coastguard Worker missingPrebuiltErrorTemplate, this.libraryName(ctx), 409*333d2b36SAndroid Build Coastguard Worker prebuiltAbiDump.InvalidReason()) 410*333d2b36SAndroid Build Coastguard Worker if !prebuiltAbiDump.Valid() { 411*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 412*333d2b36SAndroid Build Coastguard Worker Rule: android.ErrorRule, 413*333d2b36SAndroid Build Coastguard Worker Output: abiDiffPath, 414*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 415*333d2b36SAndroid Build Coastguard Worker "error": missingPrebuiltError, 416*333d2b36SAndroid Build Coastguard Worker }, 417*333d2b36SAndroid Build Coastguard Worker }) 418*333d2b36SAndroid Build Coastguard Worker } else { 419*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 420*333d2b36SAndroid Build Coastguard Worker Rule: stgdiff, 421*333d2b36SAndroid Build Coastguard Worker Description: fmt.Sprintf("Comparing ABI %s %s", prebuiltAbiDump, 422*333d2b36SAndroid Build Coastguard Worker this.abiDumpPath), 423*333d2b36SAndroid Build Coastguard Worker Output: abiDiffPath, 424*333d2b36SAndroid Build Coastguard Worker Inputs: android.Paths{prebuiltAbiDump.Path(), this.abiDumpPath}, 425*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 426*333d2b36SAndroid Build Coastguard Worker "args": "--format=small", 427*333d2b36SAndroid Build Coastguard Worker }, 428*333d2b36SAndroid Build Coastguard Worker }) 429*333d2b36SAndroid Build Coastguard Worker } 430*333d2b36SAndroid Build Coastguard Worker this.abiDiffPaths = append(this.abiDiffPaths, abiDiffPath) 431*333d2b36SAndroid Build Coastguard Worker 432*333d2b36SAndroid Build Coastguard Worker // Also ensure that the ABI of the next API level (if there is one) matches 433*333d2b36SAndroid Build Coastguard Worker // this API level. *New* ABI is allowed, but any changes to APIs that exist 434*333d2b36SAndroid Build Coastguard Worker // in this API level are disallowed. 435*333d2b36SAndroid Build Coastguard Worker if prebuiltAbiDump.Valid() { 436*333d2b36SAndroid Build Coastguard Worker nextApiLevel := findNextApiLevel(ctx, this.apiLevel) 437*333d2b36SAndroid Build Coastguard Worker if nextApiLevel == nil { 438*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("could not determine which API level follows "+ 439*333d2b36SAndroid Build Coastguard Worker "non-current API level %s", this.apiLevel)) 440*333d2b36SAndroid Build Coastguard Worker } 441*333d2b36SAndroid Build Coastguard Worker 442*333d2b36SAndroid Build Coastguard Worker // Preview ABI levels are not recorded in prebuilts. ABI compatibility 443*333d2b36SAndroid Build Coastguard Worker // for preview APIs is still monitored via "current" so we have early 444*333d2b36SAndroid Build Coastguard Worker // warning rather than learning about an ABI break during finalization, 445*333d2b36SAndroid Build Coastguard Worker // but is only checked against the "current" API dumps in the out 446*333d2b36SAndroid Build Coastguard Worker // directory. 447*333d2b36SAndroid Build Coastguard Worker nextAbiDiffPath := android.PathForModuleOut(ctx, 448*333d2b36SAndroid Build Coastguard Worker "abidiff_next.timestamp") 449*333d2b36SAndroid Build Coastguard Worker 450*333d2b36SAndroid Build Coastguard Worker var nextAbiDump android.OptionalPath 451*333d2b36SAndroid Build Coastguard Worker if nextApiLevel.IsCurrent() { 452*333d2b36SAndroid Build Coastguard Worker nextAbiDump = android.OptionalPathForPath( 453*333d2b36SAndroid Build Coastguard Worker this.builtAbiDumpLocation(ctx, *nextApiLevel), 454*333d2b36SAndroid Build Coastguard Worker ) 455*333d2b36SAndroid Build Coastguard Worker } else { 456*333d2b36SAndroid Build Coastguard Worker nextAbiDump = this.findPrebuiltAbiDump(ctx, *nextApiLevel) 457*333d2b36SAndroid Build Coastguard Worker } 458*333d2b36SAndroid Build Coastguard Worker 459*333d2b36SAndroid Build Coastguard Worker if !nextAbiDump.Valid() { 460*333d2b36SAndroid Build Coastguard Worker missingNextPrebuiltError := fmt.Sprintf( 461*333d2b36SAndroid Build Coastguard Worker missingPrebuiltErrorTemplate, this.libraryName(ctx), 462*333d2b36SAndroid Build Coastguard Worker nextAbiDump.InvalidReason()) 463*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 464*333d2b36SAndroid Build Coastguard Worker Rule: android.ErrorRule, 465*333d2b36SAndroid Build Coastguard Worker Output: nextAbiDiffPath, 466*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 467*333d2b36SAndroid Build Coastguard Worker "error": missingNextPrebuiltError, 468*333d2b36SAndroid Build Coastguard Worker }, 469*333d2b36SAndroid Build Coastguard Worker }) 470*333d2b36SAndroid Build Coastguard Worker } else { 471*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 472*333d2b36SAndroid Build Coastguard Worker Rule: stgdiff, 473*333d2b36SAndroid Build Coastguard Worker Description: fmt.Sprintf( 474*333d2b36SAndroid Build Coastguard Worker "Comparing ABI to the next API level %s %s", 475*333d2b36SAndroid Build Coastguard Worker prebuiltAbiDump, nextAbiDump), 476*333d2b36SAndroid Build Coastguard Worker Output: nextAbiDiffPath, 477*333d2b36SAndroid Build Coastguard Worker Inputs: android.Paths{ 478*333d2b36SAndroid Build Coastguard Worker prebuiltAbiDump.Path(), nextAbiDump.Path()}, 479*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 480*333d2b36SAndroid Build Coastguard Worker "args": "--format=small --ignore=interface_addition", 481*333d2b36SAndroid Build Coastguard Worker }, 482*333d2b36SAndroid Build Coastguard Worker }) 483*333d2b36SAndroid Build Coastguard Worker } 484*333d2b36SAndroid Build Coastguard Worker this.abiDiffPaths = append(this.abiDiffPaths, nextAbiDiffPath) 485*333d2b36SAndroid Build Coastguard Worker } 486*333d2b36SAndroid Build Coastguard Worker} 487*333d2b36SAndroid Build Coastguard Worker 488*333d2b36SAndroid Build Coastguard Workerfunc (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { 489*333d2b36SAndroid Build Coastguard Worker if !strings.HasSuffix(String(c.properties.Symbol_file), ".map.txt") { 490*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("symbol_file", "must end with .map.txt") 491*333d2b36SAndroid Build Coastguard Worker } 492*333d2b36SAndroid Build Coastguard Worker 493*333d2b36SAndroid Build Coastguard Worker if !c.buildStubs() { 494*333d2b36SAndroid Build Coastguard Worker // NDK libraries have no implementation variant, nothing to do 495*333d2b36SAndroid Build Coastguard Worker return Objects{} 496*333d2b36SAndroid Build Coastguard Worker } 497*333d2b36SAndroid Build Coastguard Worker 498*333d2b36SAndroid Build Coastguard Worker if !c.initializeProperties(ctx) { 499*333d2b36SAndroid Build Coastguard Worker // Emits its own errors, so we don't need to. 500*333d2b36SAndroid Build Coastguard Worker return Objects{} 501*333d2b36SAndroid Build Coastguard Worker } 502*333d2b36SAndroid Build Coastguard Worker 503*333d2b36SAndroid Build Coastguard Worker symbolFile := String(c.properties.Symbol_file) 504*333d2b36SAndroid Build Coastguard Worker nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "") 505*333d2b36SAndroid Build Coastguard Worker objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc) 506*333d2b36SAndroid Build Coastguard Worker c.versionScriptPath = nativeAbiResult.versionScript 507*333d2b36SAndroid Build Coastguard Worker if c.canDumpAbi(ctx) { 508*333d2b36SAndroid Build Coastguard Worker c.dumpAbi(ctx, nativeAbiResult.symbolList) 509*333d2b36SAndroid Build Coastguard Worker if c.canDiffAbi(ctx.Config()) { 510*333d2b36SAndroid Build Coastguard Worker c.diffAbi(ctx) 511*333d2b36SAndroid Build Coastguard Worker } 512*333d2b36SAndroid Build Coastguard Worker } 513*333d2b36SAndroid Build Coastguard Worker if c.apiLevel.IsCurrent() && ctx.PrimaryArch() { 514*333d2b36SAndroid Build Coastguard Worker c.parsedCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile) 515*333d2b36SAndroid Build Coastguard Worker } 516*333d2b36SAndroid Build Coastguard Worker return objs 517*333d2b36SAndroid Build Coastguard Worker} 518*333d2b36SAndroid Build Coastguard Worker 519*333d2b36SAndroid Build Coastguard Worker// Add a dependency on the header modules of this ndk_library 520*333d2b36SAndroid Build Coastguard Workerfunc (linker *stubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { 521*333d2b36SAndroid Build Coastguard Worker return Deps{ 522*333d2b36SAndroid Build Coastguard Worker ReexportHeaderLibHeaders: linker.properties.Export_header_libs, 523*333d2b36SAndroid Build Coastguard Worker HeaderLibs: linker.properties.Export_header_libs, 524*333d2b36SAndroid Build Coastguard Worker } 525*333d2b36SAndroid Build Coastguard Worker} 526*333d2b36SAndroid Build Coastguard Worker 527*333d2b36SAndroid Build Coastguard Workerfunc (linker *stubDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { 528*333d2b36SAndroid Build Coastguard Worker linker.libraryDecorator.moduleInfoJSON(ctx, moduleInfoJSON) 529*333d2b36SAndroid Build Coastguard Worker // Overwrites the SubName computed by libraryDecorator 530*333d2b36SAndroid Build Coastguard Worker moduleInfoJSON.SubName = ndkLibrarySuffix + "." + linker.apiLevel.String() 531*333d2b36SAndroid Build Coastguard Worker} 532*333d2b36SAndroid Build Coastguard Worker 533*333d2b36SAndroid Build Coastguard Workerfunc (linker *stubDecorator) Name(name string) string { 534*333d2b36SAndroid Build Coastguard Worker return name + ndkLibrarySuffix 535*333d2b36SAndroid Build Coastguard Worker} 536*333d2b36SAndroid Build Coastguard Worker 537*333d2b36SAndroid Build Coastguard Workerfunc (stub *stubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 538*333d2b36SAndroid Build Coastguard Worker stub.libraryDecorator.libName = ctx.baseModuleName() 539*333d2b36SAndroid Build Coastguard Worker return stub.libraryDecorator.linkerFlags(ctx, flags) 540*333d2b36SAndroid Build Coastguard Worker} 541*333d2b36SAndroid Build Coastguard Worker 542*333d2b36SAndroid Build Coastguard Workerfunc (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, 543*333d2b36SAndroid Build Coastguard Worker objs Objects) android.Path { 544*333d2b36SAndroid Build Coastguard Worker 545*333d2b36SAndroid Build Coastguard Worker if !stub.buildStubs() { 546*333d2b36SAndroid Build Coastguard Worker // NDK libraries have no implementation variant, nothing to do 547*333d2b36SAndroid Build Coastguard Worker return nil 548*333d2b36SAndroid Build Coastguard Worker } 549*333d2b36SAndroid Build Coastguard Worker 550*333d2b36SAndroid Build Coastguard Worker if shouldUseVersionScript(ctx, stub) { 551*333d2b36SAndroid Build Coastguard Worker linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String() 552*333d2b36SAndroid Build Coastguard Worker flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag) 553*333d2b36SAndroid Build Coastguard Worker flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath) 554*333d2b36SAndroid Build Coastguard Worker } 555*333d2b36SAndroid Build Coastguard Worker 556*333d2b36SAndroid Build Coastguard Worker stub.libraryDecorator.skipAPIDefine = true 557*333d2b36SAndroid Build Coastguard Worker return stub.libraryDecorator.link(ctx, flags, deps, objs) 558*333d2b36SAndroid Build Coastguard Worker} 559*333d2b36SAndroid Build Coastguard Worker 560*333d2b36SAndroid Build Coastguard Workerfunc (stub *stubDecorator) nativeCoverage() bool { 561*333d2b36SAndroid Build Coastguard Worker return false 562*333d2b36SAndroid Build Coastguard Worker} 563*333d2b36SAndroid Build Coastguard Worker 564*333d2b36SAndroid Build Coastguard Worker// Returns the install path for unversioned NDK libraries (currently only static 565*333d2b36SAndroid Build Coastguard Worker// libraries). 566*333d2b36SAndroid Build Coastguard Workerfunc getUnversionedLibraryInstallPath(ctx ModuleContext) android.OutputPath { 567*333d2b36SAndroid Build Coastguard Worker return getNdkSysrootBase(ctx).Join(ctx, "usr/lib", config.NDKTriple(ctx.toolchain())) 568*333d2b36SAndroid Build Coastguard Worker} 569*333d2b36SAndroid Build Coastguard Worker 570*333d2b36SAndroid Build Coastguard Worker// Returns the install path for versioned NDK libraries. These are most often 571*333d2b36SAndroid Build Coastguard Worker// stubs, but the same paths are used for CRT objects. 572*333d2b36SAndroid Build Coastguard Workerfunc getVersionedLibraryInstallPath(ctx ModuleContext, apiLevel android.ApiLevel) android.OutputPath { 573*333d2b36SAndroid Build Coastguard Worker return getUnversionedLibraryInstallPath(ctx).Join(ctx, apiLevel.String()) 574*333d2b36SAndroid Build Coastguard Worker} 575*333d2b36SAndroid Build Coastguard Worker 576*333d2b36SAndroid Build Coastguard Workerfunc (stub *stubDecorator) install(ctx ModuleContext, path android.Path) { 577*333d2b36SAndroid Build Coastguard Worker installDir := getVersionedLibraryInstallPath(ctx, stub.apiLevel) 578*333d2b36SAndroid Build Coastguard Worker out := installDir.Join(ctx, path.Base()) 579*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 580*333d2b36SAndroid Build Coastguard Worker Rule: android.Cp, 581*333d2b36SAndroid Build Coastguard Worker Input: path, 582*333d2b36SAndroid Build Coastguard Worker Output: out, 583*333d2b36SAndroid Build Coastguard Worker }) 584*333d2b36SAndroid Build Coastguard Worker stub.installPath = out 585*333d2b36SAndroid Build Coastguard Worker} 586*333d2b36SAndroid Build Coastguard Worker 587*333d2b36SAndroid Build Coastguard Workerfunc newStubLibrary() *Module { 588*333d2b36SAndroid Build Coastguard Worker module, library := NewLibrary(android.DeviceSupported) 589*333d2b36SAndroid Build Coastguard Worker library.BuildOnlyShared() 590*333d2b36SAndroid Build Coastguard Worker module.stl = nil 591*333d2b36SAndroid Build Coastguard Worker module.sanitize = nil 592*333d2b36SAndroid Build Coastguard Worker library.disableStripping() 593*333d2b36SAndroid Build Coastguard Worker 594*333d2b36SAndroid Build Coastguard Worker stub := &stubDecorator{ 595*333d2b36SAndroid Build Coastguard Worker libraryDecorator: library, 596*333d2b36SAndroid Build Coastguard Worker } 597*333d2b36SAndroid Build Coastguard Worker module.compiler = stub 598*333d2b36SAndroid Build Coastguard Worker module.linker = stub 599*333d2b36SAndroid Build Coastguard Worker module.installer = stub 600*333d2b36SAndroid Build Coastguard Worker module.library = stub 601*333d2b36SAndroid Build Coastguard Worker 602*333d2b36SAndroid Build Coastguard Worker module.Properties.AlwaysSdk = true 603*333d2b36SAndroid Build Coastguard Worker module.Properties.Sdk_version = StringPtr("current") 604*333d2b36SAndroid Build Coastguard Worker 605*333d2b36SAndroid Build Coastguard Worker module.AddProperties(&stub.properties, &library.MutatedProperties) 606*333d2b36SAndroid Build Coastguard Worker 607*333d2b36SAndroid Build Coastguard Worker return module 608*333d2b36SAndroid Build Coastguard Worker} 609*333d2b36SAndroid Build Coastguard Worker 610*333d2b36SAndroid Build Coastguard Worker// ndk_library creates a library that exposes a stub implementation of functions 611*333d2b36SAndroid Build Coastguard Worker// and variables for use at build time only. 612*333d2b36SAndroid Build Coastguard Workerfunc NdkLibraryFactory() android.Module { 613*333d2b36SAndroid Build Coastguard Worker module := newStubLibrary() 614*333d2b36SAndroid Build Coastguard Worker android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth) 615*333d2b36SAndroid Build Coastguard Worker return module 616*333d2b36SAndroid Build Coastguard Worker} 617