xref: /aosp_15_r20/build/soong/cc/ndk_library.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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