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