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	"sort"
23	"strconv"
24	"strings"
25	"sync"
26
27	"github.com/google/blueprint/pathtools"
28
29	"android/soong/android"
30	"android/soong/cc/config"
31	"android/soong/genrule"
32)
33
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	Stubs struct {
63		// Relative path to the symbol map. The symbol map provides the list of
64		// symbols that are exported for stubs variant of this library.
65		Symbol_file *string `android:"path"`
66
67		// List versions to generate stubs libs for.
68		Versions []string
69	}
70
71	// set the name of the output
72	Stem *string `android:"arch_variant"`
73
74	// set suffix of the name of the output
75	Suffix *string `android:"arch_variant"`
76
77	Target struct {
78		Vendor struct {
79			// set suffix of the name of the output
80			Suffix *string `android:"arch_variant"`
81		}
82	}
83
84	// Names of modules to be overridden. Listed modules can only be other shared libraries
85	// (in Make or Soong).
86	// This does not completely prevent installation of the overridden libraries, but if both
87	// binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed
88	// from PRODUCT_PACKAGES.
89	Overrides []string
90
91	// Properties for ABI compatibility checker
92	Header_abi_checker struct {
93		// Enable ABI checks (even if this is not an LLNDK/VNDK lib)
94		Enabled *bool
95
96		// Path to a symbol file that specifies the symbols to be included in the generated
97		// ABI dump file
98		Symbol_file *string `android:"path"`
99
100		// Symbol versions that should be ignored from the symbol file
101		Exclude_symbol_versions []string
102
103		// Symbol tags that should be ignored from the symbol file
104		Exclude_symbol_tags []string
105
106		// Run checks on all APIs (in addition to the ones referred by
107		// one of exported ELF symbols.)
108		Check_all_apis *bool
109	}
110
111	// Order symbols in .bss section by their sizes.  Only useful for shared libraries.
112	Sort_bss_symbols_by_size *bool
113
114	// Inject boringssl hash into the shared library.  This is only intended for use by external/boringssl.
115	Inject_bssl_hash *bool `android:"arch_variant"`
116}
117
118type StaticProperties struct {
119	Static StaticOrSharedProperties `android:"arch_variant"`
120}
121
122type SharedProperties struct {
123	Shared StaticOrSharedProperties `android:"arch_variant"`
124}
125
126type StaticOrSharedProperties struct {
127	Srcs   []string `android:"path,arch_variant"`
128	Cflags []string `android:"arch_variant"`
129
130	Enabled            *bool    `android:"arch_variant"`
131	Whole_static_libs  []string `android:"arch_variant"`
132	Static_libs        []string `android:"arch_variant"`
133	Shared_libs        []string `android:"arch_variant"`
134	System_shared_libs []string `android:"arch_variant"`
135
136	Export_shared_lib_headers []string `android:"arch_variant"`
137	Export_static_lib_headers []string `android:"arch_variant"`
138
139	Apex_available []string `android:"arch_variant"`
140}
141
142type LibraryMutatedProperties struct {
143	// Build a static variant
144	BuildStatic bool `blueprint:"mutated"`
145	// Build a shared variant
146	BuildShared bool `blueprint:"mutated"`
147	// This variant is shared
148	VariantIsShared bool `blueprint:"mutated"`
149	// This variant is static
150	VariantIsStatic bool `blueprint:"mutated"`
151
152	// This variant is a stubs lib
153	BuildStubs bool `blueprint:"mutated"`
154	// Version of the stubs lib
155	StubsVersion string `blueprint:"mutated"`
156}
157
158type FlagExporterProperties struct {
159	// list of directories relative to the Blueprints file that will
160	// be added to the include path (using -I) for this module and any module that links
161	// against this module.  Directories listed in export_include_dirs do not need to be
162	// listed in local_include_dirs.
163	Export_include_dirs []string `android:"arch_variant"`
164
165	// list of directories that will be added to the system include path
166	// using -isystem for this module and any module that links against this module.
167	Export_system_include_dirs []string `android:"arch_variant"`
168
169	Target struct {
170		Vendor struct {
171			// list of exported include directories, like
172			// export_include_dirs, that will be applied to the
173			// vendor variant of this library. This will overwrite
174			// any other declarations.
175			Override_export_include_dirs []string
176		}
177	}
178}
179
180func init() {
181	RegisterLibraryBuildComponents(android.InitRegistrationContext)
182}
183
184func RegisterLibraryBuildComponents(ctx android.RegistrationContext) {
185	ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory)
186	ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory)
187	ctx.RegisterModuleType("cc_library", LibraryFactory)
188	ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory)
189	ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory)
190}
191
192// cc_library creates both static and/or shared libraries for a device and/or
193// host. By default, a cc_library has a single variant that targets the device.
194// Specifying `host_supported: true` also creates a library that targets the
195// host.
196func LibraryFactory() android.Module {
197	module, _ := NewLibrary(android.HostAndDeviceSupported)
198	// Can be used as both a static and a shared library.
199	module.sdkMemberTypes = []android.SdkMemberType{
200		sharedLibrarySdkMemberType,
201		staticLibrarySdkMemberType,
202		staticAndSharedLibrarySdkMemberType,
203	}
204	return module.Init()
205}
206
207// cc_library_static creates a static library for a device and/or host binary.
208func LibraryStaticFactory() android.Module {
209	module, library := NewLibrary(android.HostAndDeviceSupported)
210	library.BuildOnlyStatic()
211	module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
212	return module.Init()
213}
214
215// cc_library_shared creates a shared library for a device and/or host.
216func LibrarySharedFactory() android.Module {
217	module, library := NewLibrary(android.HostAndDeviceSupported)
218	library.BuildOnlyShared()
219	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
220	return module.Init()
221}
222
223// cc_library_host_static creates a static library that is linkable to a host
224// binary.
225func LibraryHostStaticFactory() android.Module {
226	module, library := NewLibrary(android.HostSupported)
227	library.BuildOnlyStatic()
228	module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
229	return module.Init()
230}
231
232// cc_library_host_shared creates a shared library that is usable on a host.
233func LibraryHostSharedFactory() android.Module {
234	module, library := NewLibrary(android.HostSupported)
235	library.BuildOnlyShared()
236	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
237	return module.Init()
238}
239
240type flagExporter struct {
241	Properties FlagExporterProperties
242
243	dirs       android.Paths
244	systemDirs android.Paths
245	flags      []string
246	deps       android.Paths
247	headers    android.Paths
248}
249
250func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
251	if ctx.useVndk() && f.Properties.Target.Vendor.Override_export_include_dirs != nil {
252		return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs)
253	} else {
254		return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
255	}
256}
257
258func (f *flagExporter) exportIncludes(ctx ModuleContext) {
259	f.dirs = append(f.dirs, f.exportedIncludes(ctx)...)
260	f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
261}
262
263func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) {
264	// all dirs are force exported as system
265	f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...)
266	f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
267}
268
269func (f *flagExporter) reexportDirs(dirs ...android.Path) {
270	f.dirs = append(f.dirs, dirs...)
271}
272
273func (f *flagExporter) reexportSystemDirs(dirs ...android.Path) {
274	f.systemDirs = append(f.systemDirs, dirs...)
275}
276
277func (f *flagExporter) reexportFlags(flags ...string) {
278	if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") {
279		panic(fmt.Errorf("Exporting invalid flag %q: "+
280			"use reexportDirs or reexportSystemDirs to export directories", flag))
281	}
282	f.flags = append(f.flags, flags...)
283}
284
285func (f *flagExporter) reexportDeps(deps ...android.Path) {
286	f.deps = append(f.deps, deps...)
287}
288
289// addExportedGeneratedHeaders does nothing but collects generated header files.
290// This can be differ to exportedDeps which may contain phony files to minimize ninja.
291func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
292	f.headers = append(f.headers, headers...)
293}
294
295func (f *flagExporter) exportedDirs() android.Paths {
296	return f.dirs
297}
298
299func (f *flagExporter) exportedSystemDirs() android.Paths {
300	return f.systemDirs
301}
302
303func (f *flagExporter) exportedFlags() []string {
304	return f.flags
305}
306
307func (f *flagExporter) exportedDeps() android.Paths {
308	return f.deps
309}
310
311func (f *flagExporter) exportedGeneratedHeaders() android.Paths {
312	return f.headers
313}
314
315type exportedFlagsProducer interface {
316	exportedDirs() android.Paths
317	exportedSystemDirs() android.Paths
318	exportedFlags() []string
319	exportedDeps() android.Paths
320	exportedGeneratedHeaders() android.Paths
321}
322
323var _ exportedFlagsProducer = (*flagExporter)(nil)
324
325// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific
326// functionality: static vs. shared linkage, reusing object files for shared libraries
327type libraryDecorator struct {
328	Properties        LibraryProperties
329	StaticProperties  StaticProperties
330	SharedProperties  SharedProperties
331	MutatedProperties LibraryMutatedProperties
332
333	// For reusing static library objects for shared library
334	reuseObjects Objects
335
336	// table-of-contents file to optimize out relinking when possible
337	tocFile android.OptionalPath
338
339	flagExporter
340	stripper
341
342	// If we're used as a whole_static_lib, our missing dependencies need
343	// to be given
344	wholeStaticMissingDeps []string
345
346	// For whole_static_libs
347	objects Objects
348
349	// Uses the module's name if empty, but can be overridden. Does not include
350	// shlib suffix.
351	libName string
352
353	sabi *sabi
354
355	// Output archive of gcno coverage information files
356	coverageOutputFile android.OptionalPath
357
358	// linked Source Abi Dump
359	sAbiOutputFile android.OptionalPath
360
361	// Source Abi Diff
362	sAbiDiff android.OptionalPath
363
364	// Location of the static library in the sysroot. Empty if the library is
365	// not included in the NDK.
366	ndkSysrootPath android.Path
367
368	// Location of the linked, unstripped library for shared libraries
369	unstrippedOutputFile android.Path
370
371	// Location of the file that should be copied to dist dir when requested
372	distFile android.Path
373
374	versionScriptPath android.ModuleGenPath
375
376	post_install_cmds []string
377
378	// If useCoreVariant is true, the vendor variant of a VNDK library is
379	// not installed.
380	useCoreVariant       bool
381	checkSameCoreVariant bool
382
383	// Decorated interfaces
384	*baseCompiler
385	*baseLinker
386	*baseInstaller
387
388	collectedSnapshotHeaders android.Paths
389}
390
391// collectHeadersForSnapshot collects all exported headers from library.
392// It globs header files in the source tree for exported include directories,
393// and tracks generated header files separately.
394//
395// This is to be called from GenerateAndroidBuildActions, and then collected
396// header files can be retrieved by snapshotHeaders().
397func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) {
398	ret := android.Paths{}
399
400	// Headers in the source tree should be globbed. On the contrast, generated headers
401	// can't be globbed, and they should be manually collected.
402	// So, we first filter out intermediate directories (which contains generated headers)
403	// from exported directories, and then glob headers under remaining directories.
404	for _, path := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
405		dir := path.String()
406		// Skip if dir is for generated headers
407		if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
408			continue
409		}
410		// libeigen wrongly exports the root directory "external/eigen". But only two
411		// subdirectories "Eigen" and "unsupported" contain exported header files. Even worse
412		// some of them have no extension. So we need special treatment for libeigen in order
413		// to glob correctly.
414		if dir == "external/eigen" {
415			// Only these two directories contains exported headers.
416			for _, subdir := range []string{"Eigen", "unsupported/Eigen"} {
417				glob, err := ctx.GlobWithDeps("external/eigen/"+subdir+"/**/*", nil)
418				if err != nil {
419					ctx.ModuleErrorf("glob failed: %#v", err)
420					return
421				}
422				for _, header := range glob {
423					if strings.HasSuffix(header, "/") {
424						continue
425					}
426					ext := filepath.Ext(header)
427					if ext != "" && ext != ".h" {
428						continue
429					}
430					ret = append(ret, android.PathForSource(ctx, header))
431				}
432			}
433			continue
434		}
435		exts := headerExts
436		// Glob all files under this special directory, because of C++ headers.
437		if strings.HasPrefix(dir, "external/libcxx/include") {
438			exts = []string{""}
439		}
440		for _, ext := range exts {
441			glob, err := ctx.GlobWithDeps(dir+"/**/*"+ext, nil)
442			if err != nil {
443				ctx.ModuleErrorf("glob failed: %#v", err)
444				return
445			}
446			for _, header := range glob {
447				if strings.HasSuffix(header, "/") {
448					continue
449				}
450				ret = append(ret, android.PathForSource(ctx, header))
451			}
452		}
453	}
454
455	// Collect generated headers
456	for _, header := range append(l.exportedGeneratedHeaders(), l.exportedDeps()...) {
457		// TODO(b/148123511): remove exportedDeps after cleaning up genrule
458		if strings.HasSuffix(header.Base(), "-phony") {
459			continue
460		}
461		ret = append(ret, header)
462	}
463
464	l.collectedSnapshotHeaders = ret
465}
466
467// This returns all exported header files, both generated ones and headers from source tree.
468// collectHeadersForSnapshot() must be called before calling this.
469func (l *libraryDecorator) snapshotHeaders() android.Paths {
470	if l.collectedSnapshotHeaders == nil {
471		panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
472	}
473	return l.collectedSnapshotHeaders
474}
475
476func (library *libraryDecorator) linkerProps() []interface{} {
477	var props []interface{}
478	props = append(props, library.baseLinker.linkerProps()...)
479	props = append(props,
480		&library.Properties,
481		&library.MutatedProperties,
482		&library.flagExporter.Properties,
483		&library.stripper.StripProperties)
484
485	if library.MutatedProperties.BuildShared {
486		props = append(props, &library.SharedProperties)
487	}
488	if library.MutatedProperties.BuildStatic {
489		props = append(props, &library.StaticProperties)
490	}
491
492	return props
493}
494
495func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
496	flags = library.baseLinker.linkerFlags(ctx, flags)
497
498	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
499	// all code is position independent, and then those warnings get promoted to
500	// errors.
501	if !ctx.Windows() {
502		flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC")
503	}
504
505	if library.static() {
506		flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags...)
507	} else if library.shared() {
508		flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags...)
509	}
510
511	if library.shared() {
512		libName := library.getLibName(ctx)
513		var f []string
514		if ctx.toolchain().Bionic() {
515			f = append(f,
516				"-nostdlib",
517				"-Wl,--gc-sections",
518			)
519		}
520
521		if ctx.Darwin() {
522			f = append(f,
523				"-dynamiclib",
524				"-single_module",
525				"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
526			)
527			if ctx.Arch().ArchType == android.X86 {
528				f = append(f,
529					"-read_only_relocs suppress",
530				)
531			}
532		} else {
533			f = append(f, "-shared")
534			if !ctx.Windows() {
535				f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
536			}
537		}
538
539		flags.Global.LdFlags = append(flags.Global.LdFlags, f...)
540	}
541
542	return flags
543}
544
545func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
546	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
547	if len(exportIncludeDirs) > 0 {
548		f := includeDirsToFlags(exportIncludeDirs)
549		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
550		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
551	}
552
553	flags = library.baseCompiler.compilerFlags(ctx, flags, deps)
554	if library.buildStubs() {
555		// Remove -include <file> when compiling stubs. Otherwise, the force included
556		// headers might cause conflicting types error with the symbols in the
557		// generated stubs source code. e.g.
558		// double acos(double); // in header
559		// void acos() {} // in the generated source code
560		removeInclude := func(flags []string) []string {
561			ret := flags[:0]
562			for _, f := range flags {
563				if strings.HasPrefix(f, "-include ") {
564					continue
565				}
566				ret = append(ret, f)
567			}
568			return ret
569		}
570		flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags)
571		flags.Local.CFlags = removeInclude(flags.Local.CFlags)
572
573		flags = addStubLibraryCompilerFlags(flags)
574	}
575	return flags
576}
577
578// Returns a string that represents the class of the ABI dump.
579// Returns an empty string if ABI check is disabled for this library.
580func (library *libraryDecorator) classifySourceAbiDump(ctx ModuleContext) string {
581	enabled := library.Properties.Header_abi_checker.Enabled
582	if enabled != nil && !Bool(enabled) {
583		return ""
584	}
585	// Return NDK if the library is both NDK and LLNDK.
586	if ctx.isNdk() {
587		return "NDK"
588	}
589	if ctx.isLlndkPublic(ctx.Config()) {
590		return "LLNDK"
591	}
592	if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(ctx.Config()) {
593		if ctx.isVndkSp() {
594			if ctx.isVndkExt() {
595				return "VNDK-SP-ext"
596			} else {
597				return "VNDK-SP"
598			}
599		} else {
600			if ctx.isVndkExt() {
601				return "VNDK-ext"
602			} else {
603				return "VNDK-core"
604			}
605		}
606	}
607	if Bool(enabled) || ctx.hasStubsVariants() {
608		return "PLATFORM"
609	}
610	return ""
611}
612
613func (library *libraryDecorator) shouldCreateSourceAbiDump(ctx ModuleContext) bool {
614	if !ctx.shouldCreateSourceAbiDump() {
615		return false
616	}
617	if !ctx.isForPlatform() {
618		if !ctx.hasStubsVariants() {
619			// Skip ABI checks if this library is for APEX but isn't exported.
620			return false
621		}
622		if !Bool(library.Properties.Header_abi_checker.Enabled) {
623			// Skip ABI checks if this library is for APEX and did not explicitly enable
624			// ABI checks.
625			// TODO(b/145608479): ABI checks should be enabled by default. Remove this
626			// after evaluating the extra build time.
627			return false
628		}
629	}
630	return library.classifySourceAbiDump(ctx) != ""
631}
632
633func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
634	if library.buildStubs() {
635		objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "--apex")
636		library.versionScriptPath = versionScript
637		return objs
638	}
639
640	if !library.buildShared() && !library.buildStatic() {
641		if len(library.baseCompiler.Properties.Srcs) > 0 {
642			ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs")
643		}
644		if len(library.StaticProperties.Static.Srcs) > 0 {
645			ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs")
646		}
647		if len(library.SharedProperties.Shared.Srcs) > 0 {
648			ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs")
649		}
650		return Objects{}
651	}
652	if library.shouldCreateSourceAbiDump(ctx) || library.sabi.Properties.CreateSAbiDumps {
653		exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
654		var SourceAbiFlags []string
655		for _, dir := range exportIncludeDirs.Strings() {
656			SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
657		}
658		for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes {
659			SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude)
660		}
661		flags.SAbiFlags = SourceAbiFlags
662		total_length := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) +
663			len(library.SharedProperties.Shared.Srcs) + len(library.StaticProperties.Static.Srcs)
664		if total_length > 0 {
665			flags.SAbiDump = true
666		}
667	}
668	objs := library.baseCompiler.compile(ctx, flags, deps)
669	library.reuseObjects = objs
670	buildFlags := flagsToBuilderFlags(flags)
671
672	if library.static() {
673		srcs := android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Srcs)
674		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary,
675			srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
676	} else if library.shared() {
677		srcs := android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Srcs)
678		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary,
679			srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
680	}
681
682	return objs
683}
684
685type libraryInterface interface {
686	getWholeStaticMissingDeps() []string
687	static() bool
688	shared() bool
689	objs() Objects
690	reuseObjs() (Objects, exportedFlagsProducer)
691	toc() android.OptionalPath
692
693	// Returns true if the build options for the module have selected a static or shared build
694	buildStatic() bool
695	buildShared() bool
696
697	// Sets whether a specific variant is static or shared
698	setStatic()
699	setShared()
700
701	// Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff
702	androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer)
703
704	availableFor(string) bool
705}
706
707func (library *libraryDecorator) getLibNameHelper(baseModuleName string, useVndk bool) string {
708	name := library.libName
709	if name == "" {
710		name = String(library.Properties.Stem)
711		if name == "" {
712			name = baseModuleName
713		}
714	}
715
716	suffix := ""
717	if useVndk {
718		suffix = String(library.Properties.Target.Vendor.Suffix)
719	}
720	if suffix == "" {
721		suffix = String(library.Properties.Suffix)
722	}
723
724	return name + suffix
725}
726
727func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string {
728	name := library.getLibNameHelper(ctx.baseModuleName(), ctx.useVndk())
729
730	if ctx.isVndkExt() {
731		// vndk-ext lib should have the same name with original lib
732		ctx.VisitDirectDepsWithTag(vndkExtDepTag, func(module android.Module) {
733			originalName := module.(*Module).outputFile.Path()
734			name = strings.TrimSuffix(originalName.Base(), originalName.Ext())
735		})
736	}
737
738	if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
739		if !strings.HasSuffix(name, "-host") {
740			name = name + "-host"
741		}
742	}
743
744	return name
745}
746
747var versioningMacroNamesListMutex sync.Mutex
748
749func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
750	location := InstallInSystem
751	if library.baseLinker.sanitize.inSanitizerDir() {
752		location = InstallInSanitizerDir
753	}
754	library.baseInstaller.location = location
755	library.baseLinker.linkerInit(ctx)
756	// Let baseLinker know whether this variant is for stubs or not, so that
757	// it can omit things that are not required for linking stubs.
758	library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs()
759
760	if library.buildStubs() {
761		macroNames := versioningMacroNamesList(ctx.Config())
762		myName := versioningMacroName(ctx.ModuleName())
763		versioningMacroNamesListMutex.Lock()
764		defer versioningMacroNamesListMutex.Unlock()
765		if (*macroNames)[myName] == "" {
766			(*macroNames)[myName] = ctx.ModuleName()
767		} else if (*macroNames)[myName] != ctx.ModuleName() {
768			ctx.ModuleErrorf("Macro name %q for versioning conflicts with macro name from module %q ", myName, (*macroNames)[myName])
769		}
770	}
771}
772
773func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
774	deps = library.baseCompiler.compilerDeps(ctx, deps)
775
776	return deps
777}
778
779func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
780	if library.static() {
781		// Compare with nil because an empty list needs to be propagated.
782		if library.StaticProperties.Static.System_shared_libs != nil {
783			library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs
784		}
785	} else if library.shared() {
786		// Compare with nil because an empty list needs to be propagated.
787		if library.SharedProperties.Shared.System_shared_libs != nil {
788			library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs
789		}
790	}
791
792	deps = library.baseLinker.linkerDeps(ctx, deps)
793
794	if library.static() {
795		deps.WholeStaticLibs = append(deps.WholeStaticLibs,
796			library.StaticProperties.Static.Whole_static_libs...)
797		deps.StaticLibs = append(deps.StaticLibs, library.StaticProperties.Static.Static_libs...)
798		deps.SharedLibs = append(deps.SharedLibs, library.StaticProperties.Static.Shared_libs...)
799
800		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...)
801		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...)
802	} else if library.shared() {
803		if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) {
804			if !ctx.useSdk() {
805				deps.CrtBegin = "crtbegin_so"
806				deps.CrtEnd = "crtend_so"
807			} else {
808				// TODO(danalbert): Add generation of crt objects.
809				// For `sdk_version: "current"`, we don't actually have a
810				// freshly generated set of CRT objects. Use the last stable
811				// version.
812				version := ctx.sdkVersion()
813				if version == "current" {
814					version = getCurrentNdkPrebuiltVersion(ctx)
815				}
816				deps.CrtBegin = "ndk_crtbegin_so." + version
817				deps.CrtEnd = "ndk_crtend_so." + version
818			}
819		}
820		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs...)
821		deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs...)
822		deps.SharedLibs = append(deps.SharedLibs, library.SharedProperties.Shared.Shared_libs...)
823
824		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...)
825		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...)
826	}
827	if ctx.useVndk() {
828		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
829		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
830		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
831		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
832		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
833	}
834	if ctx.inRecovery() {
835		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
836		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs)
837		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
838		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs)
839		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
840	}
841	if ctx.inRamdisk() {
842		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
843		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs)
844		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
845		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs)
846		deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
847	}
848
849	return deps
850}
851
852func (library *libraryDecorator) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps {
853	specifiedDeps = library.baseLinker.linkerSpecifiedDeps(specifiedDeps)
854	var properties StaticOrSharedProperties
855	if library.static() {
856		properties = library.StaticProperties.Static
857	} else if library.shared() {
858		properties = library.SharedProperties.Shared
859	}
860
861	specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs...)
862
863	// Must distinguish nil and [] in system_shared_libs - ensure that [] in
864	// either input list doesn't come out as nil.
865	if specifiedDeps.systemSharedLibs == nil {
866		specifiedDeps.systemSharedLibs = properties.System_shared_libs
867	} else {
868		specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...)
869	}
870
871	specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs)
872	if len(specifiedDeps.systemSharedLibs) > 0 {
873		// Skip this if systemSharedLibs is either nil or [], to ensure they are
874		// retained.
875		specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs)
876	}
877	return specifiedDeps
878}
879
880func (library *libraryDecorator) linkStatic(ctx ModuleContext,
881	flags Flags, deps PathDeps, objs Objects) android.Path {
882
883	library.objects = deps.WholeStaticLibObjs.Copy()
884	library.objects = library.objects.Append(objs)
885
886	fileName := ctx.ModuleName() + staticLibraryExtension
887	outputFile := android.PathForModuleOut(ctx, fileName)
888	builderFlags := flagsToBuilderFlags(flags)
889
890	if Bool(library.baseLinker.Properties.Use_version_lib) {
891		if ctx.Host() {
892			versionedOutputFile := outputFile
893			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
894			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
895		} else {
896			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
897			library.distFile = versionedOutputFile
898			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
899		}
900	}
901
902	TransformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, objs.tidyFiles)
903
904	library.coverageOutputFile = TransformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName())
905
906	library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
907
908	ctx.CheckbuildFile(outputFile)
909
910	return outputFile
911}
912
913func (library *libraryDecorator) linkShared(ctx ModuleContext,
914	flags Flags, deps PathDeps, objs Objects) android.Path {
915
916	var linkerDeps android.Paths
917	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
918
919	unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list")
920	forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list")
921	forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list")
922	if !ctx.Darwin() {
923		if unexportedSymbols.Valid() {
924			ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
925		}
926		if forceNotWeakSymbols.Valid() {
927			ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
928		}
929		if forceWeakSymbols.Valid() {
930			ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
931		}
932	} else {
933		if unexportedSymbols.Valid() {
934			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
935			linkerDeps = append(linkerDeps, unexportedSymbols.Path())
936		}
937		if forceNotWeakSymbols.Valid() {
938			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
939			linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
940		}
941		if forceWeakSymbols.Valid() {
942			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
943			linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
944		}
945	}
946	if library.buildStubs() {
947		linkerScriptFlags := "-Wl,--version-script," + library.versionScriptPath.String()
948		flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlags)
949		linkerDeps = append(linkerDeps, library.versionScriptPath)
950	}
951
952	fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
953	outputFile := android.PathForModuleOut(ctx, fileName)
954	ret := outputFile
955
956	var implicitOutputs android.WritablePaths
957	if ctx.Windows() {
958		importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib"))
959
960		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--out-implib="+importLibraryPath.String())
961		implicitOutputs = append(implicitOutputs, importLibraryPath)
962	}
963
964	builderFlags := flagsToBuilderFlags(flags)
965
966	// Optimize out relinking against shared libraries whose interface hasn't changed by
967	// depending on a table of contents file instead of the library itself.
968	tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc")
969	library.tocFile = android.OptionalPathForPath(tocFile)
970	TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags)
971
972	if library.stripper.needsStrip(ctx) {
973		if ctx.Darwin() {
974			builderFlags.stripUseGnuStrip = true
975		}
976		strippedOutputFile := outputFile
977		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
978		library.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
979	}
980	library.unstrippedOutputFile = outputFile
981
982	outputFile = maybeInjectBoringSSLHash(ctx, outputFile, library.Properties.Inject_bssl_hash, fileName)
983
984	if Bool(library.baseLinker.Properties.Use_version_lib) {
985		if ctx.Host() {
986			versionedOutputFile := outputFile
987			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
988			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
989		} else {
990			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
991			library.distFile = versionedOutputFile
992
993			if library.stripper.needsStrip(ctx) {
994				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
995				library.distFile = out
996				library.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
997			}
998
999			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
1000		}
1001	}
1002
1003	sharedLibs := deps.EarlySharedLibs
1004	sharedLibs = append(sharedLibs, deps.SharedLibs...)
1005	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1006
1007	linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
1008	linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
1009	linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
1010	linkerDeps = append(linkerDeps, objs.tidyFiles...)
1011
1012	if Bool(library.Properties.Sort_bss_symbols_by_size) {
1013		unsortedOutputFile := android.PathForModuleOut(ctx, "unsorted", fileName)
1014		TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
1015			deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1016			linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, unsortedOutputFile, implicitOutputs)
1017
1018		symbolOrderingFile := android.PathForModuleOut(ctx, "unsorted", fileName+".symbol_order")
1019		symbolOrderingFlag := library.baseLinker.sortBssSymbolsBySize(ctx, unsortedOutputFile, symbolOrderingFile, builderFlags)
1020		builderFlags.localLdFlags += " " + symbolOrderingFlag
1021		linkerDeps = append(linkerDeps, symbolOrderingFile)
1022	}
1023
1024	TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
1025		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1026		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs)
1027
1028	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
1029	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
1030
1031	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...)
1032	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
1033
1034	library.coverageOutputFile = TransformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
1035	library.linkSAbiDumpFiles(ctx, objs, fileName, ret)
1036
1037	return ret
1038}
1039
1040func (library *libraryDecorator) unstrippedOutputFilePath() android.Path {
1041	return library.unstrippedOutputFile
1042}
1043
1044func (library *libraryDecorator) nativeCoverage() bool {
1045	if library.header() || library.buildStubs() {
1046		return false
1047	}
1048	return true
1049}
1050
1051func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath {
1052	return library.coverageOutputFile
1053}
1054
1055func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
1056	// The logic must be consistent with classifySourceAbiDump.
1057	isNdk := ctx.isNdk()
1058	isLlndkOrVndk := ctx.isLlndkPublic(ctx.Config()) || (ctx.useVndk() && ctx.isVndk())
1059
1060	refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false)
1061	refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true)
1062
1063	if refAbiDumpTextFile.Valid() {
1064		if refAbiDumpGzipFile.Valid() {
1065			ctx.ModuleErrorf(
1066				"Two reference ABI dump files are found: %q and %q. Please delete the stale one.",
1067				refAbiDumpTextFile, refAbiDumpGzipFile)
1068			return nil
1069		}
1070		return refAbiDumpTextFile.Path()
1071	}
1072	if refAbiDumpGzipFile.Valid() {
1073		return UnzipRefDump(ctx, refAbiDumpGzipFile.Path(), fileName)
1074	}
1075	return nil
1076}
1077
1078func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
1079	if library.shouldCreateSourceAbiDump(ctx) {
1080		var vndkVersion string
1081
1082		if ctx.useVndk() {
1083			// For modules linking against vndk, follow its vndk version
1084			vndkVersion = ctx.Module().(*Module).VndkVersion()
1085		} else {
1086			// Regard the other modules as PLATFORM_VNDK_VERSION
1087			vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
1088		}
1089
1090		exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
1091		var SourceAbiFlags []string
1092		for _, dir := range exportIncludeDirs.Strings() {
1093			SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
1094		}
1095		for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes {
1096			SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude)
1097		}
1098		exportedHeaderFlags := strings.Join(SourceAbiFlags, " ")
1099		library.sAbiOutputFile = TransformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags,
1100			android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
1101			library.Properties.Header_abi_checker.Exclude_symbol_versions,
1102			library.Properties.Header_abi_checker.Exclude_symbol_tags)
1103
1104		addLsdumpPath(library.classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String())
1105
1106		refAbiDumpFile := getRefAbiDumpFile(ctx, vndkVersion, fileName)
1107		if refAbiDumpFile != nil {
1108			library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
1109				refAbiDumpFile, fileName, exportedHeaderFlags,
1110				Bool(library.Properties.Header_abi_checker.Check_all_apis),
1111				ctx.isLlndk(ctx.Config()), ctx.isNdk(), ctx.isVndkExt())
1112		}
1113	}
1114}
1115
1116func (library *libraryDecorator) link(ctx ModuleContext,
1117	flags Flags, deps PathDeps, objs Objects) android.Path {
1118
1119	objs = deps.Objs.Copy().Append(objs)
1120	var out android.Path
1121	if library.static() || library.header() {
1122		out = library.linkStatic(ctx, flags, deps, objs)
1123	} else {
1124		out = library.linkShared(ctx, flags, deps, objs)
1125	}
1126
1127	library.exportIncludes(ctx)
1128	library.reexportDirs(deps.ReexportedDirs...)
1129	library.reexportSystemDirs(deps.ReexportedSystemDirs...)
1130	library.reexportFlags(deps.ReexportedFlags...)
1131	library.reexportDeps(deps.ReexportedDeps...)
1132	library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
1133
1134	if Bool(library.Properties.Aidl.Export_aidl_headers) {
1135		if library.baseCompiler.hasSrcExt(".aidl") {
1136			dir := android.PathForModuleGen(ctx, "aidl")
1137			library.reexportDirs(dir)
1138
1139			// TODO: restrict to aidl deps
1140			library.reexportDeps(library.baseCompiler.pathDeps...)
1141			library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...)
1142		}
1143	}
1144
1145	if Bool(library.Properties.Proto.Export_proto_headers) {
1146		if library.baseCompiler.hasSrcExt(".proto") {
1147			var includes android.Paths
1148			if flags.proto.CanonicalPathFromRoot {
1149				includes = append(includes, flags.proto.SubDir)
1150			}
1151			includes = append(includes, flags.proto.Dir)
1152			library.reexportDirs(includes...)
1153
1154			// TODO: restrict to proto deps
1155			library.reexportDeps(library.baseCompiler.pathDeps...)
1156			library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...)
1157		}
1158	}
1159
1160	if library.baseCompiler.hasSrcExt(".sysprop") {
1161		dir := android.PathForModuleGen(ctx, "sysprop", "include")
1162		if library.Properties.Sysprop.Platform != nil {
1163			isProduct := ctx.ProductSpecific() && !ctx.useVndk()
1164			isVendor := ctx.useVndk()
1165			isOwnerPlatform := Bool(library.Properties.Sysprop.Platform)
1166
1167			if !ctx.inRamdisk() && !ctx.inRecovery() && (isProduct || (isOwnerPlatform == isVendor)) {
1168				dir = android.PathForModuleGen(ctx, "sysprop/public", "include")
1169			}
1170		}
1171
1172		library.reexportDirs(dir)
1173		library.reexportDeps(library.baseCompiler.pathDeps...)
1174		library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...)
1175	}
1176
1177	if library.buildStubs() {
1178		library.reexportFlags("-D" + versioningMacroName(ctx.ModuleName()) + "=" + library.stubsVersion())
1179	}
1180
1181	return out
1182}
1183
1184func (library *libraryDecorator) buildStatic() bool {
1185	return library.MutatedProperties.BuildStatic &&
1186		BoolDefault(library.StaticProperties.Static.Enabled, true)
1187}
1188
1189func (library *libraryDecorator) buildShared() bool {
1190	return library.MutatedProperties.BuildShared &&
1191		BoolDefault(library.SharedProperties.Shared.Enabled, true)
1192}
1193
1194func (library *libraryDecorator) getWholeStaticMissingDeps() []string {
1195	return append([]string(nil), library.wholeStaticMissingDeps...)
1196}
1197
1198func (library *libraryDecorator) objs() Objects {
1199	return library.objects
1200}
1201
1202func (library *libraryDecorator) reuseObjs() (Objects, exportedFlagsProducer) {
1203	return library.reuseObjects, &library.flagExporter
1204}
1205
1206func (library *libraryDecorator) toc() android.OptionalPath {
1207	return library.tocFile
1208}
1209
1210func (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
1211	dir := library.baseInstaller.installDir(ctx)
1212	dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir)
1213	target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), "bionic", file.Base())
1214	ctx.InstallAbsoluteSymlink(dir, file.Base(), target)
1215	library.post_install_cmds = append(library.post_install_cmds, makeSymlinkCmd(dirOnDevice, file.Base(), target))
1216}
1217
1218func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
1219	if library.shared() {
1220		if ctx.Device() && ctx.useVndk() {
1221			if ctx.isVndkSp() {
1222				library.baseInstaller.subDir = "vndk-sp"
1223			} else if ctx.isVndk() {
1224				mayUseCoreVariant := true
1225
1226				if ctx.mustUseVendorVariant() {
1227					mayUseCoreVariant = false
1228				}
1229
1230				if ctx.isVndkExt() {
1231					mayUseCoreVariant = false
1232				}
1233
1234				if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
1235					mayUseCoreVariant = false
1236				}
1237
1238				if mayUseCoreVariant {
1239					library.checkSameCoreVariant = true
1240					if ctx.DeviceConfig().VndkUseCoreVariant() {
1241						library.useCoreVariant = true
1242					}
1243				}
1244				library.baseInstaller.subDir = "vndk"
1245			}
1246
1247			// Append a version to vndk or vndk-sp directories on the system partition.
1248			if ctx.isVndk() && !ctx.isVndkExt() {
1249				vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
1250				if vndkVersion != "current" && vndkVersion != "" {
1251					library.baseInstaller.subDir += "-" + vndkVersion
1252				}
1253			}
1254		} else if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
1255			// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
1256			// The original path becomes a symlink to the corresponding file in the
1257			// runtime APEX.
1258			translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
1259			if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && !translatedArch && !ctx.inRamdisk() && !ctx.inRecovery() {
1260				if ctx.Device() {
1261					library.installSymlinkToRuntimeApex(ctx, file)
1262				}
1263				library.baseInstaller.subDir = "bootstrap"
1264			}
1265		} else if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && ctx.isLlndk(ctx.Config()) && !isBionic(ctx.baseModuleName()) {
1266			// Skip installing LLNDK (non-bionic) libraries moved to APEX.
1267			ctx.Module().SkipInstall()
1268		}
1269
1270		library.baseInstaller.install(ctx, file)
1271	}
1272
1273	if Bool(library.Properties.Static_ndk_lib) && library.static() &&
1274		!ctx.useVndk() && !ctx.inRamdisk() && !ctx.inRecovery() && ctx.Device() &&
1275		library.baseLinker.sanitize.isUnsanitizedVariant() &&
1276		!library.buildStubs() && ctx.sdkVersion() == "" {
1277		installPath := getNdkSysrootBase(ctx).Join(
1278			ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base())
1279
1280		ctx.ModuleBuild(pctx, android.ModuleBuildParams{
1281			Rule:        android.Cp,
1282			Description: "install " + installPath.Base(),
1283			Output:      installPath,
1284			Input:       file,
1285		})
1286
1287		library.ndkSysrootPath = installPath
1288	}
1289}
1290
1291func (library *libraryDecorator) everInstallable() bool {
1292	// Only shared and static libraries are installed. Header libraries (which are
1293	// neither static or shared) are not installed.
1294	return library.shared() || library.static()
1295}
1296
1297func (library *libraryDecorator) static() bool {
1298	return library.MutatedProperties.VariantIsStatic
1299}
1300
1301func (library *libraryDecorator) shared() bool {
1302	return library.MutatedProperties.VariantIsShared
1303}
1304
1305func (library *libraryDecorator) header() bool {
1306	return !library.static() && !library.shared()
1307}
1308
1309func (library *libraryDecorator) setStatic() {
1310	library.MutatedProperties.VariantIsStatic = true
1311	library.MutatedProperties.VariantIsShared = false
1312}
1313
1314func (library *libraryDecorator) setShared() {
1315	library.MutatedProperties.VariantIsStatic = false
1316	library.MutatedProperties.VariantIsShared = true
1317}
1318
1319func (library *libraryDecorator) BuildOnlyStatic() {
1320	library.MutatedProperties.BuildShared = false
1321}
1322
1323func (library *libraryDecorator) BuildOnlyShared() {
1324	library.MutatedProperties.BuildStatic = false
1325}
1326
1327func (library *libraryDecorator) HeaderOnly() {
1328	library.MutatedProperties.BuildShared = false
1329	library.MutatedProperties.BuildStatic = false
1330}
1331
1332func (library *libraryDecorator) buildStubs() bool {
1333	return library.MutatedProperties.BuildStubs
1334}
1335
1336func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string {
1337	if library.Properties.Header_abi_checker.Symbol_file != nil {
1338		return library.Properties.Header_abi_checker.Symbol_file
1339	}
1340	if ctx.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
1341		return library.Properties.Stubs.Symbol_file
1342	}
1343	return nil
1344}
1345
1346func (library *libraryDecorator) stubsVersion() string {
1347	return library.MutatedProperties.StubsVersion
1348}
1349
1350func (library *libraryDecorator) isLatestStubVersion() bool {
1351	versions := library.Properties.Stubs.Versions
1352	return versions[len(versions)-1] == library.stubsVersion()
1353}
1354
1355func (library *libraryDecorator) availableFor(what string) bool {
1356	var list []string
1357	if library.static() {
1358		list = library.StaticProperties.Static.Apex_available
1359	} else if library.shared() {
1360		list = library.SharedProperties.Shared.Apex_available
1361	}
1362	if len(list) == 0 {
1363		return false
1364	}
1365	return android.CheckAvailableForApex(what, list)
1366}
1367
1368func (library *libraryDecorator) skipInstall(mod *Module) {
1369	if library.static() && library.buildStatic() && !library.buildStubs() {
1370		// If we're asked to skip installation of a static library (in particular
1371		// when it's not //apex_available:platform) we still want an AndroidMk entry
1372		// for it to ensure we get the relevant NOTICE file targets (cf.
1373		// notice_files.mk) that other libraries might depend on. AndroidMkEntries
1374		// always sets LOCAL_UNINSTALLABLE_MODULE for these entries.
1375		return
1376	}
1377	mod.ModuleBase.SkipInstall()
1378}
1379
1380var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
1381
1382func versioningMacroNamesList(config android.Config) *map[string]string {
1383	return config.Once(versioningMacroNamesListKey, func() interface{} {
1384		m := make(map[string]string)
1385		return &m
1386	}).(*map[string]string)
1387}
1388
1389// alphanumeric and _ characters are preserved.
1390// other characters are all converted to _
1391var charsNotForMacro = regexp.MustCompile("[^a-zA-Z0-9_]+")
1392
1393func versioningMacroName(moduleName string) string {
1394	macroName := charsNotForMacro.ReplaceAllString(moduleName, "_")
1395	macroName = strings.ToUpper(macroName)
1396	return "__" + macroName + "_API__"
1397}
1398
1399func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
1400	module := newModule(hod, android.MultilibBoth)
1401
1402	library := &libraryDecorator{
1403		MutatedProperties: LibraryMutatedProperties{
1404			BuildShared: true,
1405			BuildStatic: true,
1406		},
1407		baseCompiler:  NewBaseCompiler(),
1408		baseLinker:    NewBaseLinker(module.sanitize),
1409		baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem),
1410		sabi:          module.sabi,
1411	}
1412
1413	module.compiler = library
1414	module.linker = library
1415	module.installer = library
1416
1417	return module, library
1418}
1419
1420// connects a shared library to a static library in order to reuse its .o files to avoid
1421// compiling source files twice.
1422func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) {
1423	if staticCompiler, ok := static.compiler.(*libraryDecorator); ok {
1424		sharedCompiler := shared.compiler.(*libraryDecorator)
1425
1426		// Check libraries in addition to cflags, since libraries may be exporting different
1427		// include directories.
1428		if len(staticCompiler.StaticProperties.Static.Cflags) == 0 &&
1429			len(sharedCompiler.SharedProperties.Shared.Cflags) == 0 &&
1430			len(staticCompiler.StaticProperties.Static.Whole_static_libs) == 0 &&
1431			len(sharedCompiler.SharedProperties.Shared.Whole_static_libs) == 0 &&
1432			len(staticCompiler.StaticProperties.Static.Static_libs) == 0 &&
1433			len(sharedCompiler.SharedProperties.Shared.Static_libs) == 0 &&
1434			len(staticCompiler.StaticProperties.Static.Shared_libs) == 0 &&
1435			len(sharedCompiler.SharedProperties.Shared.Shared_libs) == 0 &&
1436			// Compare System_shared_libs properties with nil because empty lists are
1437			// semantically significant for them.
1438			staticCompiler.StaticProperties.Static.System_shared_libs == nil &&
1439			sharedCompiler.SharedProperties.Shared.System_shared_libs == nil {
1440
1441			mctx.AddInterVariantDependency(reuseObjTag, shared, static)
1442			sharedCompiler.baseCompiler.Properties.OriginalSrcs =
1443				sharedCompiler.baseCompiler.Properties.Srcs
1444			sharedCompiler.baseCompiler.Properties.Srcs = nil
1445			sharedCompiler.baseCompiler.Properties.Generated_sources = nil
1446		} else {
1447			// This dep is just to reference static variant from shared variant
1448			mctx.AddInterVariantDependency(staticVariantTag, shared, static)
1449		}
1450	}
1451}
1452
1453func LinkageMutator(mctx android.BottomUpMutatorContext) {
1454	cc_prebuilt := false
1455	if m, ok := mctx.Module().(*Module); ok && m.linker != nil {
1456		_, cc_prebuilt = m.linker.(prebuiltLibraryInterface)
1457	}
1458	if cc_prebuilt {
1459		library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface)
1460
1461		// Differentiate between header only and building an actual static/shared library
1462		if library.buildStatic() || library.buildShared() {
1463			// Always create both the static and shared variants for prebuilt libraries, and then disable the one
1464			// that is not being used.  This allows them to share the name of a cc_library module, which requires that
1465			// all the variants of the cc_library also exist on the prebuilt.
1466			modules := mctx.CreateLocalVariations("static", "shared")
1467			static := modules[0].(*Module)
1468			shared := modules[1].(*Module)
1469
1470			static.linker.(prebuiltLibraryInterface).setStatic()
1471			shared.linker.(prebuiltLibraryInterface).setShared()
1472
1473			if !library.buildStatic() {
1474				static.linker.(prebuiltLibraryInterface).disablePrebuilt()
1475			}
1476			if !library.buildShared() {
1477				shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
1478			}
1479		} else {
1480			// Header only
1481		}
1482
1483	} else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
1484
1485		// Non-cc.Modules may need an empty variant for their mutators.
1486		variations := []string{}
1487		if library.NonCcVariants() {
1488			variations = append(variations, "")
1489		}
1490
1491		if library.BuildStaticVariant() && library.BuildSharedVariant() {
1492			variations := append([]string{"static", "shared"}, variations...)
1493
1494			modules := mctx.CreateLocalVariations(variations...)
1495			static := modules[0].(LinkableInterface)
1496			shared := modules[1].(LinkableInterface)
1497
1498			static.SetStatic()
1499			shared.SetShared()
1500
1501			if _, ok := library.(*Module); ok {
1502				reuseStaticLibrary(mctx, static.(*Module), shared.(*Module))
1503			}
1504		} else if library.BuildStaticVariant() {
1505			variations := append([]string{"static"}, variations...)
1506
1507			modules := mctx.CreateLocalVariations(variations...)
1508			modules[0].(LinkableInterface).SetStatic()
1509		} else if library.BuildSharedVariant() {
1510			variations := append([]string{"shared"}, variations...)
1511
1512			modules := mctx.CreateLocalVariations(variations...)
1513			modules[0].(LinkableInterface).SetShared()
1514		} else if len(variations) > 0 {
1515			mctx.CreateLocalVariations(variations...)
1516		}
1517	}
1518}
1519
1520var stubVersionsKey = android.NewOnceKey("stubVersions")
1521
1522// maps a module name to the list of stubs versions available for the module
1523func stubsVersionsFor(config android.Config) map[string][]string {
1524	return config.Once(stubVersionsKey, func() interface{} {
1525		return make(map[string][]string)
1526	}).(map[string][]string)
1527}
1528
1529var stubsVersionsLock sync.Mutex
1530
1531func LatestStubsVersionFor(config android.Config, name string) string {
1532	versions, ok := stubsVersionsFor(config)[name]
1533	if ok && len(versions) > 0 {
1534		// the versions are alreay sorted in ascending order
1535		return versions[len(versions)-1]
1536	}
1537	return ""
1538}
1539
1540func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
1541	numVersions := make([]int, len(versions))
1542	for i, v := range versions {
1543		numVer, err := android.ApiStrToNum(ctx, v)
1544		if err != nil {
1545			ctx.PropertyErrorf("versions", "%s", err.Error())
1546			return
1547		}
1548		numVersions[i] = numVer
1549	}
1550	if !sort.IsSorted(sort.IntSlice(numVersions)) {
1551		ctx.PropertyErrorf("versions", "not sorted: %v", versions)
1552	}
1553	for i, v := range numVersions {
1554		versions[i] = strconv.Itoa(v)
1555	}
1556}
1557
1558func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
1559	// "" is for the non-stubs variant
1560	versions = append([]string{""}, versions...)
1561
1562	modules := mctx.CreateVariations(versions...)
1563	for i, m := range modules {
1564		if versions[i] != "" {
1565			m.(LinkableInterface).SetBuildStubs()
1566			m.(LinkableInterface).SetStubsVersions(versions[i])
1567		}
1568	}
1569}
1570
1571func VersionVariantAvailable(module interface {
1572	Host() bool
1573	InRamdisk() bool
1574	InRecovery() bool
1575}) bool {
1576	return !module.Host() && !module.InRamdisk() && !module.InRecovery()
1577}
1578
1579// VersionMutator splits a module into the mandatory non-stubs variant
1580// (which is unnamed) and zero or more stubs variants.
1581func VersionMutator(mctx android.BottomUpMutatorContext) {
1582	if library, ok := mctx.Module().(LinkableInterface); ok && VersionVariantAvailable(library) {
1583		if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 &&
1584			!library.IsSdkVariant() {
1585			versions := library.StubsVersions()
1586			normalizeVersions(mctx, versions)
1587			if mctx.Failed() {
1588				return
1589			}
1590
1591			stubsVersionsLock.Lock()
1592			defer stubsVersionsLock.Unlock()
1593			// save the list of versions for later use
1594			stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions
1595
1596			createVersionVariations(mctx, versions)
1597			return
1598		}
1599
1600		if c, ok := library.(*Module); ok && c.IsStubs() {
1601			stubsVersionsLock.Lock()
1602			defer stubsVersionsLock.Unlock()
1603			// For LLNDK llndk_library, we borrow vstubs.ersions from its implementation library.
1604			// Since llndk_library has dependency to its implementation library,
1605			// we can safely access stubsVersionsFor() with its baseModuleName.
1606			versions := stubsVersionsFor(mctx.Config())[c.BaseModuleName()]
1607			// save the list of versions for later use
1608			stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions
1609
1610			createVersionVariations(mctx, versions)
1611			return
1612		}
1613
1614		mctx.CreateVariations("")
1615		return
1616	}
1617	if genrule, ok := mctx.Module().(*genrule.Module); ok {
1618		if _, ok := genrule.Extra.(*GenruleExtraProperties); ok {
1619			if VersionVariantAvailable(genrule) {
1620				mctx.CreateVariations("")
1621				return
1622			}
1623		}
1624	}
1625}
1626
1627// maybeInjectBoringSSLHash adds a rule to run bssl_inject_hash on the output file if the module has the
1628// inject_bssl_hash or if any static library dependencies have inject_bssl_hash set.  It returns the output path
1629// that the linked output file should be written to.
1630// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
1631func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.ModuleOutPath,
1632	inject *bool, fileName string) android.ModuleOutPath {
1633	// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
1634	injectBoringSSLHash := Bool(inject)
1635	ctx.VisitDirectDeps(func(dep android.Module) {
1636		tag := ctx.OtherModuleDependencyTag(dep)
1637		if tag == StaticDepTag || tag == staticExportDepTag || tag == wholeStaticDepTag || tag == lateStaticDepTag {
1638			if cc, ok := dep.(*Module); ok {
1639				if library, ok := cc.linker.(*libraryDecorator); ok {
1640					if Bool(library.Properties.Inject_bssl_hash) {
1641						injectBoringSSLHash = true
1642					}
1643				}
1644			}
1645		}
1646	})
1647	if injectBoringSSLHash {
1648		hashedOutputfile := outputFile
1649		outputFile = android.PathForModuleOut(ctx, "unhashed", fileName)
1650
1651		rule := android.NewRuleBuilder()
1652		rule.Command().
1653			BuiltTool(ctx, "bssl_inject_hash").
1654			Flag("-sha256").
1655			FlagWithInput("-in-object ", outputFile).
1656			FlagWithOutput("-o ", hashedOutputfile)
1657		rule.Build(pctx, ctx, "injectCryptoHash", "inject crypto hash")
1658	}
1659
1660	return outputFile
1661}
1662