1// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
18	"fmt"
19	"io"
20	"path/filepath"
21	"regexp"
22	"strconv"
23	"strings"
24	"sync"
25
26	"android/soong/android"
27
28	"github.com/google/blueprint"
29	"github.com/google/blueprint/pathtools"
30	"github.com/google/blueprint/proptools"
31)
32
33// LibraryProperties is a collection of properties shared by cc library rules/cc.
34type LibraryProperties struct {
35	// local file name to pass to the linker as -unexported_symbols_list
36	Unexported_symbols_list *string `android:"path,arch_variant"`
37	// local file name to pass to the linker as -force_symbols_not_weak_list
38	Force_symbols_not_weak_list *string `android:"path,arch_variant"`
39	// local file name to pass to the linker as -force_symbols_weak_list
40	Force_symbols_weak_list *string `android:"path,arch_variant"`
41
42	// rename host libraries to prevent overlap with system installed libraries
43	Unique_host_soname *bool
44
45	Aidl struct {
46		// export headers generated from .aidl sources
47		Export_aidl_headers *bool
48	}
49
50	Proto struct {
51		// export headers generated from .proto sources
52		Export_proto_headers *bool
53	}
54
55	Sysprop struct {
56		// Whether platform owns this sysprop library.
57		Platform *bool
58	} `blueprint:"mutated"`
59
60	Static_ndk_lib *bool
61
62	// Generate stubs to make this library accessible to APEXes.
63	Stubs struct {
64		// Relative path to the symbol map. The symbol map provides the list of
65		// symbols that are exported for stubs variant of this library.
66		Symbol_file *string `android:"path"`
67
68		// List versions to generate stubs libs for. The version name "current" is always
69		// implicitly added.
70		Versions []string
71
72		// Whether to not require the implementation of the library to be installed if a
73		// client of the stubs is installed. Defaults to true; set to false if the
74		// implementation is made available by some other means, e.g. in a Microdroid
75		// virtual machine.
76		Implementation_installable *bool
77	}
78
79	// set the name of the output
80	Stem *string `android:"arch_variant"`
81
82	// set suffix of the name of the output
83	Suffix *string `android:"arch_variant"`
84
85	// Properties for ABI compatibility checker.
86	Header_abi_checker headerAbiCheckerProperties
87
88	Target struct {
89		Vendor, Product struct {
90			// set suffix of the name of the output
91			Suffix *string `android:"arch_variant"`
92
93			Header_abi_checker headerAbiCheckerProperties
94
95			// Disable stubs for vendor/product variants
96			// This is a workaround to keep `stubs` only for "core" variant (not product/vendor).
97			// It would be nice if we could put `stubs` into a `target: { core: {} }`
98			// block but it's not supported in soong yet. This could be removed/simplified once we have
99			// a better syntax.
100			No_stubs bool
101		}
102
103		Platform struct {
104			Header_abi_checker headerAbiCheckerProperties
105		}
106	}
107
108	// Names of modules to be overridden. Listed modules can only be other shared libraries
109	// (in Make or Soong).
110	// This does not completely prevent installation of the overridden libraries, but if both
111	// binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed
112	// from PRODUCT_PACKAGES.
113	Overrides []string
114
115	// Inject boringssl hash into the shared library.  This is only intended for use by external/boringssl.
116	Inject_bssl_hash *bool `android:"arch_variant"`
117
118	// If this is an LLNDK library, properties to describe the LLNDK stubs.  Will be copied from
119	// the module pointed to by llndk_stubs if it is set.
120	Llndk llndkLibraryProperties
121
122	// If this is a vendor public library, properties to describe the vendor public library stubs.
123	Vendor_public_library vendorPublicLibraryProperties
124}
125
126// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a
127// library module.
128type StaticProperties struct {
129	Static StaticOrSharedProperties `android:"arch_variant"`
130}
131
132// SharedProperties is a properties stanza to affect only attributes of the "shared" variants of a
133// library module.
134type SharedProperties struct {
135	Shared StaticOrSharedProperties `android:"arch_variant"`
136}
137
138// StaticOrSharedProperties is an embedded struct representing properties to affect attributes of
139// either only the "static" variants or only the "shared" variants of a library module. These override
140// the base properties of the same name.
141// Use `StaticProperties` or `SharedProperties`, depending on which variant is needed.
142// `StaticOrSharedProperties` exists only to avoid duplication.
143type StaticOrSharedProperties struct {
144	Srcs []string `android:"path,arch_variant"`
145
146	Tidy_disabled_srcs []string `android:"path,arch_variant"`
147
148	Tidy_timeout_srcs []string `android:"path,arch_variant"`
149
150	Sanitized Sanitized `android:"arch_variant"`
151
152	Cflags proptools.Configurable[[]string] `android:"arch_variant"`
153
154	Enabled            *bool    `android:"arch_variant"`
155	Whole_static_libs  []string `android:"arch_variant"`
156	Static_libs        []string `android:"arch_variant"`
157	Shared_libs        []string `android:"arch_variant"`
158	System_shared_libs []string `android:"arch_variant"`
159
160	Export_shared_lib_headers []string `android:"arch_variant"`
161	Export_static_lib_headers []string `android:"arch_variant"`
162
163	Apex_available []string `android:"arch_variant"`
164
165	Installable *bool `android:"arch_variant"`
166}
167
168type LibraryMutatedProperties struct {
169	// Build a static variant
170	BuildStatic bool `blueprint:"mutated"`
171	// Build a shared variant
172	BuildShared bool `blueprint:"mutated"`
173	// This variant is shared
174	VariantIsShared bool `blueprint:"mutated"`
175	// This variant is static
176	VariantIsStatic bool `blueprint:"mutated"`
177
178	// This variant is a stubs lib
179	BuildStubs bool `blueprint:"mutated"`
180	// This variant is the latest version
181	IsLatestVersion bool `blueprint:"mutated"`
182	// Version of the stubs lib
183	StubsVersion string `blueprint:"mutated"`
184	// List of all stubs versions associated with an implementation lib
185	AllStubsVersions []string `blueprint:"mutated"`
186}
187
188type FlagExporterProperties struct {
189	// list of directories relative to the Blueprints file that will
190	// be added to the include path (using -I) for this module and any module that links
191	// against this module.  Directories listed in export_include_dirs do not need to be
192	// listed in local_include_dirs.
193	Export_include_dirs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
194
195	// list of directories that will be added to the system include path
196	// using -isystem for this module and any module that links against this module.
197	Export_system_include_dirs []string `android:"arch_variant,variant_prepend"`
198
199	Target struct {
200		Vendor, Product struct {
201			// list of exported include directories, like
202			// export_include_dirs, that will be applied to
203			// vendor or product variant of this library.
204			// This will overwrite any other declarations.
205			Override_export_include_dirs []string
206		}
207	}
208}
209
210func init() {
211	RegisterLibraryBuildComponents(android.InitRegistrationContext)
212}
213
214func RegisterLibraryBuildComponents(ctx android.RegistrationContext) {
215	ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory)
216	ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory)
217	ctx.RegisterModuleType("cc_library", LibraryFactory)
218	ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory)
219	ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory)
220}
221
222// cc_library creates both static and/or shared libraries for a device and/or
223// host. By default, a cc_library has a single variant that targets the device.
224// Specifying `host_supported: true` also creates a library that targets the
225// host.
226func LibraryFactory() android.Module {
227	module, _ := NewLibrary(android.HostAndDeviceSupported)
228	// Can be used as both a static and a shared library.
229	module.sdkMemberTypes = []android.SdkMemberType{
230		sharedLibrarySdkMemberType,
231		staticLibrarySdkMemberType,
232		staticAndSharedLibrarySdkMemberType,
233	}
234	return module.Init()
235}
236
237// cc_library_static creates a static library for a device and/or host binary.
238func LibraryStaticFactory() android.Module {
239	module, library := NewLibrary(android.HostAndDeviceSupported)
240	library.BuildOnlyStatic()
241	module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
242	return module.Init()
243}
244
245// cc_library_shared creates a shared library for a device and/or host.
246func LibrarySharedFactory() android.Module {
247	module, library := NewLibrary(android.HostAndDeviceSupported)
248	library.BuildOnlyShared()
249	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
250	return module.Init()
251}
252
253// cc_library_host_static creates a static library that is linkable to a host
254// binary.
255func LibraryHostStaticFactory() android.Module {
256	module, library := NewLibrary(android.HostSupported)
257	library.BuildOnlyStatic()
258	module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
259	return module.Init()
260}
261
262// cc_library_host_shared creates a shared library that is usable on a host.
263func LibraryHostSharedFactory() android.Module {
264	module, library := NewLibrary(android.HostSupported)
265	library.BuildOnlyShared()
266	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
267	return module.Init()
268}
269
270// flagExporter is a separated portion of libraryDecorator pertaining to exported
271// include paths and flags. Keeping this dependency-related information separate
272// from the rest of library information is helpful in keeping data more structured
273// and explicit.
274type flagExporter struct {
275	Properties FlagExporterProperties
276
277	dirs         android.Paths // Include directories to be included with -I
278	systemDirs   android.Paths // System include directories to be included with -isystem
279	flags        []string      // Exported raw flags.
280	deps         android.Paths
281	headers      android.Paths
282	rustRlibDeps []RustRlibDep
283}
284
285// exportedIncludes returns the effective include paths for this module and
286// any module that links against this module. This is obtained from
287// the export_include_dirs property in the appropriate target stanza.
288func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
289	if ctx.inVendor() && f.Properties.Target.Vendor.Override_export_include_dirs != nil {
290		return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs)
291	}
292	if ctx.inProduct() && f.Properties.Target.Product.Override_export_include_dirs != nil {
293		return android.PathsForModuleSrc(ctx, f.Properties.Target.Product.Override_export_include_dirs)
294	}
295	return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs.GetOrDefault(ctx, nil))
296}
297
298func (f *flagExporter) exportedSystemIncludes(ctx ModuleContext) android.Paths {
299	return android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)
300}
301
302// exportIncludes registers the include directories and system include directories to be exported
303// transitively to modules depending on this module.
304func (f *flagExporter) exportIncludes(ctx ModuleContext) {
305	f.dirs = append(f.dirs, f.exportedIncludes(ctx)...)
306	f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
307}
308
309// exportIncludesAsSystem registers the include directories and system include directories to be
310// exported transitively both as system include directories to modules depending on this module.
311func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) {
312	// all dirs are force exported as system
313	f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...)
314	f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
315}
316
317// reexportDirs registers the given directories as include directories to be exported transitively
318// to modules depending on this module.
319func (f *flagExporter) reexportDirs(dirs ...android.Path) {
320	f.dirs = append(f.dirs, dirs...)
321}
322
323// reexportSystemDirs registers the given directories as system include directories
324// to be exported transitively to modules depending on this module.
325func (f *flagExporter) reexportSystemDirs(dirs ...android.Path) {
326	f.systemDirs = append(f.systemDirs, dirs...)
327}
328
329// reexportFlags registers the flags to be exported transitively to modules depending on this
330// module.
331func (f *flagExporter) reexportFlags(flags ...string) {
332	if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") {
333		panic(fmt.Errorf("Exporting invalid flag %q: "+
334			"use reexportDirs or reexportSystemDirs to export directories", flag))
335	}
336	f.flags = append(f.flags, flags...)
337}
338
339func (f *flagExporter) reexportDeps(deps ...android.Path) {
340	f.deps = append(f.deps, deps...)
341}
342
343func (f *flagExporter) reexportRustStaticDeps(deps ...RustRlibDep) {
344	f.rustRlibDeps = append(f.rustRlibDeps, deps...)
345}
346
347// addExportedGeneratedHeaders does nothing but collects generated header files.
348// This can be differ to exportedDeps which may contain phony files to minimize ninja.
349func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
350	f.headers = append(f.headers, headers...)
351}
352
353func (f *flagExporter) setProvider(ctx android.ModuleContext) {
354	android.SetProvider(ctx, FlagExporterInfoProvider, FlagExporterInfo{
355		// Comes from Export_include_dirs property, and those of exported transitive deps
356		IncludeDirs: android.FirstUniquePaths(f.dirs),
357		// Comes from Export_system_include_dirs property, and those of exported transitive deps
358		SystemIncludeDirs: android.FirstUniquePaths(f.systemDirs),
359		// Used in very few places as a one-off way of adding extra defines.
360		Flags: f.flags,
361		// Used sparingly, for extra files that need to be explicitly exported to dependers,
362		// or for phony files to minimize ninja.
363		Deps: f.deps,
364		// Used for exporting rlib deps of static libraries to dependents.
365		RustRlibDeps: f.rustRlibDeps,
366		// For exported generated headers, such as exported aidl headers, proto headers, or
367		// sysprop headers.
368		GeneratedHeaders: f.headers,
369	})
370}
371
372// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific
373// functionality: static vs. shared linkage, reusing object files for shared libraries
374type libraryDecorator struct {
375	Properties        LibraryProperties
376	StaticProperties  StaticProperties
377	SharedProperties  SharedProperties
378	MutatedProperties LibraryMutatedProperties
379
380	// For reusing static library objects for shared library
381	reuseObjects Objects
382
383	// table-of-contents file to optimize out relinking when possible
384	tocFile android.OptionalPath
385
386	flagExporter
387	flagExporterInfo *FlagExporterInfo
388	stripper         Stripper
389
390	// For whole_static_libs
391	objects                      Objects
392	wholeStaticLibsFromPrebuilts android.Paths
393
394	// Uses the module's name if empty, but can be overridden. Does not include
395	// shlib suffix.
396	libName string
397
398	sabi *sabi
399
400	// Output archive of gcno coverage information files
401	coverageOutputFile android.OptionalPath
402
403	// Source Abi Diff
404	sAbiDiff android.Paths
405
406	// Location of the static library in the sysroot. Empty if the library is
407	// not included in the NDK.
408	ndkSysrootPath android.Path
409
410	// Location of the linked, unstripped library for shared libraries
411	unstrippedOutputFile android.Path
412	// Location of the linked, stripped library for shared libraries, strip: "all"
413	strippedAllOutputFile android.Path
414
415	// Location of the file that should be copied to dist dir when requested
416	distFile android.Path
417
418	versionScriptPath android.OptionalPath
419
420	postInstallCmds []string
421
422	skipAPIDefine bool
423
424	// Decorated interfaces
425	*baseCompiler
426	*baseLinker
427	*baseInstaller
428
429	apiListCoverageXmlPath android.ModuleOutPath
430}
431
432// linkerProps returns the list of properties structs relevant for this library. (For example, if
433// the library is cc_shared_library, then static-library properties are omitted.)
434func (library *libraryDecorator) linkerProps() []interface{} {
435	var props []interface{}
436	props = append(props, library.baseLinker.linkerProps()...)
437	props = append(props,
438		&library.Properties,
439		&library.MutatedProperties,
440		&library.flagExporter.Properties,
441		&library.stripper.StripProperties)
442
443	if library.MutatedProperties.BuildShared {
444		props = append(props, &library.SharedProperties)
445	}
446	if library.MutatedProperties.BuildStatic {
447		props = append(props, &library.StaticProperties)
448	}
449
450	return props
451}
452
453// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this
454// library, or that are implied by attributes of this library (such as whether this library is a
455// shared library).
456func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
457	flags = library.baseLinker.linkerFlags(ctx, flags)
458
459	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
460	// all code is position independent, and then those warnings get promoted to
461	// errors.
462	if !ctx.Windows() {
463		flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC")
464	}
465
466	if library.static() {
467		flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...)
468	} else if library.shared() {
469		flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)...)
470	}
471
472	if library.shared() {
473		libName := library.getLibName(ctx)
474		var f []string
475		if ctx.toolchain().Bionic() {
476			f = append(f,
477				"-nostdlib",
478				"-Wl,--gc-sections",
479			)
480		}
481
482		if ctx.Darwin() {
483			f = append(f,
484				"-dynamiclib",
485				"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
486			)
487			if ctx.Arch().ArchType == android.X86 {
488				f = append(f,
489					"-read_only_relocs suppress",
490				)
491			}
492		} else {
493			f = append(f, "-shared")
494			if !ctx.Windows() {
495				f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
496			}
497		}
498
499		flags.Global.LdFlags = append(flags.Global.LdFlags, f...)
500	}
501
502	return flags
503}
504
505// compilerFlags takes a Flags and augments it to contain compile flags from global values,
506// per-target values, module type values, per-module Blueprints properties, extra flags from
507// `flags`, and generated sources from `deps`.
508func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
509	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
510	if len(exportIncludeDirs) > 0 {
511		f := includeDirsToFlags(exportIncludeDirs)
512		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
513		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
514	}
515
516	flags = library.baseCompiler.compilerFlags(ctx, flags, deps)
517	if ctx.IsLlndk() {
518		// LLNDK libraries ignore most of the properties on the cc_library and use the
519		// LLNDK-specific properties instead.
520		// Wipe all the module-local properties, leaving only the global properties.
521		flags.Local = LocalOrGlobalFlags{}
522	}
523	if library.buildStubs() {
524		// Remove -include <file> when compiling stubs. Otherwise, the force included
525		// headers might cause conflicting types error with the symbols in the
526		// generated stubs source code. e.g.
527		// double acos(double); // in header
528		// void acos() {} // in the generated source code
529		removeInclude := func(flags []string) []string {
530			ret := flags[:0]
531			for _, f := range flags {
532				if strings.HasPrefix(f, "-include ") {
533					continue
534				}
535				ret = append(ret, f)
536			}
537			return ret
538		}
539		flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags)
540		flags.Local.CFlags = removeInclude(flags.Local.CFlags)
541
542		flags = addStubLibraryCompilerFlags(flags)
543	}
544	return flags
545}
546
547func (library *libraryDecorator) getHeaderAbiCheckerProperties(ctx android.BaseModuleContext) headerAbiCheckerProperties {
548	m := ctx.Module().(*Module)
549	variantProps := &library.Properties.Target.Platform.Header_abi_checker
550	if m.InVendor() {
551		variantProps = &library.Properties.Target.Vendor.Header_abi_checker
552	} else if m.InProduct() {
553		variantProps = &library.Properties.Target.Product.Header_abi_checker
554	}
555	props := library.Properties.Header_abi_checker
556	err := proptools.AppendProperties(&props, variantProps, nil)
557	if err != nil {
558		ctx.ModuleErrorf("Cannot merge headerAbiCheckerProperties: %s", err.Error())
559	}
560	return props
561}
562
563func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
564	if ctx.IsLlndk() {
565		vendorApiLevel := ctx.Config().VendorApiLevel()
566		if vendorApiLevel == "" {
567			// TODO(b/321892570): Some tests relying on old fixtures which
568			// doesn't set vendorApiLevel. Needs to fix them.
569			vendorApiLevel = ctx.Config().PlatformSdkVersion().String()
570		}
571		// This is the vendor variant of an LLNDK library, build the LLNDK stubs.
572		nativeAbiResult := parseNativeAbiDefinition(ctx,
573			String(library.Properties.Llndk.Symbol_file),
574			android.ApiLevelOrPanic(ctx, vendorApiLevel), "--llndk")
575		objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
576		if !Bool(library.Properties.Llndk.Unversioned) {
577			library.versionScriptPath = android.OptionalPathForPath(
578				nativeAbiResult.versionScript)
579		}
580		return objs
581	}
582	if ctx.IsVendorPublicLibrary() {
583		nativeAbiResult := parseNativeAbiDefinition(ctx,
584			String(library.Properties.Vendor_public_library.Symbol_file),
585			android.FutureApiLevel, "")
586		objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
587		if !Bool(library.Properties.Vendor_public_library.Unversioned) {
588			library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.versionScript)
589		}
590		return objs
591	}
592	if library.buildStubs() {
593		symbolFile := String(library.Properties.Stubs.Symbol_file)
594		if symbolFile != "" && !strings.HasSuffix(symbolFile, ".map.txt") {
595			ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
596			return Objects{}
597		}
598		// b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
599		// systemapi, respectively. The former is for symbols defined in platform libraries
600		// and the latter is for symbols defined in APEXes.
601		// A single library can contain either # apex or # systemapi, but not both.
602		// The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
603		// However, having this distinction helps guard accidental
604		// promotion or demotion of API and also helps the API review process b/191371676
605		var flag string
606		if ctx.Module().(android.ApexModule).NotInPlatform() {
607			flag = "--apex"
608		} else {
609			flag = "--systemapi"
610		}
611		// b/184712170, unless the lib is an NDK library, exclude all public symbols from
612		// the stub so that it is mandated that all symbols are explicitly marked with
613		// either apex or systemapi.
614		if !ctx.Module().(*Module).IsNdk(ctx.Config()) {
615			flag = flag + " --no-ndk"
616		}
617		nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
618			android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
619		objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
620		library.versionScriptPath = android.OptionalPathForPath(
621			nativeAbiResult.versionScript)
622
623		// Parse symbol file to get API list for coverage
624		if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
625			library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
626		}
627
628		return objs
629	}
630
631	if !library.buildShared() && !library.buildStatic() {
632		if len(library.baseCompiler.Properties.Srcs) > 0 {
633			ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs")
634		}
635		if len(library.StaticProperties.Static.Srcs) > 0 {
636			ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs")
637		}
638		if len(library.SharedProperties.Shared.Srcs) > 0 {
639			ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs")
640		}
641		return Objects{}
642	}
643	if library.sabi.shouldCreateSourceAbiDump() {
644		dirs := library.exportedIncludeDirsForAbiCheck(ctx)
645		flags.SAbiFlags = make([]string, 0, len(dirs))
646		for _, dir := range dirs {
647			flags.SAbiFlags = append(flags.SAbiFlags, "-I"+dir)
648		}
649		totalLength := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) +
650			len(library.SharedProperties.Shared.Srcs) + len(library.StaticProperties.Static.Srcs)
651		if totalLength > 0 {
652			flags.SAbiDump = true
653		}
654	}
655	objs := library.baseCompiler.compile(ctx, flags, deps)
656	library.reuseObjects = objs
657	buildFlags := flagsToBuilderFlags(flags)
658
659	if library.static() {
660		srcs := android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Srcs)
661		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, srcs,
662			android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_disabled_srcs),
663			android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_timeout_srcs),
664			library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
665	} else if library.shared() {
666		srcs := android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Srcs)
667		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, srcs,
668			android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_disabled_srcs),
669			android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_timeout_srcs),
670			library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
671	}
672
673	return objs
674}
675
676type libraryInterface interface {
677	versionedInterface
678
679	static() bool
680	shared() bool
681	objs() Objects
682	reuseObjs() Objects
683	toc() android.OptionalPath
684
685	// Returns true if the build options for the module have selected a static or shared build
686	buildStatic() bool
687	buildShared() bool
688
689	// Sets whether a specific variant is static or shared
690	setStatic()
691	setShared()
692
693	// Gets the ABI properties for vendor, product, or platform variant
694	getHeaderAbiCheckerProperties(ctx android.BaseModuleContext) headerAbiCheckerProperties
695
696	// Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff
697	androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer)
698
699	availableFor(string) bool
700
701	getAPIListCoverageXMLPath() android.ModuleOutPath
702
703	installable() *bool
704}
705
706type versionedInterface interface {
707	buildStubs() bool
708	setBuildStubs(isLatest bool)
709	hasStubsVariants() bool
710	isStubsImplementationRequired() bool
711	setStubsVersion(string)
712	stubsVersion() string
713
714	stubsVersions(ctx android.BaseMutatorContext) []string
715	setAllStubsVersions([]string)
716	allStubsVersions() []string
717
718	implementationModuleName(name string) string
719	hasLLNDKStubs() bool
720	hasLLNDKHeaders() bool
721	hasVendorPublicLibrary() bool
722}
723
724var _ libraryInterface = (*libraryDecorator)(nil)
725var _ versionedInterface = (*libraryDecorator)(nil)
726
727func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendor bool, inProduct bool) string {
728	name := library.libName
729	if name == "" {
730		name = String(library.Properties.Stem)
731		if name == "" {
732			name = baseModuleName
733		}
734	}
735
736	suffix := ""
737	if inVendor {
738		suffix = String(library.Properties.Target.Vendor.Suffix)
739	} else if inProduct {
740		suffix = String(library.Properties.Target.Product.Suffix)
741	}
742	if suffix == "" {
743		suffix = String(library.Properties.Suffix)
744	}
745
746	return name + suffix
747}
748
749// getLibName returns the actual canonical name of the library (the name which
750// should be passed to the linker via linker flags).
751func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string {
752	name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct())
753
754	if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
755		if !strings.HasSuffix(name, "-host") {
756			name = name + "-host"
757		}
758	}
759
760	return name
761}
762
763var versioningMacroNamesListMutex sync.Mutex
764
765func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
766	location := InstallInSystem
767	if library.baseLinker.sanitize.inSanitizerDir() {
768		location = InstallInSanitizerDir
769	}
770	library.baseInstaller.location = location
771	library.baseLinker.linkerInit(ctx)
772	// Let baseLinker know whether this variant is for stubs or not, so that
773	// it can omit things that are not required for linking stubs.
774	library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs()
775
776	if library.buildStubs() {
777		macroNames := versioningMacroNamesList(ctx.Config())
778		myName := versioningMacroName(ctx.ModuleName())
779		versioningMacroNamesListMutex.Lock()
780		defer versioningMacroNamesListMutex.Unlock()
781		if (*macroNames)[myName] == "" {
782			(*macroNames)[myName] = ctx.ModuleName()
783		} else if (*macroNames)[myName] != ctx.ModuleName() {
784			ctx.ModuleErrorf("Macro name %q for versioning conflicts with macro name from module %q ", myName, (*macroNames)[myName])
785		}
786	}
787}
788
789func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
790	if ctx.IsLlndk() {
791		// LLNDK libraries ignore most of the properties on the cc_library and use the
792		// LLNDK-specific properties instead.
793		return deps
794	}
795
796	deps = library.baseCompiler.compilerDeps(ctx, deps)
797
798	return deps
799}
800
801func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
802	if ctx.IsLlndk() {
803		// LLNDK libraries ignore most of the properties on the cc_library and use the
804		// LLNDK-specific properties instead.
805		deps.HeaderLibs = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
806		deps.ReexportHeaderLibHeaders = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
807		return deps
808	}
809	if ctx.IsVendorPublicLibrary() {
810		headers := library.Properties.Vendor_public_library.Export_public_headers
811		deps.HeaderLibs = append([]string(nil), headers...)
812		deps.ReexportHeaderLibHeaders = append([]string(nil), headers...)
813		return deps
814	}
815
816	if library.static() {
817		// Compare with nil because an empty list needs to be propagated.
818		if library.StaticProperties.Static.System_shared_libs != nil {
819			library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs
820		}
821	} else if library.shared() {
822		// Compare with nil because an empty list needs to be propagated.
823		if library.SharedProperties.Shared.System_shared_libs != nil {
824			library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs
825		}
826	}
827
828	deps = library.baseLinker.linkerDeps(ctx, deps)
829
830	if library.static() {
831		deps.WholeStaticLibs = append(deps.WholeStaticLibs,
832			library.StaticProperties.Static.Whole_static_libs...)
833		deps.StaticLibs = append(deps.StaticLibs, library.StaticProperties.Static.Static_libs...)
834		deps.SharedLibs = append(deps.SharedLibs, library.StaticProperties.Static.Shared_libs...)
835
836		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...)
837		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...)
838	} else if library.shared() {
839		if library.baseLinker.Properties.crt() {
840			deps.CrtBegin = append(deps.CrtBegin, ctx.toolchain().CrtBeginSharedLibrary()...)
841			deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtEndSharedLibrary()...)
842
843		}
844		if library.baseLinker.Properties.crtPadSegment() {
845			deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtPadSegmentSharedLibrary()...)
846		}
847		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs...)
848		deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs...)
849		deps.SharedLibs = append(deps.SharedLibs, library.SharedProperties.Shared.Shared_libs...)
850
851		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...)
852		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...)
853
854		deps.LlndkHeaderLibs = append(deps.LlndkHeaderLibs, library.Properties.Llndk.Export_llndk_headers...)
855	}
856	if ctx.inVendor() {
857		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
858		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
859		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
860		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
861		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
862	}
863	if ctx.inProduct() {
864		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
865		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Product.Exclude_shared_libs)
866		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
867		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_shared_libs)
868		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
869	}
870	if ctx.inRecovery() {
871		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
872		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs)
873		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
874		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs)
875		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
876	}
877	if ctx.inRamdisk() {
878		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
879		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs)
880		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
881		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs)
882		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
883	}
884	if ctx.inVendorRamdisk() {
885		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
886		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
887		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
888		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
889		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
890	}
891
892	return deps
893}
894
895func (library *libraryDecorator) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps {
896	specifiedDeps = library.baseLinker.linkerSpecifiedDeps(specifiedDeps)
897	var properties StaticOrSharedProperties
898	if library.static() {
899		properties = library.StaticProperties.Static
900	} else if library.shared() {
901		properties = library.SharedProperties.Shared
902	}
903
904	specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs...)
905
906	// Must distinguish nil and [] in system_shared_libs - ensure that [] in
907	// either input list doesn't come out as nil.
908	if specifiedDeps.systemSharedLibs == nil {
909		specifiedDeps.systemSharedLibs = properties.System_shared_libs
910	} else {
911		specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...)
912	}
913
914	specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs)
915	if len(specifiedDeps.systemSharedLibs) > 0 {
916		// Skip this if systemSharedLibs is either nil or [], to ensure they are
917		// retained.
918		specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs)
919	}
920	return specifiedDeps
921}
922
923func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
924	if library.static() {
925		moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
926		moduleInfoJSON.Uninstallable = true
927	} else if library.shared() {
928		moduleInfoJSON.Class = []string{"SHARED_LIBRARIES"}
929	} else if library.header() {
930		moduleInfoJSON.Class = []string{"HEADER_LIBRARIES"}
931		moduleInfoJSON.Uninstallable = true
932	}
933
934	if library.buildStubs() && library.stubsVersion() != "" {
935		moduleInfoJSON.SubName += "." + library.stubsVersion()
936	}
937
938	// If a library providing a stub is included in an APEX, the private APIs of the library
939	// is accessible only inside the APEX. From outside of the APEX, clients can only use the
940	// public APIs via the stub. To enforce this, the (latest version of the) stub gets the
941	// name of the library. The impl library instead gets the `.bootstrap` suffix to so that
942	// they can be exceptionally used directly when APEXes are not available (e.g. during the
943	// very early stage in the boot process).
944	if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.notInPlatform() &&
945		!ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && !ctx.useVndk() && !ctx.static() {
946		if library.buildStubs() && library.isLatestStubVersion() {
947			moduleInfoJSON.SubName = ""
948		}
949		if !library.buildStubs() {
950			moduleInfoJSON.SubName = ".bootstrap"
951		}
952	}
953
954	library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
955}
956
957func (library *libraryDecorator) linkStatic(ctx ModuleContext,
958	flags Flags, deps PathDeps, objs Objects) android.Path {
959
960	library.objects = deps.WholeStaticLibObjs.Copy()
961	library.objects = library.objects.Append(objs)
962	library.wholeStaticLibsFromPrebuilts = android.CopyOfPaths(deps.WholeStaticLibsFromPrebuilts)
963
964	fileName := ctx.ModuleName() + staticLibraryExtension
965	outputFile := android.PathForModuleOut(ctx, fileName)
966	builderFlags := flagsToBuilderFlags(flags)
967
968	if Bool(library.baseLinker.Properties.Use_version_lib) {
969		if ctx.Host() {
970			versionedOutputFile := outputFile
971			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
972			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
973		} else {
974			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
975			library.distFile = versionedOutputFile
976			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
977		}
978	}
979
980	transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, nil, objs.tidyDepFiles)
981
982	library.coverageOutputFile = transformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName())
983
984	ctx.CheckbuildFile(outputFile)
985
986	if library.static() {
987		android.SetProvider(ctx, StaticLibraryInfoProvider, StaticLibraryInfo{
988			StaticLibrary:                outputFile,
989			ReuseObjects:                 library.reuseObjects,
990			Objects:                      library.objects,
991			WholeStaticLibsFromPrebuilts: library.wholeStaticLibsFromPrebuilts,
992
993			TransitiveStaticLibrariesForOrdering: android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
994				Direct(outputFile).
995				Transitive(deps.TranstiveStaticLibrariesForOrdering).
996				Build(),
997		})
998	}
999
1000	if library.header() {
1001		android.SetProvider(ctx, HeaderLibraryInfoProvider, HeaderLibraryInfo{})
1002	}
1003
1004	return outputFile
1005}
1006
1007func ndkSharedLibDeps(ctx ModuleContext) android.Paths {
1008	if ctx.Module().(*Module).IsSdkVariant() {
1009		// The NDK sysroot timestamp file depends on all the NDK
1010		// sysroot header and shared library files.
1011		return android.Paths{getNdkBaseTimestampFile(ctx)}
1012	}
1013	return nil
1014}
1015
1016func (library *libraryDecorator) linkShared(ctx ModuleContext,
1017	flags Flags, deps PathDeps, objs Objects) android.Path {
1018
1019	var linkerDeps android.Paths
1020	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
1021	linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
1022
1023	unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list")
1024	forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list")
1025	forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list")
1026	if !ctx.Darwin() {
1027		if unexportedSymbols.Valid() {
1028			ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1029		}
1030		if forceNotWeakSymbols.Valid() {
1031			ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1032		}
1033		if forceWeakSymbols.Valid() {
1034			ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1035		}
1036	} else {
1037		if unexportedSymbols.Valid() {
1038			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
1039			linkerDeps = append(linkerDeps, unexportedSymbols.Path())
1040		}
1041		if forceNotWeakSymbols.Valid() {
1042			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
1043			linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
1044		}
1045		if forceWeakSymbols.Valid() {
1046			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
1047			linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
1048		}
1049	}
1050	if library.versionScriptPath.Valid() {
1051		linkerScriptFlags := "-Wl,--version-script," + library.versionScriptPath.String()
1052		flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlags)
1053		linkerDeps = append(linkerDeps, library.versionScriptPath.Path())
1054	}
1055
1056	fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
1057	outputFile := android.PathForModuleOut(ctx, fileName)
1058	unstrippedOutputFile := outputFile
1059
1060	var implicitOutputs android.WritablePaths
1061	if ctx.Windows() {
1062		importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib"))
1063
1064		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--out-implib="+importLibraryPath.String())
1065		implicitOutputs = append(implicitOutputs, importLibraryPath)
1066	}
1067
1068	builderFlags := flagsToBuilderFlags(flags)
1069
1070	if ctx.Darwin() && deps.DarwinSecondArchOutput.Valid() {
1071		fatOutputFile := outputFile
1072		outputFile = android.PathForModuleOut(ctx, "pre-fat", fileName)
1073		transformDarwinUniversalBinary(ctx, fatOutputFile, outputFile, deps.DarwinSecondArchOutput.Path())
1074	}
1075
1076	// Optimize out relinking against shared libraries whose interface hasn't changed by
1077	// depending on a table of contents file instead of the library itself.
1078	tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc")
1079	library.tocFile = android.OptionalPathForPath(tocFile)
1080	TransformSharedObjectToToc(ctx, outputFile, tocFile)
1081
1082	stripFlags := flagsToStripFlags(flags)
1083	needsStrip := library.stripper.NeedsStrip(ctx)
1084	if library.buildStubs() {
1085		// No need to strip stubs libraries
1086		needsStrip = false
1087	}
1088	if needsStrip {
1089		if ctx.Darwin() {
1090			stripFlags.StripUseGnuStrip = true
1091		}
1092		strippedOutputFile := outputFile
1093		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
1094		library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags)
1095	}
1096	library.unstrippedOutputFile = outputFile
1097
1098	outputFile = maybeInjectBoringSSLHash(ctx, outputFile, library.Properties.Inject_bssl_hash, fileName)
1099
1100	if Bool(library.baseLinker.Properties.Use_version_lib) {
1101		if ctx.Host() {
1102			versionedOutputFile := outputFile
1103			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
1104			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
1105		} else {
1106			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
1107			library.distFile = versionedOutputFile
1108
1109			if library.stripper.NeedsStrip(ctx) {
1110				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
1111				library.distFile = out
1112				library.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
1113			}
1114
1115			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
1116		}
1117	}
1118
1119	// Generate an output file for dist as if strip: "all" is set on the module.
1120	// Currently this is for layoutlib release process only.
1121	for _, dist := range ctx.Module().(*Module).Dists() {
1122		if dist.Tag != nil && *dist.Tag == "stripped_all" {
1123			strippedAllOutputFile := android.PathForModuleOut(ctx, "stripped_all", fileName)
1124			transformStrip(ctx, outputFile, strippedAllOutputFile, StripFlags{Toolchain: flags.Toolchain})
1125			library.strippedAllOutputFile = strippedAllOutputFile
1126			break
1127		}
1128	}
1129
1130	sharedLibs := deps.EarlySharedLibs
1131	sharedLibs = append(sharedLibs, deps.SharedLibs...)
1132	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1133
1134	linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
1135	linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
1136	linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
1137
1138	if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
1139		deps.StaticLibs = append(deps.StaticLibs, generatedLib)
1140	}
1141
1142	transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
1143		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin,
1144		deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles)
1145
1146	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
1147	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
1148	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...)
1149	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
1150
1151	library.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
1152	library.linkSAbiDumpFiles(ctx, deps, objs, fileName, unstrippedOutputFile)
1153
1154	var transitiveStaticLibrariesForOrdering *android.DepSet[android.Path]
1155	if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
1156		s, _ := android.OtherModuleProvider(ctx, static[0], StaticLibraryInfoProvider)
1157		transitiveStaticLibrariesForOrdering = s.TransitiveStaticLibrariesForOrdering
1158	}
1159
1160	android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
1161		TableOfContents:                      android.OptionalPathForPath(tocFile),
1162		SharedLibrary:                        unstrippedOutputFile,
1163		TransitiveStaticLibrariesForOrdering: transitiveStaticLibrariesForOrdering,
1164		Target:                               ctx.Target(),
1165	})
1166
1167	addStubDependencyProviders(ctx)
1168
1169	return unstrippedOutputFile
1170}
1171
1172func addStubDependencyProviders(ctx ModuleContext) {
1173	stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
1174	if len(stubs) > 0 {
1175		var stubsInfo []SharedStubLibrary
1176		for _, stub := range stubs {
1177			stubInfo, _ := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
1178			flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
1179			stubsInfo = append(stubsInfo, SharedStubLibrary{
1180				Version:           moduleLibraryInterface(stub).stubsVersion(),
1181				SharedLibraryInfo: stubInfo,
1182				FlagExporterInfo:  flagInfo,
1183			})
1184		}
1185		android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
1186			SharedStubLibraries: stubsInfo,
1187			IsLLNDK:             ctx.IsLlndk(),
1188		})
1189	}
1190}
1191
1192func (library *libraryDecorator) unstrippedOutputFilePath() android.Path {
1193	return library.unstrippedOutputFile
1194}
1195
1196func (library *libraryDecorator) strippedAllOutputFilePath() android.Path {
1197	return library.strippedAllOutputFile
1198}
1199
1200func (library *libraryDecorator) disableStripping() {
1201	library.stripper.StripProperties.Strip.None = BoolPtr(true)
1202}
1203
1204func (library *libraryDecorator) nativeCoverage() bool {
1205	if library.header() || library.buildStubs() {
1206		return false
1207	}
1208	return true
1209}
1210
1211func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath {
1212	return library.coverageOutputFile
1213}
1214
1215func (library *libraryDecorator) exportedIncludeDirsForAbiCheck(ctx ModuleContext) []string {
1216	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx).Strings()
1217	exportIncludeDirs = append(exportIncludeDirs, library.sabi.Properties.ReexportedIncludes...)
1218	exportSystemIncludeDirs := library.flagExporter.exportedSystemIncludes(ctx).Strings()
1219	exportSystemIncludeDirs = append(exportSystemIncludeDirs, library.sabi.Properties.ReexportedSystemIncludes...)
1220	// The ABI checker does not distinguish normal and system headers.
1221	return append(exportIncludeDirs, exportSystemIncludeDirs...)
1222}
1223
1224func (library *libraryDecorator) llndkIncludeDirsForAbiCheck(ctx ModuleContext, deps PathDeps) []string {
1225	var includeDirs, systemIncludeDirs []string
1226
1227	// The ABI checker does not need the preprocess which adds macro guards to function declarations.
1228	preprocessedDirs := android.PathsForModuleSrc(ctx, library.Properties.Llndk.Export_preprocessed_headers).Strings()
1229	if Bool(library.Properties.Llndk.Export_headers_as_system) {
1230		systemIncludeDirs = append(systemIncludeDirs, preprocessedDirs...)
1231	} else {
1232		includeDirs = append(includeDirs, preprocessedDirs...)
1233	}
1234
1235	if library.Properties.Llndk.Override_export_include_dirs != nil {
1236		includeDirs = append(includeDirs, android.PathsForModuleSrc(
1237			ctx, library.Properties.Llndk.Override_export_include_dirs).Strings()...)
1238	} else {
1239		includeDirs = append(includeDirs, library.flagExporter.exportedIncludes(ctx).Strings()...)
1240		// Ignore library.sabi.Properties.ReexportedIncludes because
1241		// LLNDK does not reexport the implementation's dependencies, such as export_header_libs.
1242	}
1243
1244	systemIncludeDirs = append(systemIncludeDirs,
1245		library.flagExporter.exportedSystemIncludes(ctx).Strings()...)
1246	if Bool(library.Properties.Llndk.Export_headers_as_system) {
1247		systemIncludeDirs = append(systemIncludeDirs, includeDirs...)
1248		includeDirs = nil
1249	}
1250	// Header libs.
1251	includeDirs = append(includeDirs, deps.LlndkIncludeDirs.Strings()...)
1252	systemIncludeDirs = append(systemIncludeDirs, deps.LlndkSystemIncludeDirs.Strings()...)
1253	// The ABI checker does not distinguish normal and system headers.
1254	return append(includeDirs, systemIncludeDirs...)
1255}
1256
1257func (library *libraryDecorator) linkLlndkSAbiDumpFiles(ctx ModuleContext,
1258	deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string,
1259	excludeSymbolVersions, excludeSymbolTags []string,
1260	vendorApiLevel string) android.Path {
1261	// NDK symbols in version 34 are LLNDK symbols. Those in version 35 are not.
1262	return transformDumpToLinkedDump(ctx,
1263		sAbiDumpFiles, soFile, libFileName+".llndk",
1264		library.llndkIncludeDirsForAbiCheck(ctx, deps),
1265		android.OptionalPathForModuleSrc(ctx, library.Properties.Llndk.Symbol_file),
1266		append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
1267		append([]string{"platform-only"}, excludeSymbolTags...),
1268		[]string{"llndk=" + vendorApiLevel}, "34", true /* isLlndk */)
1269}
1270
1271func (library *libraryDecorator) linkApexSAbiDumpFiles(ctx ModuleContext,
1272	deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string,
1273	excludeSymbolVersions, excludeSymbolTags []string,
1274	sdkVersion string) android.Path {
1275	return transformDumpToLinkedDump(ctx,
1276		sAbiDumpFiles, soFile, libFileName+".apex",
1277		library.exportedIncludeDirsForAbiCheck(ctx),
1278		android.OptionalPathForModuleSrc(ctx, library.Properties.Stubs.Symbol_file),
1279		append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
1280		append([]string{"platform-only"}, excludeSymbolTags...),
1281		[]string{"apex", "systemapi"}, sdkVersion, false /* isLlndk */)
1282}
1283
1284func getRefAbiDumpFile(ctx android.ModuleInstallPathContext,
1285	versionedDumpDir, fileName string) android.OptionalPath {
1286
1287	currentArchType := ctx.Arch().ArchType
1288	primaryArchType := ctx.Config().DevicePrimaryArchType()
1289	archName := currentArchType.String()
1290	if currentArchType != primaryArchType {
1291		archName += "_" + primaryArchType.String()
1292	}
1293
1294	return android.ExistentPathForSource(ctx, versionedDumpDir, archName, "source-based",
1295		fileName+".lsdump")
1296}
1297
1298// Return the previous and current SDK versions for cross-version ABI diff.
1299func crossVersionAbiDiffSdkVersions(ctx ModuleContext, dumpDir string) (int, int) {
1300	sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt()
1301
1302	if ctx.Config().PlatformSdkFinal() {
1303		return sdkVersionInt - 1, sdkVersionInt
1304	} else {
1305		// The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't
1306		// been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version.
1307		// This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory.
1308		versionedDumpDir := android.ExistentPathForSource(ctx,
1309			dumpDir, ctx.Config().PlatformSdkVersion().String())
1310		if versionedDumpDir.Valid() {
1311			return sdkVersionInt, sdkVersionInt + 1
1312		} else {
1313			return sdkVersionInt - 1, sdkVersionInt
1314		}
1315	}
1316}
1317
1318// Return the SDK version for same-version ABI diff.
1319func currRefAbiDumpSdkVersion(ctx ModuleContext) string {
1320	if ctx.Config().PlatformSdkFinal() {
1321		// After sdk finalization, the ABI of the latest API level must be consistent with the source code,
1322		// so choose PLATFORM_SDK_VERSION as the current version.
1323		return ctx.Config().PlatformSdkVersion().String()
1324	} else {
1325		return "current"
1326	}
1327}
1328
1329// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
1330func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext,
1331	sourceDump, referenceDump android.Path,
1332	baseName, nameExt string, isLlndk, allowExtensions bool,
1333	sourceVersion, errorMessage string) {
1334
1335	extraFlags := []string{"-target-version", sourceVersion}
1336	headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
1337	if Bool(headerAbiChecker.Check_all_apis) {
1338		extraFlags = append(extraFlags, "-check-all-apis")
1339	} else {
1340		extraFlags = append(extraFlags,
1341			"-allow-unreferenced-changes",
1342			"-allow-unreferenced-elf-symbol-changes")
1343	}
1344	if isLlndk {
1345		extraFlags = append(extraFlags, "-consider-opaque-types-different")
1346	}
1347	if allowExtensions {
1348		extraFlags = append(extraFlags, "-allow-extensions")
1349	}
1350	extraFlags = append(extraFlags, headerAbiChecker.Diff_flags...)
1351
1352	library.sAbiDiff = append(
1353		library.sAbiDiff,
1354		transformAbiDumpToAbiDiff(ctx, sourceDump, referenceDump,
1355			baseName, nameExt, extraFlags, errorMessage))
1356}
1357
1358func (library *libraryDecorator) crossVersionAbiDiff(ctx android.ModuleContext,
1359	sourceDump, referenceDump android.Path,
1360	baseName, nameExt string, isLlndk bool, sourceVersion, prevDumpDir string) {
1361
1362	errorMessage := "error: Please follow https://android.googlesource.com/platform/development/+/main/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the difference between your source code and the ABI dumps in " + prevDumpDir
1363
1364	library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
1365		isLlndk, true /* allowExtensions */, sourceVersion, errorMessage)
1366}
1367
1368func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext,
1369	sourceDump, referenceDump android.Path,
1370	baseName, nameExt string, isLlndk bool, lsdumpTagName string) {
1371
1372	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
1373	errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py --lib " + libName + " --lib-variant " + lsdumpTagName
1374
1375	targetRelease := ctx.Config().Getenv("TARGET_RELEASE")
1376	if targetRelease != "" {
1377		errorMessage += " --release " + targetRelease
1378	}
1379
1380	library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
1381		isLlndk, false /* allowExtensions */, "current", errorMessage)
1382}
1383
1384func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext,
1385	sourceDump, referenceDump android.Path,
1386	baseName, nameExt string, refDumpDir string, lsdumpTagName string) {
1387
1388	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
1389	errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py --lib " + libName + " --lib-variant " + lsdumpTagName + " --ref-dump-dir $$ANDROID_BUILD_TOP/" + refDumpDir
1390
1391	targetRelease := ctx.Config().Getenv("TARGET_RELEASE")
1392	if targetRelease != "" {
1393		errorMessage += " --release " + targetRelease
1394	}
1395
1396	// Most opt-in libraries do not have dumps for all default architectures.
1397	if ctx.Config().HasDeviceProduct() {
1398		errorMessage += " --product " + ctx.Config().DeviceProduct()
1399	}
1400
1401	library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
1402		false /* isLlndk */, false /* allowExtensions */, "current", errorMessage)
1403}
1404
1405func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, deps PathDeps, objs Objects, fileName string, soFile android.Path) {
1406	if library.sabi.shouldCreateSourceAbiDump() {
1407		exportedIncludeDirs := library.exportedIncludeDirsForAbiCheck(ctx)
1408		headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
1409		currSdkVersion := currRefAbiDumpSdkVersion(ctx)
1410		currVendorVersion := ctx.Config().VendorApiLevel()
1411
1412		// Generate source dumps.
1413		implDump := transformDumpToLinkedDump(ctx,
1414			objs.sAbiDumpFiles, soFile, fileName,
1415			exportedIncludeDirs,
1416			android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
1417			headerAbiChecker.Exclude_symbol_versions,
1418			headerAbiChecker.Exclude_symbol_tags,
1419			[]string{} /* includeSymbolTags */, currSdkVersion, false /* isLlndk */)
1420
1421		var llndkDump, apexVariantDump android.Path
1422		tags := classifySourceAbiDump(ctx)
1423		optInTags := []lsdumpTag{}
1424		for _, tag := range tags {
1425			if tag == llndkLsdumpTag && currVendorVersion != "" {
1426				if llndkDump == nil {
1427					// TODO(b/323447559): Evaluate if replacing sAbiDumpFiles with implDump is faster
1428					llndkDump = library.linkLlndkSAbiDumpFiles(ctx,
1429						deps, objs.sAbiDumpFiles, soFile, fileName,
1430						headerAbiChecker.Exclude_symbol_versions,
1431						headerAbiChecker.Exclude_symbol_tags,
1432						currVendorVersion)
1433				}
1434				addLsdumpPath(string(tag) + ":" + llndkDump.String())
1435			} else if tag == apexLsdumpTag {
1436				if apexVariantDump == nil {
1437					apexVariantDump = library.linkApexSAbiDumpFiles(ctx,
1438						deps, objs.sAbiDumpFiles, soFile, fileName,
1439						headerAbiChecker.Exclude_symbol_versions,
1440						headerAbiChecker.Exclude_symbol_tags,
1441						currSdkVersion)
1442				}
1443				addLsdumpPath(string(tag) + ":" + apexVariantDump.String())
1444			} else {
1445				if tag.dirName() == "" {
1446					optInTags = append(optInTags, tag)
1447				}
1448				addLsdumpPath(string(tag) + ":" + implDump.String())
1449			}
1450		}
1451
1452		// Diff source dumps and reference dumps.
1453		for _, tag := range tags {
1454			dumpDirName := tag.dirName()
1455			if dumpDirName == "" {
1456				continue
1457			}
1458			dumpDir := filepath.Join("prebuilts", "abi-dumps", dumpDirName)
1459			isLlndk := (tag == llndkLsdumpTag)
1460			isApex := (tag == apexLsdumpTag)
1461			binderBitness := ctx.DeviceConfig().BinderBitness()
1462			nameExt := ""
1463			if isLlndk {
1464				nameExt = "llndk"
1465			} else if isApex {
1466				nameExt = "apex"
1467			}
1468			// Check against the previous version.
1469			var prevVersion, currVersion string
1470			sourceDump := implDump
1471			// If this release config does not define VendorApiLevel, fall back to the old policy.
1472			if isLlndk && currVendorVersion != "" {
1473				prevVersion = ctx.Config().PrevVendorApiLevel()
1474				currVersion = currVendorVersion
1475				// LLNDK dumps are generated by different rules after trunk stable.
1476				if android.IsTrunkStableVendorApiLevel(prevVersion) {
1477					sourceDump = llndkDump
1478				}
1479			} else {
1480				prevVersionInt, currVersionInt := crossVersionAbiDiffSdkVersions(ctx, dumpDir)
1481				prevVersion = strconv.Itoa(prevVersionInt)
1482				currVersion = strconv.Itoa(currVersionInt)
1483				// APEX dumps are generated by different rules after trunk stable.
1484				if isApex && prevVersionInt > 34 {
1485					sourceDump = apexVariantDump
1486				}
1487			}
1488			prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness)
1489			prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName)
1490			if prevDumpFile.Valid() {
1491				library.crossVersionAbiDiff(ctx, sourceDump, prevDumpFile.Path(),
1492					fileName, nameExt+prevVersion, isLlndk, currVersion, prevDumpDir)
1493			}
1494			// Check against the current version.
1495			sourceDump = implDump
1496			if isLlndk && currVendorVersion != "" {
1497				currVersion = currVendorVersion
1498				if android.IsTrunkStableVendorApiLevel(currVersion) {
1499					sourceDump = llndkDump
1500				}
1501			} else {
1502				currVersion = currSdkVersion
1503				if isApex && (!ctx.Config().PlatformSdkFinal() ||
1504					ctx.Config().PlatformSdkVersion().FinalInt() > 34) {
1505					sourceDump = apexVariantDump
1506				}
1507			}
1508			currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness)
1509			currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName)
1510			if currDumpFile.Valid() {
1511				library.sameVersionAbiDiff(ctx, sourceDump, currDumpFile.Path(),
1512					fileName, nameExt, isLlndk, string(tag))
1513			}
1514		}
1515
1516		// Assert that a module is tagged with at most one of platformLsdumpTag, productLsdumpTag, or vendorLsdumpTag.
1517		if len(headerAbiChecker.Ref_dump_dirs) > 0 && len(optInTags) != 1 {
1518			ctx.ModuleErrorf("Expect exactly one opt-in lsdump tag when ref_dump_dirs are specified: %s", optInTags)
1519			return
1520		}
1521		// Ensure that a module tagged with only platformLsdumpTag has ref_dump_dirs.
1522		// Android.bp in vendor projects should be cleaned up before this is enforced for vendorLsdumpTag and productLsdumpTag.
1523		if len(headerAbiChecker.Ref_dump_dirs) == 0 && len(tags) == 1 && tags[0] == platformLsdumpTag {
1524			ctx.ModuleErrorf("header_abi_checker is explicitly enabled, but no ref_dump_dirs are specified.")
1525		}
1526		// Check against the opt-in reference dumps.
1527		for i, optInDumpDir := range headerAbiChecker.Ref_dump_dirs {
1528			optInDumpDirPath := android.PathForModuleSrc(ctx, optInDumpDir)
1529			// Ref_dump_dirs are not versioned.
1530			// They do not contain subdir for binder bitness because 64-bit binder has been mandatory.
1531			optInDumpFile := getRefAbiDumpFile(ctx, optInDumpDirPath.String(), fileName)
1532			if !optInDumpFile.Valid() {
1533				continue
1534			}
1535			library.optInAbiDiff(ctx,
1536				implDump, optInDumpFile.Path(),
1537				fileName, "opt"+strconv.Itoa(i), optInDumpDirPath.String(), string(optInTags[0]))
1538		}
1539	}
1540}
1541
1542func processLLNDKHeaders(ctx ModuleContext, srcHeaderDir string, outDir android.ModuleGenPath) (timestamp android.Path, installPaths android.WritablePaths) {
1543	srcDir := android.PathForModuleSrc(ctx, srcHeaderDir)
1544	srcFiles := ctx.GlobFiles(filepath.Join(srcDir.String(), "**/*.h"), nil)
1545
1546	for _, header := range srcFiles {
1547		headerDir := filepath.Dir(header.String())
1548		relHeaderDir, err := filepath.Rel(srcDir.String(), headerDir)
1549		if err != nil {
1550			ctx.ModuleErrorf("filepath.Rel(%q, %q) failed: %s",
1551				srcDir.String(), headerDir, err)
1552			continue
1553		}
1554
1555		installPaths = append(installPaths, outDir.Join(ctx, relHeaderDir, header.Base()))
1556	}
1557
1558	return processHeadersWithVersioner(ctx, srcDir, outDir, srcFiles, installPaths), installPaths
1559}
1560
1561// link registers actions to link this library, and sets various fields
1562// on this library to reflect information that should be exported up the build
1563// tree (for example, exported flags and include paths).
1564func (library *libraryDecorator) link(ctx ModuleContext,
1565	flags Flags, deps PathDeps, objs Objects) android.Path {
1566
1567	if ctx.IsLlndk() {
1568		if len(library.Properties.Llndk.Export_preprocessed_headers) > 0 {
1569			// This is the vendor variant of an LLNDK library with preprocessed headers.
1570			genHeaderOutDir := android.PathForModuleGen(ctx, "include")
1571
1572			var timestampFiles android.Paths
1573			for _, dir := range library.Properties.Llndk.Export_preprocessed_headers {
1574				timestampFile, installPaths := processLLNDKHeaders(ctx, dir, genHeaderOutDir)
1575				timestampFiles = append(timestampFiles, timestampFile)
1576				library.addExportedGeneratedHeaders(installPaths.Paths()...)
1577			}
1578
1579			if Bool(library.Properties.Llndk.Export_headers_as_system) {
1580				library.reexportSystemDirs(genHeaderOutDir)
1581			} else {
1582				library.reexportDirs(genHeaderOutDir)
1583			}
1584
1585			library.reexportDeps(timestampFiles...)
1586		}
1587
1588		// override the module's export_include_dirs with llndk.override_export_include_dirs
1589		// if it is set.
1590		if override := library.Properties.Llndk.Override_export_include_dirs; override != nil {
1591			library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](
1592				nil,
1593				[]proptools.ConfigurableCase[[]string]{
1594					proptools.NewConfigurableCase[[]string](nil, &override),
1595				},
1596			)
1597		}
1598
1599		if Bool(library.Properties.Llndk.Export_headers_as_system) {
1600			library.flagExporter.Properties.Export_system_include_dirs = append(
1601				library.flagExporter.Properties.Export_system_include_dirs,
1602				library.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil)...)
1603			library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](nil, nil)
1604		}
1605	}
1606
1607	if ctx.IsVendorPublicLibrary() {
1608		// override the module's export_include_dirs with vendor_public_library.override_export_include_dirs
1609		// if it is set.
1610		if override := library.Properties.Vendor_public_library.Override_export_include_dirs; override != nil {
1611			library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](
1612				nil,
1613				[]proptools.ConfigurableCase[[]string]{
1614					proptools.NewConfigurableCase[[]string](nil, &override),
1615				},
1616			)
1617		}
1618	}
1619
1620	// Linking this library consists of linking `deps.Objs` (.o files in dependencies
1621	// of this library), together with `objs` (.o files created by compiling this
1622	// library).
1623	objs = deps.Objs.Copy().Append(objs)
1624	var out android.Path
1625	if library.static() || library.header() {
1626		out = library.linkStatic(ctx, flags, deps, objs)
1627	} else {
1628		out = library.linkShared(ctx, flags, deps, objs)
1629	}
1630
1631	// Export include paths and flags to be propagated up the tree.
1632	library.exportIncludes(ctx)
1633	library.reexportDirs(deps.ReexportedDirs...)
1634	library.reexportSystemDirs(deps.ReexportedSystemDirs...)
1635	library.reexportFlags(deps.ReexportedFlags...)
1636	library.reexportDeps(deps.ReexportedDeps...)
1637	library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
1638
1639	if library.static() && len(deps.ReexportedRustRlibDeps) > 0 {
1640		library.reexportRustStaticDeps(deps.ReexportedRustRlibDeps...)
1641	}
1642
1643	// Optionally export aidl headers.
1644	if Bool(library.Properties.Aidl.Export_aidl_headers) {
1645		if library.baseCompiler.hasAidl(deps) {
1646			if library.baseCompiler.hasSrcExt(".aidl") {
1647				dir := android.PathForModuleGen(ctx, "aidl")
1648				library.reexportDirs(dir)
1649			}
1650			if len(deps.AidlLibraryInfos) > 0 {
1651				dir := android.PathForModuleGen(ctx, "aidl_library")
1652				library.reexportDirs(dir)
1653			}
1654
1655			library.reexportDeps(library.baseCompiler.aidlOrderOnlyDeps...)
1656			library.addExportedGeneratedHeaders(library.baseCompiler.aidlHeaders...)
1657		}
1658	}
1659
1660	// Optionally export proto headers.
1661	if Bool(library.Properties.Proto.Export_proto_headers) {
1662		if library.baseCompiler.hasSrcExt(".proto") {
1663			var includes android.Paths
1664			if flags.proto.CanonicalPathFromRoot {
1665				includes = append(includes, flags.proto.SubDir)
1666			}
1667			includes = append(includes, flags.proto.Dir)
1668			library.reexportDirs(includes...)
1669
1670			library.reexportDeps(library.baseCompiler.protoOrderOnlyDeps...)
1671			library.addExportedGeneratedHeaders(library.baseCompiler.protoHeaders...)
1672		}
1673	}
1674
1675	// If the library is sysprop_library, expose either public or internal header selectively.
1676	if library.baseCompiler.hasSrcExt(".sysprop") {
1677		dir := android.PathForModuleGen(ctx, "sysprop", "include")
1678		if library.Properties.Sysprop.Platform != nil {
1679			isOwnerPlatform := Bool(library.Properties.Sysprop.Platform)
1680
1681			// If the owner is different from the user, expose public header. That is,
1682			// 1) if the user is product (as owner can only be platform / vendor)
1683			// 2) if the owner is platform and the client is vendor
1684			// We don't care Platform -> Vendor dependency as it's already forbidden.
1685			if ctx.Device() && (ctx.ProductSpecific() || (isOwnerPlatform && ctx.inVendor())) {
1686				dir = android.PathForModuleGen(ctx, "sysprop/public", "include")
1687			}
1688		}
1689
1690		// Make sure to only export headers which are within the include directory.
1691		_, headers := android.FilterPathListPredicate(library.baseCompiler.syspropHeaders, func(path android.Path) bool {
1692			_, isRel := android.MaybeRel(ctx, dir.String(), path.String())
1693			return isRel
1694		})
1695
1696		// Add sysprop-related directories to the exported directories of this library.
1697		library.reexportDirs(dir)
1698		library.reexportDeps(library.baseCompiler.syspropOrderOnlyDeps...)
1699		library.addExportedGeneratedHeaders(headers...)
1700	}
1701
1702	// Add stub-related flags if this library is a stub library.
1703	library.exportVersioningMacroIfNeeded(ctx)
1704
1705	// Propagate a Provider containing information about exported flags, deps, and include paths.
1706	library.flagExporter.setProvider(ctx)
1707
1708	return out
1709}
1710
1711func (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) {
1712	if library.buildStubs() && library.stubsVersion() != "" && !library.skipAPIDefine {
1713		name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx))
1714		apiLevel, err := android.ApiLevelFromUser(ctx, library.stubsVersion())
1715		if err != nil {
1716			ctx.ModuleErrorf("Can't export version macro: %s", err.Error())
1717		}
1718		library.reexportFlags("-D" + name + "=" + strconv.Itoa(apiLevel.FinalOrPreviewInt()))
1719	}
1720}
1721
1722// buildStatic returns true if this library should be built as a static library.
1723func (library *libraryDecorator) buildStatic() bool {
1724	return library.MutatedProperties.BuildStatic &&
1725		BoolDefault(library.StaticProperties.Static.Enabled, true)
1726}
1727
1728// buildShared returns true if this library should be built as a shared library.
1729func (library *libraryDecorator) buildShared() bool {
1730	return library.MutatedProperties.BuildShared &&
1731		BoolDefault(library.SharedProperties.Shared.Enabled, true)
1732}
1733
1734func (library *libraryDecorator) objs() Objects {
1735	return library.objects
1736}
1737
1738func (library *libraryDecorator) reuseObjs() Objects {
1739	return library.reuseObjects
1740}
1741
1742func (library *libraryDecorator) toc() android.OptionalPath {
1743	return library.tocFile
1744}
1745
1746func (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
1747	dir := library.baseInstaller.installDir(ctx)
1748	dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir)
1749	// libc_hwasan has relative_install_dir set, which would mess up the dir.Base() logic.
1750	// hardcode here because it's the only target, if we have other targets that use this
1751	// we can generalise this.
1752	var target string
1753	if ctx.baseModuleName() == "libc_hwasan" {
1754		target = "/" + filepath.Join("apex", "com.android.runtime", "lib64", "bionic", "hwasan", file.Base())
1755	} else {
1756		base := dir.Base()
1757		target = "/" + filepath.Join("apex", "com.android.runtime", base, "bionic", file.Base())
1758	}
1759	ctx.InstallAbsoluteSymlink(dir, file.Base(), target)
1760	library.postInstallCmds = append(library.postInstallCmds, makeSymlinkCmd(dirOnDevice, file.Base(), target))
1761}
1762
1763func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
1764	if library.shared() {
1765		if library.hasStubsVariants() && !ctx.Host() && ctx.directlyInAnyApex() {
1766			// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
1767			// The original path becomes a symlink to the corresponding file in the
1768			// runtime APEX.
1769			translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
1770			if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() &&
1771				!translatedArch && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() {
1772				if ctx.Device() {
1773					library.installSymlinkToRuntimeApex(ctx, file)
1774				}
1775				library.baseInstaller.subDir = "bootstrap"
1776			}
1777		} else if ctx.directlyInAnyApex() && ctx.IsLlndk() && !isBionic(ctx.baseModuleName()) {
1778			// Skip installing LLNDK (non-bionic) libraries moved to APEX.
1779			ctx.Module().HideFromMake()
1780		}
1781
1782		library.baseInstaller.install(ctx, file)
1783	}
1784
1785	if Bool(library.Properties.Static_ndk_lib) && library.static() &&
1786		!ctx.InVendorOrProduct() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() &&
1787		library.baseLinker.sanitize.isUnsanitizedVariant() &&
1788		ctx.isForPlatform() && !ctx.isPreventInstall() {
1789		installPath := getUnversionedLibraryInstallPath(ctx).Join(ctx, file.Base())
1790
1791		ctx.ModuleBuild(pctx, android.ModuleBuildParams{
1792			Rule:        android.Cp,
1793			Description: "install " + installPath.Base(),
1794			Output:      installPath,
1795			Input:       file,
1796		})
1797
1798		library.ndkSysrootPath = installPath
1799	}
1800}
1801
1802func (library *libraryDecorator) everInstallable() bool {
1803	// Only shared and static libraries are installed. Header libraries (which are
1804	// neither static or shared) are not installed.
1805	return library.shared() || library.static()
1806}
1807
1808// static returns true if this library is for a "static' variant.
1809func (library *libraryDecorator) static() bool {
1810	return library.MutatedProperties.VariantIsStatic
1811}
1812
1813// shared returns true if this library is for a "shared' variant.
1814func (library *libraryDecorator) shared() bool {
1815	return library.MutatedProperties.VariantIsShared
1816}
1817
1818// header returns true if this library is for a header-only variant.
1819func (library *libraryDecorator) header() bool {
1820	// Neither "static" nor "shared" implies this library is header-only.
1821	return !library.static() && !library.shared()
1822}
1823
1824// setStatic marks the library variant as "static".
1825func (library *libraryDecorator) setStatic() {
1826	library.MutatedProperties.VariantIsStatic = true
1827	library.MutatedProperties.VariantIsShared = false
1828}
1829
1830// setShared marks the library variant as "shared".
1831func (library *libraryDecorator) setShared() {
1832	library.MutatedProperties.VariantIsStatic = false
1833	library.MutatedProperties.VariantIsShared = true
1834}
1835
1836// BuildOnlyStatic disables building this library as a shared library.
1837func (library *libraryDecorator) BuildOnlyStatic() {
1838	library.MutatedProperties.BuildShared = false
1839}
1840
1841// BuildOnlyShared disables building this library as a static library.
1842func (library *libraryDecorator) BuildOnlyShared() {
1843	library.MutatedProperties.BuildStatic = false
1844}
1845
1846// HeaderOnly disables building this library as a shared or static library;
1847// the library only exists to propagate header file dependencies up the build graph.
1848func (library *libraryDecorator) HeaderOnly() {
1849	library.MutatedProperties.BuildShared = false
1850	library.MutatedProperties.BuildStatic = false
1851}
1852
1853// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
1854func (library *libraryDecorator) hasLLNDKStubs() bool {
1855	return String(library.Properties.Llndk.Symbol_file) != ""
1856}
1857
1858// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
1859func (library *libraryDecorator) hasLLNDKHeaders() bool {
1860	return Bool(library.Properties.Llndk.Llndk_headers)
1861}
1862
1863// hasVendorPublicLibrary returns true if this cc_library module has a variant that will build
1864// vendor public library stubs.
1865func (library *libraryDecorator) hasVendorPublicLibrary() bool {
1866	return String(library.Properties.Vendor_public_library.Symbol_file) != ""
1867}
1868
1869func (library *libraryDecorator) implementationModuleName(name string) string {
1870	return name
1871}
1872
1873func (library *libraryDecorator) buildStubs() bool {
1874	return library.MutatedProperties.BuildStubs
1875}
1876
1877func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string {
1878	if props := library.getHeaderAbiCheckerProperties(ctx); props.Symbol_file != nil {
1879		return props.Symbol_file
1880	}
1881	if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
1882		return library.Properties.Stubs.Symbol_file
1883	}
1884	// TODO(b/309880485): Distinguish platform, NDK, LLNDK, and APEX version scripts.
1885	if library.baseLinker.Properties.Version_script != nil {
1886		return library.baseLinker.Properties.Version_script
1887	}
1888	return nil
1889}
1890
1891func (library *libraryDecorator) hasStubsVariants() bool {
1892	// Just having stubs.symbol_file is enough to create a stub variant. In that case
1893	// the stub for the future API level is created.
1894	return library.Properties.Stubs.Symbol_file != nil ||
1895		len(library.Properties.Stubs.Versions) > 0
1896}
1897
1898func (library *libraryDecorator) isStubsImplementationRequired() bool {
1899	return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
1900}
1901
1902func (library *libraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
1903	if !library.hasStubsVariants() {
1904		return nil
1905	}
1906
1907	if library.hasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() {
1908		// LLNDK libraries only need a single stubs variant (""), which is
1909		// added automatically in createVersionVariations().
1910		return nil
1911	}
1912
1913	// Future API level is implicitly added if there isn't
1914	versions := addCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
1915	normalizeVersions(ctx, versions)
1916	return versions
1917}
1918
1919func addCurrentVersionIfNotPresent(vers []string) []string {
1920	if inList(android.FutureApiLevel.String(), vers) {
1921		return vers
1922	}
1923	// In some cases, people use the raw value "10000" in the versions property.
1924	// We shouldn't add the future API level in that case, otherwise there will
1925	// be two identical versions.
1926	if inList(strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()), vers) {
1927		return vers
1928	}
1929	return append(vers, android.FutureApiLevel.String())
1930}
1931
1932func (library *libraryDecorator) setStubsVersion(version string) {
1933	library.MutatedProperties.StubsVersion = version
1934}
1935
1936func (library *libraryDecorator) stubsVersion() string {
1937	return library.MutatedProperties.StubsVersion
1938}
1939
1940func (library *libraryDecorator) setBuildStubs(isLatest bool) {
1941	library.MutatedProperties.BuildStubs = true
1942	library.MutatedProperties.IsLatestVersion = isLatest
1943}
1944
1945func (library *libraryDecorator) setAllStubsVersions(versions []string) {
1946	library.MutatedProperties.AllStubsVersions = versions
1947}
1948
1949func (library *libraryDecorator) allStubsVersions() []string {
1950	return library.MutatedProperties.AllStubsVersions
1951}
1952
1953func (library *libraryDecorator) isLatestStubVersion() bool {
1954	return library.MutatedProperties.IsLatestVersion
1955}
1956
1957func (library *libraryDecorator) availableFor(what string) bool {
1958	var list []string
1959	if library.static() {
1960		list = library.StaticProperties.Static.Apex_available
1961	} else if library.shared() {
1962		list = library.SharedProperties.Shared.Apex_available
1963	}
1964	if len(list) == 0 {
1965		return false
1966	}
1967	return android.CheckAvailableForApex(what, list)
1968}
1969
1970func (library *libraryDecorator) installable() *bool {
1971	if library.static() {
1972		return library.StaticProperties.Static.Installable
1973	} else if library.shared() {
1974		return library.SharedProperties.Shared.Installable
1975	}
1976	return nil
1977}
1978
1979func (library *libraryDecorator) makeUninstallable(mod *Module) {
1980	if library.static() && library.buildStatic() && !library.buildStubs() {
1981		// If we're asked to make a static library uninstallable we don't do
1982		// anything since AndroidMkEntries always sets LOCAL_UNINSTALLABLE_MODULE
1983		// for these entries. This is done to still get the make targets for NOTICE
1984		// files from notice_files.mk, which other libraries might depend on.
1985		return
1986	}
1987	mod.ModuleBase.MakeUninstallable()
1988}
1989
1990func (library *libraryDecorator) getPartition() string {
1991	return library.path.Partition()
1992}
1993
1994func (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPath {
1995	return library.apiListCoverageXmlPath
1996}
1997
1998func (library *libraryDecorator) overriddenModules() []string {
1999	return library.Properties.Overrides
2000}
2001
2002var _ overridable = (*libraryDecorator)(nil)
2003
2004var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
2005
2006// versioningMacroNamesList returns a singleton map, where keys are "version macro names",
2007// and values are the module name responsible for registering the version macro name.
2008//
2009// Version macros are used when building against stubs, to provide version information about
2010// the stub. Only stub libraries should have an entry in this list.
2011//
2012// For example, when building against libFoo#ver, __LIBFOO_API__ macro is set to ver so
2013// that headers from libFoo can be conditionally compiled (this may hide APIs
2014// that are not available for the version).
2015//
2016// This map is used to ensure that there aren't conflicts between these version macro names.
2017func versioningMacroNamesList(config android.Config) *map[string]string {
2018	return config.Once(versioningMacroNamesListKey, func() interface{} {
2019		m := make(map[string]string)
2020		return &m
2021	}).(*map[string]string)
2022}
2023
2024// alphanumeric and _ characters are preserved.
2025// other characters are all converted to _
2026var charsNotForMacro = regexp.MustCompile("[^a-zA-Z0-9_]+")
2027
2028// versioningMacroName returns the canonical version macro name for the given module.
2029func versioningMacroName(moduleName string) string {
2030	macroName := charsNotForMacro.ReplaceAllString(moduleName, "_")
2031	macroName = strings.ToUpper(macroName)
2032	return "__" + macroName + "_API__"
2033}
2034
2035// NewLibrary builds and returns a new Module corresponding to a C++ library.
2036// Individual module implementations which comprise a C++ library (or something like
2037// a C++ library) should call this function, set some fields on the result, and
2038// then call the Init function.
2039func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
2040	module := newModule(hod, android.MultilibBoth)
2041
2042	library := &libraryDecorator{
2043		MutatedProperties: LibraryMutatedProperties{
2044			BuildShared: true,
2045			BuildStatic: true,
2046		},
2047		baseCompiler:  NewBaseCompiler(),
2048		baseLinker:    NewBaseLinker(module.sanitize),
2049		baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem),
2050		sabi:          module.sabi,
2051	}
2052
2053	module.compiler = library
2054	module.linker = library
2055	module.installer = library
2056	module.library = library
2057
2058	return module, library
2059}
2060
2061// connects a shared library to a static library in order to reuse its .o files to avoid
2062// compiling source files twice.
2063func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) {
2064	if staticCompiler, ok := static.compiler.(*libraryDecorator); ok {
2065		sharedCompiler := shared.compiler.(*libraryDecorator)
2066
2067		// Check libraries in addition to cflags, since libraries may be exporting different
2068		// include directories.
2069		if len(staticCompiler.StaticProperties.Static.Cflags.GetOrDefault(mctx, nil)) == 0 &&
2070			len(sharedCompiler.SharedProperties.Shared.Cflags.GetOrDefault(mctx, nil)) == 0 &&
2071			len(staticCompiler.StaticProperties.Static.Whole_static_libs) == 0 &&
2072			len(sharedCompiler.SharedProperties.Shared.Whole_static_libs) == 0 &&
2073			len(staticCompiler.StaticProperties.Static.Static_libs) == 0 &&
2074			len(sharedCompiler.SharedProperties.Shared.Static_libs) == 0 &&
2075			len(staticCompiler.StaticProperties.Static.Shared_libs) == 0 &&
2076			len(sharedCompiler.SharedProperties.Shared.Shared_libs) == 0 &&
2077			// Compare System_shared_libs properties with nil because empty lists are
2078			// semantically significant for them.
2079			staticCompiler.StaticProperties.Static.System_shared_libs == nil &&
2080			sharedCompiler.SharedProperties.Shared.System_shared_libs == nil {
2081
2082			mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2083			sharedCompiler.baseCompiler.Properties.OriginalSrcs =
2084				sharedCompiler.baseCompiler.Properties.Srcs
2085			sharedCompiler.baseCompiler.Properties.Srcs = nil
2086			sharedCompiler.baseCompiler.Properties.Generated_sources = nil
2087		}
2088
2089		// This dep is just to reference static variant from shared variant
2090		mctx.AddInterVariantDependency(staticVariantTag, shared, static)
2091	}
2092}
2093
2094// LinkageMutator adds "static" or "shared" variants for modules depending
2095// on whether the module can be built as a static library or a shared library.
2096func LinkageMutator(mctx android.BottomUpMutatorContext) {
2097	ccPrebuilt := false
2098	if m, ok := mctx.Module().(*Module); ok && m.linker != nil {
2099		_, ccPrebuilt = m.linker.(prebuiltLibraryInterface)
2100	}
2101	if ccPrebuilt {
2102		library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface)
2103
2104		// Differentiate between header only and building an actual static/shared library
2105		buildStatic := library.buildStatic()
2106		buildShared := library.buildShared()
2107		if buildStatic || buildShared {
2108			// Always create both the static and shared variants for prebuilt libraries, and then disable the one
2109			// that is not being used.  This allows them to share the name of a cc_library module, which requires that
2110			// all the variants of the cc_library also exist on the prebuilt.
2111			modules := mctx.CreateLocalVariations("static", "shared")
2112			static := modules[0].(*Module)
2113			shared := modules[1].(*Module)
2114
2115			static.linker.(prebuiltLibraryInterface).setStatic()
2116			shared.linker.(prebuiltLibraryInterface).setShared()
2117
2118			if buildShared {
2119				mctx.AliasVariation("shared")
2120			} else if buildStatic {
2121				mctx.AliasVariation("static")
2122			}
2123
2124			if !buildStatic {
2125				static.linker.(prebuiltLibraryInterface).disablePrebuilt()
2126			}
2127			if !buildShared {
2128				shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
2129			}
2130		} else {
2131			// Header only
2132		}
2133
2134	} else if library, ok := mctx.Module().(LinkableInterface); ok && (library.CcLibraryInterface() || library.RustLibraryInterface()) {
2135		// Non-cc.Modules may need an empty variant for their mutators.
2136		variations := []string{}
2137		if library.NonCcVariants() {
2138			variations = append(variations, "")
2139		}
2140		isLLNDK := false
2141		if m, ok := mctx.Module().(*Module); ok {
2142			isLLNDK = m.IsLlndk()
2143		}
2144		buildStatic := library.BuildStaticVariant() && !isLLNDK
2145		buildShared := library.BuildSharedVariant()
2146		if buildStatic && buildShared {
2147			variations := append([]string{"static", "shared"}, variations...)
2148
2149			modules := mctx.CreateLocalVariations(variations...)
2150			static := modules[0].(LinkableInterface)
2151			shared := modules[1].(LinkableInterface)
2152
2153			static.SetStatic()
2154			shared.SetShared()
2155
2156			if _, ok := library.(*Module); ok {
2157				reuseStaticLibrary(mctx, static.(*Module), shared.(*Module))
2158			}
2159			mctx.AliasVariation("shared")
2160		} else if buildStatic {
2161			variations := append([]string{"static"}, variations...)
2162
2163			modules := mctx.CreateLocalVariations(variations...)
2164			modules[0].(LinkableInterface).SetStatic()
2165			mctx.AliasVariation("static")
2166		} else if buildShared {
2167			variations := append([]string{"shared"}, variations...)
2168
2169			modules := mctx.CreateLocalVariations(variations...)
2170			modules[0].(LinkableInterface).SetShared()
2171			mctx.AliasVariation("shared")
2172		} else if len(variations) > 0 {
2173			mctx.CreateLocalVariations(variations...)
2174			mctx.AliasVariation(variations[0])
2175		}
2176	}
2177}
2178
2179// normalizeVersions modifies `versions` in place, so that each raw version
2180// string becomes its normalized canonical form.
2181// Validates that the versions in `versions` are specified in least to greatest order.
2182func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
2183	var previous android.ApiLevel
2184	for i, v := range versions {
2185		ver, err := android.ApiLevelFromUser(ctx, v)
2186		if err != nil {
2187			ctx.PropertyErrorf("versions", "%s", err.Error())
2188			return
2189		}
2190		if i > 0 && ver.LessThanOrEqualTo(previous) {
2191			ctx.PropertyErrorf("versions", "not sorted: %v", versions)
2192		}
2193		versions[i] = ver.String()
2194		previous = ver
2195	}
2196}
2197
2198func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
2199	// "" is for the non-stubs (implementation) variant for system modules, or the LLNDK variant
2200	// for LLNDK modules.
2201	variants := append(android.CopyOf(versions), "")
2202
2203	m := mctx.Module().(*Module)
2204	isLLNDK := m.IsLlndk()
2205	isVendorPublicLibrary := m.IsVendorPublicLibrary()
2206	isImportedApiLibrary := m.isImportedApiLibrary()
2207
2208	modules := mctx.CreateLocalVariations(variants...)
2209	for i, m := range modules {
2210
2211		if variants[i] != "" || isLLNDK || isVendorPublicLibrary || isImportedApiLibrary {
2212			// A stubs or LLNDK stubs variant.
2213			c := m.(*Module)
2214			c.sanitize = nil
2215			c.stl = nil
2216			c.Properties.PreventInstall = true
2217			lib := moduleLibraryInterface(m)
2218			isLatest := i == (len(versions) - 1)
2219			lib.setBuildStubs(isLatest)
2220
2221			if variants[i] != "" {
2222				// A non-LLNDK stubs module is hidden from make and has a dependency from the
2223				// implementation module to the stubs module.
2224				c.Properties.HideFromMake = true
2225				lib.setStubsVersion(variants[i])
2226				mctx.AddInterVariantDependency(stubImplDepTag, modules[len(modules)-1], modules[i])
2227			}
2228		}
2229	}
2230	mctx.AliasVariation("")
2231	latestVersion := ""
2232	if len(versions) > 0 {
2233		latestVersion = versions[len(versions)-1]
2234	}
2235	mctx.CreateAliasVariation("latest", latestVersion)
2236}
2237
2238func createPerApiVersionVariations(mctx android.BottomUpMutatorContext, minSdkVersion string) {
2239	from, err := nativeApiLevelFromUser(mctx, minSdkVersion)
2240	if err != nil {
2241		mctx.PropertyErrorf("min_sdk_version", err.Error())
2242		return
2243	}
2244
2245	versionStrs := ndkLibraryVersions(mctx, from)
2246	modules := mctx.CreateLocalVariations(versionStrs...)
2247
2248	for i, module := range modules {
2249		module.(*Module).Properties.Sdk_version = StringPtr(versionStrs[i])
2250		module.(*Module).Properties.Min_sdk_version = StringPtr(versionStrs[i])
2251	}
2252}
2253
2254func canBeOrLinkAgainstVersionVariants(module interface {
2255	Host() bool
2256	InRamdisk() bool
2257	InVendorRamdisk() bool
2258}) bool {
2259	return !module.Host() && !module.InRamdisk() && !module.InVendorRamdisk()
2260}
2261
2262func canBeVersionVariant(module interface {
2263	Host() bool
2264	InRamdisk() bool
2265	InVendorRamdisk() bool
2266	CcLibraryInterface() bool
2267	Shared() bool
2268}) bool {
2269	return canBeOrLinkAgainstVersionVariants(module) &&
2270		module.CcLibraryInterface() && module.Shared()
2271}
2272
2273func moduleLibraryInterface(module blueprint.Module) libraryInterface {
2274	if m, ok := module.(*Module); ok {
2275		return m.library
2276	}
2277	return nil
2278}
2279
2280// setStubsVersions normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions.
2281func setStubsVersions(mctx android.BottomUpMutatorContext, library libraryInterface, module *Module) {
2282	if !library.buildShared() || !canBeVersionVariant(module) {
2283		return
2284	}
2285	versions := library.stubsVersions(mctx)
2286	if mctx.Failed() {
2287		return
2288	}
2289	// Set the versions on the pre-mutated module so they can be read by any llndk modules that
2290	// depend on the implementation library and haven't been mutated yet.
2291	library.setAllStubsVersions(versions)
2292}
2293
2294// versionMutator splits a module into the mandatory non-stubs variant
2295// (which is unnamed) and zero or more stubs variants.
2296func versionMutator(mctx android.BottomUpMutatorContext) {
2297	if mctx.Os() != android.Android {
2298		return
2299	}
2300
2301	m, ok := mctx.Module().(*Module)
2302	if library := moduleLibraryInterface(mctx.Module()); library != nil && canBeVersionVariant(m) {
2303		setStubsVersions(mctx, library, m)
2304
2305		createVersionVariations(mctx, library.allStubsVersions())
2306		return
2307	}
2308
2309	if ok {
2310		if m.SplitPerApiLevel() && m.IsSdkVariant() {
2311			createPerApiVersionVariations(mctx, m.MinSdkVersion())
2312		}
2313	}
2314}
2315
2316// maybeInjectBoringSSLHash adds a rule to run bssl_inject_hash on the output file if the module has the
2317// inject_bssl_hash or if any static library dependencies have inject_bssl_hash set.  It returns the output path
2318// that the linked output file should be written to.
2319// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
2320func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.ModuleOutPath,
2321	inject *bool, fileName string) android.ModuleOutPath {
2322	// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
2323	injectBoringSSLHash := Bool(inject)
2324	ctx.VisitDirectDeps(func(dep android.Module) {
2325		if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() {
2326			if cc, ok := dep.(*Module); ok {
2327				if library, ok := cc.linker.(*libraryDecorator); ok {
2328					if Bool(library.Properties.Inject_bssl_hash) {
2329						injectBoringSSLHash = true
2330					}
2331				}
2332			}
2333		}
2334	})
2335	if injectBoringSSLHash {
2336		hashedOutputfile := outputFile
2337		outputFile = android.PathForModuleOut(ctx, "unhashed", fileName)
2338
2339		rule := android.NewRuleBuilder(pctx, ctx)
2340		rule.Command().
2341			BuiltTool("bssl_inject_hash").
2342			FlagWithInput("-in-object ", outputFile).
2343			FlagWithOutput("-o ", hashedOutputfile)
2344		rule.Build("injectCryptoHash", "inject crypto hash")
2345	}
2346
2347	return outputFile
2348}
2349