• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 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
17// This file contains the module types for compiling C/C++ for Android, and converts the properties
18// into the flags and filenames necessary to pass to the compiler.  The final creation of the rules
19// is handled in builder.go
20
21import (
22	"strconv"
23	"strings"
24
25	"github.com/google/blueprint"
26	"github.com/google/blueprint/proptools"
27
28	"android/soong/android"
29	"android/soong/cc/config"
30	"android/soong/genrule"
31)
32
33func init() {
34	android.RegisterModuleType("cc_defaults", defaultsFactory)
35
36	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
37		ctx.BottomUp("image", ImageMutator).Parallel()
38		ctx.BottomUp("link", LinkageMutator).Parallel()
39		ctx.BottomUp("vndk", VndkMutator).Parallel()
40		ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
41		ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
42		ctx.BottomUp("version", VersionMutator).Parallel()
43		ctx.BottomUp("begin", BeginMutator).Parallel()
44		ctx.BottomUp("sysprop", SyspropMutator).Parallel()
45	})
46
47	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
48		ctx.TopDown("asan_deps", sanitizerDepsMutator(asan))
49		ctx.BottomUp("asan", sanitizerMutator(asan)).Parallel()
50
51		ctx.TopDown("hwasan_deps", sanitizerDepsMutator(hwasan))
52		ctx.BottomUp("hwasan", sanitizerMutator(hwasan)).Parallel()
53
54		ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi))
55		ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel()
56
57		ctx.TopDown("scs_deps", sanitizerDepsMutator(scs))
58		ctx.BottomUp("scs", sanitizerMutator(scs)).Parallel()
59
60		ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
61		ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
62
63		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
64		ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
65
66		ctx.BottomUp("coverage", coverageMutator).Parallel()
67		ctx.TopDown("vndk_deps", sabiDepsMutator)
68
69		ctx.TopDown("lto_deps", ltoDepsMutator)
70		ctx.BottomUp("lto", ltoMutator).Parallel()
71
72		ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
73	})
74
75	pctx.Import("android/soong/cc/config")
76}
77
78type Deps struct {
79	SharedLibs, LateSharedLibs                  []string
80	StaticLibs, LateStaticLibs, WholeStaticLibs []string
81	HeaderLibs                                  []string
82	RuntimeLibs                                 []string
83
84	ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
85
86	ObjFiles []string
87
88	GeneratedSources []string
89	GeneratedHeaders []string
90
91	ReexportGeneratedHeaders []string
92
93	CrtBegin, CrtEnd string
94
95	// Used for host bionic
96	LinkerFlagsFile string
97	DynamicLinker   string
98}
99
100type PathDeps struct {
101	// Paths to .so files
102	SharedLibs, EarlySharedLibs, LateSharedLibs android.Paths
103	// Paths to the dependencies to use for .so files (.so.toc files)
104	SharedLibsDeps, EarlySharedLibsDeps, LateSharedLibsDeps android.Paths
105	// Paths to .a files
106	StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
107
108	// Paths to .o files
109	Objs               Objects
110	StaticLibObjs      Objects
111	WholeStaticLibObjs Objects
112
113	// Paths to generated source files
114	GeneratedSources android.Paths
115	GeneratedHeaders android.Paths
116
117	Flags, ReexportedFlags []string
118	ReexportedFlagsDeps    android.Paths
119
120	// Paths to crt*.o files
121	CrtBegin, CrtEnd android.OptionalPath
122
123	// Path to the file container flags to use with the linker
124	LinkerFlagsFile android.OptionalPath
125
126	// Path to the dynamic linker binary
127	DynamicLinker android.OptionalPath
128}
129
130type Flags struct {
131	GlobalFlags     []string // Flags that apply to C, C++, and assembly source files
132	ArFlags         []string // Flags that apply to ar
133	AsFlags         []string // Flags that apply to assembly source files
134	CFlags          []string // Flags that apply to C and C++ source files
135	ToolingCFlags   []string // Flags that apply to C and C++ source files parsed by clang LibTooling tools
136	ConlyFlags      []string // Flags that apply to C source files
137	CppFlags        []string // Flags that apply to C++ source files
138	ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools
139	YaccFlags       []string // Flags that apply to Yacc source files
140	aidlFlags       []string // Flags that apply to aidl source files
141	rsFlags         []string // Flags that apply to renderscript source files
142	LdFlags         []string // Flags that apply to linker command lines
143	libFlags        []string // Flags to add libraries early to the link order
144	TidyFlags       []string // Flags that apply to clang-tidy
145	SAbiFlags       []string // Flags that apply to header-abi-dumper
146	YasmFlags       []string // Flags that apply to yasm assembly source files
147
148	// Global include flags that apply to C, C++, and assembly source files
149	// These must be after any module include flags, which will be in GlobalFlags.
150	SystemIncludeFlags []string
151
152	Toolchain config.Toolchain
153	Tidy      bool
154	Coverage  bool
155	SAbiDump  bool
156
157	RequiredInstructionSet string
158	DynamicLinker          string
159
160	CFlagsDeps  android.Paths // Files depended on by compiler flags
161	LdFlagsDeps android.Paths // Files depended on by linker flags
162
163	GroupStaticLibs bool
164
165	proto            android.ProtoFlags
166	protoC           bool // Whether to use C instead of C++
167	protoOptionsFile bool // Whether to look for a .options file next to the .proto
168}
169
170type ObjectLinkerProperties struct {
171	// names of other cc_object modules to link into this module using partial linking
172	Objs []string `android:"arch_variant"`
173
174	// if set, add an extra objcopy --prefix-symbols= step
175	Prefix_symbols *string
176}
177
178// Properties used to compile all C or C++ modules
179type BaseProperties struct {
180	// Deprecated. true is the default, false is invalid.
181	Clang *bool `android:"arch_variant"`
182
183	// Minimum sdk version supported when compiling against the ndk
184	Sdk_version *string
185
186	AndroidMkSharedLibs       []string `blueprint:"mutated"`
187	AndroidMkStaticLibs       []string `blueprint:"mutated"`
188	AndroidMkRuntimeLibs      []string `blueprint:"mutated"`
189	AndroidMkWholeStaticLibs  []string `blueprint:"mutated"`
190	HideFromMake              bool     `blueprint:"mutated"`
191	PreventInstall            bool     `blueprint:"mutated"`
192	ApexesProvidingSharedLibs []string `blueprint:"mutated"`
193
194	UseVndk bool `blueprint:"mutated"`
195
196	// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
197	// file
198	Logtags []string
199
200	// Make this module available when building for recovery
201	Recovery_available *bool
202
203	InRecovery bool `blueprint:"mutated"`
204
205	// Allows this module to use non-APEX version of libraries. Useful
206	// for building binaries that are started before APEXes are activated.
207	Bootstrap *bool
208}
209
210type VendorProperties struct {
211	// whether this module should be allowed to be directly depended by other
212	// modules with `vendor: true`, `proprietary: true`, or `vendor_available:true`.
213	// If set to true, two variants will be built separately, one like
214	// normal, and the other limited to the set of libraries and headers
215	// that are exposed to /vendor modules.
216	//
217	// The vendor variant may be used with a different (newer) /system,
218	// so it shouldn't have any unversioned runtime dependencies, or
219	// make assumptions about the system that may not be true in the
220	// future.
221	//
222	// If set to false, this module becomes inaccessible from /vendor modules.
223	//
224	// Default value is true when vndk: {enabled: true} or vendor: true.
225	//
226	// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
227	Vendor_available *bool
228
229	// whether this module is capable of being loaded with other instance
230	// (possibly an older version) of the same module in the same process.
231	// Currently, a shared library that is a member of VNDK (vndk: {enabled: true})
232	// can be double loaded in a vendor process if the library is also a
233	// (direct and indirect) dependency of an LLNDK library. Such libraries must be
234	// explicitly marked as `double_loadable: true` by the owner, or the dependency
235	// from the LLNDK lib should be cut if the lib is not designed to be double loaded.
236	Double_loadable *bool
237}
238
239type ModuleContextIntf interface {
240	static() bool
241	staticBinary() bool
242	toolchain() config.Toolchain
243	useSdk() bool
244	sdkVersion() string
245	useVndk() bool
246	isNdk() bool
247	isLlndk() bool
248	isLlndkPublic() bool
249	isVndkPrivate() bool
250	isVndk() bool
251	isVndkSp() bool
252	isVndkExt() bool
253	inRecovery() bool
254	shouldCreateVndkSourceAbiDump() bool
255	selectedStl() string
256	baseModuleName() string
257	getVndkExtendsModuleName() string
258	isPgoCompile() bool
259	isNDKStubLibrary() bool
260	useClangLld(actx ModuleContext) bool
261	apexName() string
262	hasStubsVariants() bool
263	isStubs() bool
264	bootstrap() bool
265	mustUseVendorVariant() bool
266	nativeCoverage() bool
267}
268
269type ModuleContext interface {
270	android.ModuleContext
271	ModuleContextIntf
272}
273
274type BaseModuleContext interface {
275	android.BaseContext
276	ModuleContextIntf
277}
278
279type DepsContext interface {
280	android.BottomUpMutatorContext
281	ModuleContextIntf
282}
283
284type feature interface {
285	begin(ctx BaseModuleContext)
286	deps(ctx DepsContext, deps Deps) Deps
287	flags(ctx ModuleContext, flags Flags) Flags
288	props() []interface{}
289}
290
291type compiler interface {
292	compilerInit(ctx BaseModuleContext)
293	compilerDeps(ctx DepsContext, deps Deps) Deps
294	compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags
295	compilerProps() []interface{}
296
297	appendCflags([]string)
298	appendAsflags([]string)
299	compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects
300}
301
302type linker interface {
303	linkerInit(ctx BaseModuleContext)
304	linkerDeps(ctx DepsContext, deps Deps) Deps
305	linkerFlags(ctx ModuleContext, flags Flags) Flags
306	linkerProps() []interface{}
307	useClangLld(actx ModuleContext) bool
308
309	link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path
310	appendLdflags([]string)
311	unstrippedOutputFilePath() android.Path
312
313	nativeCoverage() bool
314}
315
316type installer interface {
317	installerProps() []interface{}
318	install(ctx ModuleContext, path android.Path)
319	inData() bool
320	inSanitizerDir() bool
321	hostToolPath() android.OptionalPath
322	relativeInstallPath() string
323}
324
325type dependencyTag struct {
326	blueprint.BaseDependencyTag
327	name    string
328	library bool
329
330	reexportFlags bool
331
332	explicitlyVersioned bool
333}
334
335var (
336	sharedDepTag          = dependencyTag{name: "shared", library: true}
337	sharedExportDepTag    = dependencyTag{name: "shared", library: true, reexportFlags: true}
338	earlySharedDepTag     = dependencyTag{name: "early_shared", library: true}
339	lateSharedDepTag      = dependencyTag{name: "late shared", library: true}
340	staticDepTag          = dependencyTag{name: "static", library: true}
341	staticExportDepTag    = dependencyTag{name: "static", library: true, reexportFlags: true}
342	lateStaticDepTag      = dependencyTag{name: "late static", library: true}
343	wholeStaticDepTag     = dependencyTag{name: "whole static", library: true, reexportFlags: true}
344	headerDepTag          = dependencyTag{name: "header", library: true}
345	headerExportDepTag    = dependencyTag{name: "header", library: true, reexportFlags: true}
346	genSourceDepTag       = dependencyTag{name: "gen source"}
347	genHeaderDepTag       = dependencyTag{name: "gen header"}
348	genHeaderExportDepTag = dependencyTag{name: "gen header", reexportFlags: true}
349	objDepTag             = dependencyTag{name: "obj"}
350	crtBeginDepTag        = dependencyTag{name: "crtbegin"}
351	crtEndDepTag          = dependencyTag{name: "crtend"}
352	linkerFlagsDepTag     = dependencyTag{name: "linker flags file"}
353	dynamicLinkerDepTag   = dependencyTag{name: "dynamic linker"}
354	reuseObjTag           = dependencyTag{name: "reuse objects"}
355	staticVariantTag      = dependencyTag{name: "static variant"}
356	ndkStubDepTag         = dependencyTag{name: "ndk stub", library: true}
357	ndkLateStubDepTag     = dependencyTag{name: "ndk late stub", library: true}
358	vndkExtDepTag         = dependencyTag{name: "vndk extends", library: true}
359	runtimeDepTag         = dependencyTag{name: "runtime lib"}
360)
361
362// Module contains the properties and members used by all C/C++ module types, and implements
363// the blueprint.Module interface.  It delegates to compiler, linker, and installer interfaces
364// to construct the output file.  Behavior can be customized with a Customizer interface
365type Module struct {
366	android.ModuleBase
367	android.DefaultableModuleBase
368	android.ApexModuleBase
369
370	Properties       BaseProperties
371	VendorProperties VendorProperties
372
373	// initialize before calling Init
374	hod      android.HostOrDeviceSupported
375	multilib android.Multilib
376
377	// delegates, initialize before calling Init
378	features  []feature
379	compiler  compiler
380	linker    linker
381	installer installer
382	stl       *stl
383	sanitize  *sanitize
384	coverage  *coverage
385	sabi      *sabi
386	vndkdep   *vndkdep
387	lto       *lto
388	pgo       *pgo
389	xom       *xom
390
391	androidMkSharedLibDeps []string
392
393	outputFile android.OptionalPath
394
395	cachedToolchain config.Toolchain
396
397	subAndroidMkOnce map[subAndroidMkProvider]bool
398
399	// Flags used to compile this module
400	flags Flags
401
402	// When calling a linker, if module A depends on module B, then A must precede B in its command
403	// line invocation. depsInLinkOrder stores the proper ordering of all of the transitive
404	// deps of this module
405	depsInLinkOrder android.Paths
406
407	// only non-nil when this is a shared library that reuses the objects of a static library
408	staticVariant *Module
409}
410
411func (c *Module) OutputFile() android.OptionalPath {
412	return c.outputFile
413}
414
415func (c *Module) UnstrippedOutputFile() android.Path {
416	if c.linker != nil {
417		return c.linker.unstrippedOutputFilePath()
418	}
419	return nil
420}
421
422func (c *Module) RelativeInstallPath() string {
423	if c.installer != nil {
424		return c.installer.relativeInstallPath()
425	}
426	return ""
427}
428
429func (c *Module) Init() android.Module {
430	c.AddProperties(&c.Properties, &c.VendorProperties)
431	if c.compiler != nil {
432		c.AddProperties(c.compiler.compilerProps()...)
433	}
434	if c.linker != nil {
435		c.AddProperties(c.linker.linkerProps()...)
436	}
437	if c.installer != nil {
438		c.AddProperties(c.installer.installerProps()...)
439	}
440	if c.stl != nil {
441		c.AddProperties(c.stl.props()...)
442	}
443	if c.sanitize != nil {
444		c.AddProperties(c.sanitize.props()...)
445	}
446	if c.coverage != nil {
447		c.AddProperties(c.coverage.props()...)
448	}
449	if c.sabi != nil {
450		c.AddProperties(c.sabi.props()...)
451	}
452	if c.vndkdep != nil {
453		c.AddProperties(c.vndkdep.props()...)
454	}
455	if c.lto != nil {
456		c.AddProperties(c.lto.props()...)
457	}
458	if c.pgo != nil {
459		c.AddProperties(c.pgo.props()...)
460	}
461	if c.xom != nil {
462		c.AddProperties(c.xom.props()...)
463	}
464	for _, feature := range c.features {
465		c.AddProperties(feature.props()...)
466	}
467
468	c.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
469		switch class {
470		case android.Device:
471			return ctx.Config().DevicePrefer32BitExecutables()
472		case android.HostCross:
473			// Windows builds always prefer 32-bit
474			return true
475		default:
476			return false
477		}
478	})
479	android.InitAndroidArchModule(c, c.hod, c.multilib)
480
481	android.InitDefaultableModule(c)
482
483	android.InitApexModule(c)
484
485	return c
486}
487
488// Returns true for dependency roots (binaries)
489// TODO(ccross): also handle dlopenable libraries
490func (c *Module) isDependencyRoot() bool {
491	if root, ok := c.linker.(interface {
492		isDependencyRoot() bool
493	}); ok {
494		return root.isDependencyRoot()
495	}
496	return false
497}
498
499func (c *Module) useVndk() bool {
500	return c.Properties.UseVndk
501}
502
503func (c *Module) isCoverageVariant() bool {
504	return c.coverage.Properties.IsCoverageVariant
505}
506
507func (c *Module) isNdk() bool {
508	return inList(c.Name(), ndkMigratedLibs)
509}
510
511func (c *Module) isLlndk() bool {
512	// Returns true for both LLNDK (public) and LLNDK-private libs.
513	return inList(c.Name(), llndkLibraries)
514}
515
516func (c *Module) isLlndkPublic() bool {
517	// Returns true only for LLNDK (public) libs.
518	return c.isLlndk() && !c.isVndkPrivate()
519}
520
521func (c *Module) isVndkPrivate() bool {
522	// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
523	return inList(c.Name(), vndkPrivateLibraries)
524}
525
526func (c *Module) isVndk() bool {
527	if vndkdep := c.vndkdep; vndkdep != nil {
528		return vndkdep.isVndk()
529	}
530	return false
531}
532
533func (c *Module) isPgoCompile() bool {
534	if pgo := c.pgo; pgo != nil {
535		return pgo.Properties.PgoCompile
536	}
537	return false
538}
539
540func (c *Module) isNDKStubLibrary() bool {
541	if _, ok := c.compiler.(*stubDecorator); ok {
542		return true
543	}
544	return false
545}
546
547func (c *Module) isVndkSp() bool {
548	if vndkdep := c.vndkdep; vndkdep != nil {
549		return vndkdep.isVndkSp()
550	}
551	return false
552}
553
554func (c *Module) isVndkExt() bool {
555	if vndkdep := c.vndkdep; vndkdep != nil {
556		return vndkdep.isVndkExt()
557	}
558	return false
559}
560
561func (c *Module) mustUseVendorVariant() bool {
562	return c.isVndkSp() || inList(c.Name(), config.VndkMustUseVendorVariantList)
563}
564
565func (c *Module) getVndkExtendsModuleName() string {
566	if vndkdep := c.vndkdep; vndkdep != nil {
567		return vndkdep.getVndkExtendsModuleName()
568	}
569	return ""
570}
571
572// Returns true only when this module is configured to have core and vendor
573// variants.
574func (c *Module) hasVendorVariant() bool {
575	return c.isVndk() || Bool(c.VendorProperties.Vendor_available)
576}
577
578func (c *Module) inRecovery() bool {
579	return c.Properties.InRecovery || c.ModuleBase.InstallInRecovery()
580}
581
582func (c *Module) onlyInRecovery() bool {
583	return c.ModuleBase.InstallInRecovery()
584}
585
586func (c *Module) IsStubs() bool {
587	if library, ok := c.linker.(*libraryDecorator); ok {
588		return library.buildStubs()
589	} else if _, ok := c.linker.(*llndkStubDecorator); ok {
590		return true
591	}
592	return false
593}
594
595func (c *Module) HasStubsVariants() bool {
596	if library, ok := c.linker.(*libraryDecorator); ok {
597		return len(library.Properties.Stubs.Versions) > 0
598	}
599	return false
600}
601
602func (c *Module) bootstrap() bool {
603	return Bool(c.Properties.Bootstrap)
604}
605
606func (c *Module) nativeCoverage() bool {
607	return c.linker != nil && c.linker.nativeCoverage()
608}
609
610func isBionic(name string) bool {
611	switch name {
612	case "libc", "libm", "libdl", "linker":
613		return true
614	}
615	return false
616}
617
618type baseModuleContext struct {
619	android.BaseContext
620	moduleContextImpl
621}
622
623type depsContext struct {
624	android.BottomUpMutatorContext
625	moduleContextImpl
626}
627
628type moduleContext struct {
629	android.ModuleContext
630	moduleContextImpl
631}
632
633func (ctx *moduleContext) SocSpecific() bool {
634	return ctx.ModuleContext.SocSpecific() ||
635		(ctx.mod.hasVendorVariant() && ctx.mod.useVndk() && !ctx.mod.isVndk())
636}
637
638type moduleContextImpl struct {
639	mod *Module
640	ctx BaseModuleContext
641}
642
643func (ctx *moduleContextImpl) toolchain() config.Toolchain {
644	return ctx.mod.toolchain(ctx.ctx)
645}
646
647func (ctx *moduleContextImpl) static() bool {
648	return ctx.mod.static()
649}
650
651func (ctx *moduleContextImpl) staticBinary() bool {
652	return ctx.mod.staticBinary()
653}
654
655func (ctx *moduleContextImpl) useSdk() bool {
656	if ctx.ctx.Device() && !ctx.useVndk() && !ctx.inRecovery() && !ctx.ctx.Fuchsia() {
657		return String(ctx.mod.Properties.Sdk_version) != ""
658	}
659	return false
660}
661
662func (ctx *moduleContextImpl) sdkVersion() string {
663	if ctx.ctx.Device() {
664		if ctx.useVndk() {
665			vndk_ver := ctx.ctx.DeviceConfig().VndkVersion()
666			if vndk_ver == "current" {
667				platform_vndk_ver := ctx.ctx.DeviceConfig().PlatformVndkVersion()
668				if inList(platform_vndk_ver, ctx.ctx.Config().PlatformVersionCombinedCodenames()) {
669					return "current"
670				}
671				return platform_vndk_ver
672			}
673			return vndk_ver
674		}
675		return String(ctx.mod.Properties.Sdk_version)
676	}
677	return ""
678}
679
680func (ctx *moduleContextImpl) useVndk() bool {
681	return ctx.mod.useVndk()
682}
683
684func (ctx *moduleContextImpl) isNdk() bool {
685	return ctx.mod.isNdk()
686}
687
688func (ctx *moduleContextImpl) isLlndk() bool {
689	return ctx.mod.isLlndk()
690}
691
692func (ctx *moduleContextImpl) isLlndkPublic() bool {
693	return ctx.mod.isLlndkPublic()
694}
695
696func (ctx *moduleContextImpl) isVndkPrivate() bool {
697	return ctx.mod.isVndkPrivate()
698}
699
700func (ctx *moduleContextImpl) isVndk() bool {
701	return ctx.mod.isVndk()
702}
703
704func (ctx *moduleContextImpl) isPgoCompile() bool {
705	return ctx.mod.isPgoCompile()
706}
707
708func (ctx *moduleContextImpl) isNDKStubLibrary() bool {
709	return ctx.mod.isNDKStubLibrary()
710}
711
712func (ctx *moduleContextImpl) isVndkSp() bool {
713	return ctx.mod.isVndkSp()
714}
715
716func (ctx *moduleContextImpl) isVndkExt() bool {
717	return ctx.mod.isVndkExt()
718}
719
720func (ctx *moduleContextImpl) mustUseVendorVariant() bool {
721	return ctx.mod.mustUseVendorVariant()
722}
723
724func (ctx *moduleContextImpl) inRecovery() bool {
725	return ctx.mod.inRecovery()
726}
727
728// Check whether ABI dumps should be created for this module.
729func (ctx *moduleContextImpl) shouldCreateVndkSourceAbiDump() bool {
730	if ctx.ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") {
731		return false
732	}
733
734	if ctx.ctx.Fuchsia() {
735		return false
736	}
737
738	if sanitize := ctx.mod.sanitize; sanitize != nil {
739		if !sanitize.isVariantOnProductionDevice() {
740			return false
741		}
742	}
743	if !ctx.ctx.Device() {
744		// Host modules do not need ABI dumps.
745		return false
746	}
747	if !ctx.mod.IsForPlatform() {
748		// APEX variants do not need ABI dumps.
749		return false
750	}
751	if ctx.isNdk() {
752		return true
753	}
754	if ctx.isLlndkPublic() {
755		return true
756	}
757	if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate() {
758		// Return true if this is VNDK-core, VNDK-SP, or VNDK-Ext and this is not
759		// VNDK-private.
760		return true
761	}
762	return false
763}
764
765func (ctx *moduleContextImpl) selectedStl() string {
766	if stl := ctx.mod.stl; stl != nil {
767		return stl.Properties.SelectedStl
768	}
769	return ""
770}
771
772func (ctx *moduleContextImpl) useClangLld(actx ModuleContext) bool {
773	return ctx.mod.linker.useClangLld(actx)
774}
775
776func (ctx *moduleContextImpl) baseModuleName() string {
777	return ctx.mod.ModuleBase.BaseModuleName()
778}
779
780func (ctx *moduleContextImpl) getVndkExtendsModuleName() string {
781	return ctx.mod.getVndkExtendsModuleName()
782}
783
784func (ctx *moduleContextImpl) apexName() string {
785	return ctx.mod.ApexName()
786}
787
788func (ctx *moduleContextImpl) hasStubsVariants() bool {
789	return ctx.mod.HasStubsVariants()
790}
791
792func (ctx *moduleContextImpl) isStubs() bool {
793	return ctx.mod.IsStubs()
794}
795
796func (ctx *moduleContextImpl) bootstrap() bool {
797	return ctx.mod.bootstrap()
798}
799
800func (ctx *moduleContextImpl) nativeCoverage() bool {
801	return ctx.mod.nativeCoverage()
802}
803
804func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
805	return &Module{
806		hod:      hod,
807		multilib: multilib,
808	}
809}
810
811func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
812	module := newBaseModule(hod, multilib)
813	module.features = []feature{
814		&tidyFeature{},
815	}
816	module.stl = &stl{}
817	module.sanitize = &sanitize{}
818	module.coverage = &coverage{}
819	module.sabi = &sabi{}
820	module.vndkdep = &vndkdep{}
821	module.lto = &lto{}
822	module.pgo = &pgo{}
823	module.xom = &xom{}
824	return module
825}
826
827func (c *Module) Prebuilt() *android.Prebuilt {
828	if p, ok := c.linker.(prebuiltLinkerInterface); ok {
829		return p.prebuilt()
830	}
831	return nil
832}
833
834func (c *Module) Name() string {
835	name := c.ModuleBase.Name()
836	if p, ok := c.linker.(interface {
837		Name(string) string
838	}); ok {
839		name = p.Name(name)
840	}
841	return name
842}
843
844func (c *Module) Symlinks() []string {
845	if p, ok := c.installer.(interface {
846		symlinkList() []string
847	}); ok {
848		return p.symlinkList()
849	}
850	return nil
851}
852
853// orderDeps reorders dependencies into a list such that if module A depends on B, then
854// A will precede B in the resultant list.
855// This is convenient for passing into a linker.
856// Note that directSharedDeps should be the analogous static library for each shared lib dep
857func orderDeps(directStaticDeps []android.Path, directSharedDeps []android.Path, allTransitiveDeps map[android.Path][]android.Path) (orderedAllDeps []android.Path, orderedDeclaredDeps []android.Path) {
858	// If A depends on B, then
859	//   Every list containing A will also contain B later in the list
860	//   So, after concatenating all lists, the final instance of B will have come from the same
861	//     original list as the final instance of A
862	//   So, the final instance of B will be later in the concatenation than the final A
863	//   So, keeping only the final instance of A and of B ensures that A is earlier in the output
864	//     list than B
865	for _, dep := range directStaticDeps {
866		orderedAllDeps = append(orderedAllDeps, dep)
867		orderedAllDeps = append(orderedAllDeps, allTransitiveDeps[dep]...)
868	}
869	for _, dep := range directSharedDeps {
870		orderedAllDeps = append(orderedAllDeps, dep)
871		orderedAllDeps = append(orderedAllDeps, allTransitiveDeps[dep]...)
872	}
873
874	orderedAllDeps = android.LastUniquePaths(orderedAllDeps)
875
876	// We don't want to add any new dependencies into directStaticDeps (to allow the caller to
877	// intentionally exclude or replace any unwanted transitive dependencies), so we limit the
878	// resultant list to only what the caller has chosen to include in directStaticDeps
879	_, orderedDeclaredDeps = android.FilterPathList(orderedAllDeps, directStaticDeps)
880
881	return orderedAllDeps, orderedDeclaredDeps
882}
883
884func orderStaticModuleDeps(module *Module, staticDeps []*Module, sharedDeps []*Module) (results []android.Path) {
885	// convert Module to Path
886	allTransitiveDeps := make(map[android.Path][]android.Path, len(staticDeps))
887	staticDepFiles := []android.Path{}
888	for _, dep := range staticDeps {
889		allTransitiveDeps[dep.outputFile.Path()] = dep.depsInLinkOrder
890		staticDepFiles = append(staticDepFiles, dep.outputFile.Path())
891	}
892	sharedDepFiles := []android.Path{}
893	for _, sharedDep := range sharedDeps {
894		staticAnalogue := sharedDep.staticVariant
895		if staticAnalogue != nil {
896			allTransitiveDeps[staticAnalogue.outputFile.Path()] = staticAnalogue.depsInLinkOrder
897			sharedDepFiles = append(sharedDepFiles, staticAnalogue.outputFile.Path())
898		}
899	}
900
901	// reorder the dependencies based on transitive dependencies
902	module.depsInLinkOrder, results = orderDeps(staticDepFiles, sharedDepFiles, allTransitiveDeps)
903
904	return results
905}
906
907func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
908	ctx := &moduleContext{
909		ModuleContext: actx,
910		moduleContextImpl: moduleContextImpl{
911			mod: c,
912		},
913	}
914	ctx.ctx = ctx
915
916	deps := c.depsToPaths(ctx)
917	if ctx.Failed() {
918		return
919	}
920
921	if c.Properties.Clang != nil && *c.Properties.Clang == false {
922		ctx.PropertyErrorf("clang", "false (GCC) is no longer supported")
923	}
924
925	flags := Flags{
926		Toolchain: c.toolchain(ctx),
927	}
928	if c.compiler != nil {
929		flags = c.compiler.compilerFlags(ctx, flags, deps)
930	}
931	if c.linker != nil {
932		flags = c.linker.linkerFlags(ctx, flags)
933	}
934	if c.stl != nil {
935		flags = c.stl.flags(ctx, flags)
936	}
937	if c.sanitize != nil {
938		flags = c.sanitize.flags(ctx, flags)
939	}
940	if c.coverage != nil {
941		flags = c.coverage.flags(ctx, flags)
942	}
943	if c.lto != nil {
944		flags = c.lto.flags(ctx, flags)
945	}
946	if c.pgo != nil {
947		flags = c.pgo.flags(ctx, flags)
948	}
949	if c.xom != nil {
950		flags = c.xom.flags(ctx, flags)
951	}
952	for _, feature := range c.features {
953		flags = feature.flags(ctx, flags)
954	}
955	if ctx.Failed() {
956		return
957	}
958
959	flags.CFlags, _ = filterList(flags.CFlags, config.IllegalFlags)
960	flags.CppFlags, _ = filterList(flags.CppFlags, config.IllegalFlags)
961	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, config.IllegalFlags)
962
963	flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)
964	c.flags = flags
965	// We need access to all the flags seen by a source file.
966	if c.sabi != nil {
967		flags = c.sabi.flags(ctx, flags)
968	}
969	// Optimization to reduce size of build.ninja
970	// Replace the long list of flags for each file with a module-local variable
971	ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
972	ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
973	ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
974	flags.CFlags = []string{"$cflags"}
975	flags.CppFlags = []string{"$cppflags"}
976	flags.AsFlags = []string{"$asflags"}
977
978	var objs Objects
979	if c.compiler != nil {
980		objs = c.compiler.compile(ctx, flags, deps)
981		if ctx.Failed() {
982			return
983		}
984	}
985
986	if c.linker != nil {
987		outputFile := c.linker.link(ctx, flags, deps, objs)
988		if ctx.Failed() {
989			return
990		}
991		c.outputFile = android.OptionalPathForPath(outputFile)
992
993		// If a lib is directly included in any of the APEXes, unhide the stubs
994		// variant having the latest version gets visible to make. In addition,
995		// the non-stubs variant is renamed to <libname>.bootstrap. This is to
996		// force anything in the make world to link against the stubs library.
997		// (unless it is explicitly referenced via .bootstrap suffix or the
998		// module is marked with 'bootstrap: true').
999		if c.HasStubsVariants() &&
1000			android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) &&
1001			!c.inRecovery() && !c.useVndk() && !c.static() && !c.isCoverageVariant() &&
1002			c.IsStubs() {
1003			c.Properties.HideFromMake = false // unhide
1004			// Note: this is still non-installable
1005		}
1006	}
1007
1008	if c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid() {
1009		c.installer.install(ctx, c.outputFile.Path())
1010		if ctx.Failed() {
1011			return
1012		}
1013	}
1014}
1015
1016func (c *Module) toolchain(ctx android.BaseContext) config.Toolchain {
1017	if c.cachedToolchain == nil {
1018		c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
1019	}
1020	return c.cachedToolchain
1021}
1022
1023func (c *Module) begin(ctx BaseModuleContext) {
1024	if c.compiler != nil {
1025		c.compiler.compilerInit(ctx)
1026	}
1027	if c.linker != nil {
1028		c.linker.linkerInit(ctx)
1029	}
1030	if c.stl != nil {
1031		c.stl.begin(ctx)
1032	}
1033	if c.sanitize != nil {
1034		c.sanitize.begin(ctx)
1035	}
1036	if c.coverage != nil {
1037		c.coverage.begin(ctx)
1038	}
1039	if c.sabi != nil {
1040		c.sabi.begin(ctx)
1041	}
1042	if c.vndkdep != nil {
1043		c.vndkdep.begin(ctx)
1044	}
1045	if c.lto != nil {
1046		c.lto.begin(ctx)
1047	}
1048	if c.pgo != nil {
1049		c.pgo.begin(ctx)
1050	}
1051	for _, feature := range c.features {
1052		feature.begin(ctx)
1053	}
1054	if ctx.useSdk() {
1055		version, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch())
1056		if err != nil {
1057			ctx.PropertyErrorf("sdk_version", err.Error())
1058		}
1059		c.Properties.Sdk_version = StringPtr(version)
1060	}
1061}
1062
1063func (c *Module) deps(ctx DepsContext) Deps {
1064	deps := Deps{}
1065
1066	if c.compiler != nil {
1067		deps = c.compiler.compilerDeps(ctx, deps)
1068	}
1069	// Add the PGO dependency (the clang_rt.profile runtime library), which
1070	// sometimes depends on symbols from libgcc, before libgcc gets added
1071	// in linkerDeps().
1072	if c.pgo != nil {
1073		deps = c.pgo.deps(ctx, deps)
1074	}
1075	if c.linker != nil {
1076		deps = c.linker.linkerDeps(ctx, deps)
1077	}
1078	if c.stl != nil {
1079		deps = c.stl.deps(ctx, deps)
1080	}
1081	if c.sanitize != nil {
1082		deps = c.sanitize.deps(ctx, deps)
1083	}
1084	if c.coverage != nil {
1085		deps = c.coverage.deps(ctx, deps)
1086	}
1087	if c.sabi != nil {
1088		deps = c.sabi.deps(ctx, deps)
1089	}
1090	if c.vndkdep != nil {
1091		deps = c.vndkdep.deps(ctx, deps)
1092	}
1093	if c.lto != nil {
1094		deps = c.lto.deps(ctx, deps)
1095	}
1096	for _, feature := range c.features {
1097		deps = feature.deps(ctx, deps)
1098	}
1099
1100	deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
1101	deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
1102	deps.LateStaticLibs = android.LastUniqueStrings(deps.LateStaticLibs)
1103	deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
1104	deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
1105	deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs)
1106	deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs)
1107
1108	for _, lib := range deps.ReexportSharedLibHeaders {
1109		if !inList(lib, deps.SharedLibs) {
1110			ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib)
1111		}
1112	}
1113
1114	for _, lib := range deps.ReexportStaticLibHeaders {
1115		if !inList(lib, deps.StaticLibs) {
1116			ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs: '%s'", lib)
1117		}
1118	}
1119
1120	for _, lib := range deps.ReexportHeaderLibHeaders {
1121		if !inList(lib, deps.HeaderLibs) {
1122			ctx.PropertyErrorf("export_header_lib_headers", "Header library not in header_libs: '%s'", lib)
1123		}
1124	}
1125
1126	for _, gen := range deps.ReexportGeneratedHeaders {
1127		if !inList(gen, deps.GeneratedHeaders) {
1128			ctx.PropertyErrorf("export_generated_headers", "Generated header module not in generated_headers: '%s'", gen)
1129		}
1130	}
1131
1132	return deps
1133}
1134
1135func (c *Module) beginMutator(actx android.BottomUpMutatorContext) {
1136	ctx := &baseModuleContext{
1137		BaseContext: actx,
1138		moduleContextImpl: moduleContextImpl{
1139			mod: c,
1140		},
1141	}
1142	ctx.ctx = ctx
1143
1144	c.begin(ctx)
1145}
1146
1147// Split name#version into name and version
1148func stubsLibNameAndVersion(name string) (string, string) {
1149	if sharp := strings.LastIndex(name, "#"); sharp != -1 && sharp != len(name)-1 {
1150		version := name[sharp+1:]
1151		libname := name[:sharp]
1152		return libname, version
1153	}
1154	return name, ""
1155}
1156
1157func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
1158	ctx := &depsContext{
1159		BottomUpMutatorContext: actx,
1160		moduleContextImpl: moduleContextImpl{
1161			mod: c,
1162		},
1163	}
1164	ctx.ctx = ctx
1165
1166	deps := c.deps(ctx)
1167
1168	variantNdkLibs := []string{}
1169	variantLateNdkLibs := []string{}
1170	if ctx.Os() == android.Android {
1171		version := ctx.sdkVersion()
1172
1173		// rewriteNdkLibs takes a list of names of shared libraries and scans it for three types
1174		// of names:
1175		//
1176		// 1. Name of an NDK library that refers to a prebuilt module.
1177		//    For each of these, it adds the name of the prebuilt module (which will be in
1178		//    prebuilts/ndk) to the list of nonvariant libs.
1179		// 2. Name of an NDK library that refers to an ndk_library module.
1180		//    For each of these, it adds the name of the ndk_library module to the list of
1181		//    variant libs.
1182		// 3. Anything else (so anything that isn't an NDK library).
1183		//    It adds these to the nonvariantLibs list.
1184		//
1185		// The caller can then know to add the variantLibs dependencies differently from the
1186		// nonvariantLibs
1187		rewriteNdkLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) {
1188			variantLibs = []string{}
1189			nonvariantLibs = []string{}
1190			for _, entry := range list {
1191				// strip #version suffix out
1192				name, _ := stubsLibNameAndVersion(entry)
1193				if ctx.useSdk() && inList(name, ndkPrebuiltSharedLibraries) {
1194					if !inList(name, ndkMigratedLibs) {
1195						nonvariantLibs = append(nonvariantLibs, name+".ndk."+version)
1196					} else {
1197						variantLibs = append(variantLibs, name+ndkLibrarySuffix)
1198					}
1199				} else if ctx.useVndk() && inList(name, llndkLibraries) {
1200					nonvariantLibs = append(nonvariantLibs, name+llndkLibrarySuffix)
1201				} else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, vendorPublicLibraries) {
1202					vendorPublicLib := name + vendorPublicLibrarySuffix
1203					if actx.OtherModuleExists(vendorPublicLib) {
1204						nonvariantLibs = append(nonvariantLibs, vendorPublicLib)
1205					} else {
1206						// This can happen if vendor_public_library module is defined in a
1207						// namespace that isn't visible to the current module. In that case,
1208						// link to the original library.
1209						nonvariantLibs = append(nonvariantLibs, name)
1210					}
1211				} else {
1212					// put name#version back
1213					nonvariantLibs = append(nonvariantLibs, entry)
1214				}
1215			}
1216			return nonvariantLibs, variantLibs
1217		}
1218
1219		deps.SharedLibs, variantNdkLibs = rewriteNdkLibs(deps.SharedLibs)
1220		deps.LateSharedLibs, variantLateNdkLibs = rewriteNdkLibs(deps.LateSharedLibs)
1221		deps.ReexportSharedLibHeaders, _ = rewriteNdkLibs(deps.ReexportSharedLibHeaders)
1222	}
1223
1224	buildStubs := false
1225	if c.linker != nil {
1226		if library, ok := c.linker.(*libraryDecorator); ok {
1227			if library.buildStubs() {
1228				buildStubs = true
1229			}
1230		}
1231	}
1232
1233	for _, lib := range deps.HeaderLibs {
1234		depTag := headerDepTag
1235		if inList(lib, deps.ReexportHeaderLibHeaders) {
1236			depTag = headerExportDepTag
1237		}
1238		if buildStubs {
1239			actx.AddFarVariationDependencies([]blueprint.Variation{
1240				{Mutator: "arch", Variation: ctx.Target().String()},
1241				{Mutator: "image", Variation: c.imageVariation()},
1242			}, depTag, lib)
1243		} else {
1244			actx.AddVariationDependencies(nil, depTag, lib)
1245		}
1246	}
1247
1248	if buildStubs {
1249		// Stubs lib does not have dependency to other static/shared libraries.
1250		// Don't proceed.
1251		return
1252	}
1253
1254	syspropImplLibraries := syspropImplLibraries(actx.Config())
1255
1256	for _, lib := range deps.WholeStaticLibs {
1257		depTag := wholeStaticDepTag
1258		if impl, ok := syspropImplLibraries[lib]; ok {
1259			lib = impl
1260		}
1261		actx.AddVariationDependencies([]blueprint.Variation{
1262			{Mutator: "link", Variation: "static"},
1263		}, depTag, lib)
1264	}
1265
1266	for _, lib := range deps.StaticLibs {
1267		depTag := staticDepTag
1268		if inList(lib, deps.ReexportStaticLibHeaders) {
1269			depTag = staticExportDepTag
1270		}
1271
1272		if impl, ok := syspropImplLibraries[lib]; ok {
1273			lib = impl
1274		}
1275
1276		actx.AddVariationDependencies([]blueprint.Variation{
1277			{Mutator: "link", Variation: "static"},
1278		}, depTag, lib)
1279	}
1280
1281	actx.AddVariationDependencies([]blueprint.Variation{
1282		{Mutator: "link", Variation: "static"},
1283	}, lateStaticDepTag, deps.LateStaticLibs...)
1284
1285	addSharedLibDependencies := func(depTag dependencyTag, name string, version string) {
1286		var variations []blueprint.Variation
1287		variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
1288		versionVariantAvail := !ctx.useVndk() && !c.inRecovery()
1289		if version != "" && versionVariantAvail {
1290			// Version is explicitly specified. i.e. libFoo#30
1291			variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
1292			depTag.explicitlyVersioned = true
1293		}
1294		actx.AddVariationDependencies(variations, depTag, name)
1295
1296		// If the version is not specified, add dependency to the latest stubs library.
1297		// The stubs library will be used when the depending module is built for APEX and
1298		// the dependent module is not in the same APEX.
1299		latestVersion := latestStubsVersionFor(actx.Config(), name)
1300		if version == "" && latestVersion != "" && versionVariantAvail {
1301			actx.AddVariationDependencies([]blueprint.Variation{
1302				{Mutator: "link", Variation: "shared"},
1303				{Mutator: "version", Variation: latestVersion},
1304			}, depTag, name)
1305			// Note that depTag.explicitlyVersioned is false in this case.
1306		}
1307	}
1308
1309	// shared lib names without the #version suffix
1310	var sharedLibNames []string
1311
1312	for _, lib := range deps.SharedLibs {
1313		depTag := sharedDepTag
1314		if inList(lib, deps.ReexportSharedLibHeaders) {
1315			depTag = sharedExportDepTag
1316		}
1317
1318		if impl, ok := syspropImplLibraries[lib]; ok {
1319			lib = impl
1320		}
1321
1322		name, version := stubsLibNameAndVersion(lib)
1323		sharedLibNames = append(sharedLibNames, name)
1324
1325		addSharedLibDependencies(depTag, name, version)
1326	}
1327
1328	for _, lib := range deps.LateSharedLibs {
1329		if inList(lib, sharedLibNames) {
1330			// This is to handle the case that some of the late shared libs (libc, libdl, libm, ...)
1331			// are added also to SharedLibs with version (e.g., libc#10). If not skipped, we will be
1332			// linking against both the stubs lib and the non-stubs lib at the same time.
1333			continue
1334		}
1335		addSharedLibDependencies(lateSharedDepTag, lib, "")
1336	}
1337
1338	actx.AddVariationDependencies([]blueprint.Variation{
1339		{Mutator: "link", Variation: "shared"},
1340	}, runtimeDepTag, deps.RuntimeLibs...)
1341
1342	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
1343
1344	for _, gen := range deps.GeneratedHeaders {
1345		depTag := genHeaderDepTag
1346		if inList(gen, deps.ReexportGeneratedHeaders) {
1347			depTag = genHeaderExportDepTag
1348		}
1349		actx.AddDependency(c, depTag, gen)
1350	}
1351
1352	actx.AddVariationDependencies(nil, objDepTag, deps.ObjFiles...)
1353
1354	if deps.CrtBegin != "" {
1355		actx.AddVariationDependencies(nil, crtBeginDepTag, deps.CrtBegin)
1356	}
1357	if deps.CrtEnd != "" {
1358		actx.AddVariationDependencies(nil, crtEndDepTag, deps.CrtEnd)
1359	}
1360	if deps.LinkerFlagsFile != "" {
1361		actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
1362	}
1363	if deps.DynamicLinker != "" {
1364		actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
1365	}
1366
1367	version := ctx.sdkVersion()
1368	actx.AddVariationDependencies([]blueprint.Variation{
1369		{Mutator: "ndk_api", Variation: version},
1370		{Mutator: "link", Variation: "shared"},
1371	}, ndkStubDepTag, variantNdkLibs...)
1372	actx.AddVariationDependencies([]blueprint.Variation{
1373		{Mutator: "ndk_api", Variation: version},
1374		{Mutator: "link", Variation: "shared"},
1375	}, ndkLateStubDepTag, variantLateNdkLibs...)
1376
1377	if vndkdep := c.vndkdep; vndkdep != nil {
1378		if vndkdep.isVndkExt() {
1379			baseModuleMode := vendorMode
1380			if actx.DeviceConfig().VndkVersion() == "" {
1381				baseModuleMode = coreMode
1382			}
1383			actx.AddVariationDependencies([]blueprint.Variation{
1384				{Mutator: "image", Variation: baseModuleMode},
1385				{Mutator: "link", Variation: "shared"},
1386			}, vndkExtDepTag, vndkdep.getVndkExtendsModuleName())
1387		}
1388	}
1389}
1390
1391func BeginMutator(ctx android.BottomUpMutatorContext) {
1392	if c, ok := ctx.Module().(*Module); ok && c.Enabled() {
1393		c.beginMutator(ctx)
1394	}
1395}
1396
1397// Whether a module can link to another module, taking into
1398// account NDK linking.
1399func checkLinkType(ctx android.ModuleContext, from *Module, to *Module, tag dependencyTag) {
1400	if from.Target().Os != android.Android {
1401		// Host code is not restricted
1402		return
1403	}
1404	if from.Properties.UseVndk {
1405		// Though vendor code is limited by the vendor mutator,
1406		// each vendor-available module needs to check
1407		// link-type for VNDK.
1408		if from.vndkdep != nil {
1409			from.vndkdep.vndkCheckLinkType(ctx, to, tag)
1410		}
1411		return
1412	}
1413	if String(from.Properties.Sdk_version) == "" {
1414		// Platform code can link to anything
1415		return
1416	}
1417	if from.inRecovery() {
1418		// Recovery code is not NDK
1419		return
1420	}
1421	if _, ok := to.linker.(*toolchainLibraryDecorator); ok {
1422		// These are always allowed
1423		return
1424	}
1425	if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok {
1426		// These are allowed, but they don't set sdk_version
1427		return
1428	}
1429	if _, ok := to.linker.(*stubDecorator); ok {
1430		// These aren't real libraries, but are the stub shared libraries that are included in
1431		// the NDK.
1432		return
1433	}
1434
1435	if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Name() == "libc++" {
1436		// Bug: http://b/121358700 - Allow libclang_rt.* shared libraries (with sdk_version)
1437		// to link to libc++ (non-NDK and without sdk_version).
1438		return
1439	}
1440
1441	if String(to.Properties.Sdk_version) == "" {
1442		// NDK code linking to platform code is never okay.
1443		ctx.ModuleErrorf("depends on non-NDK-built library %q",
1444			ctx.OtherModuleName(to))
1445		return
1446	}
1447
1448	// At this point we know we have two NDK libraries, but we need to
1449	// check that we're not linking against anything built against a higher
1450	// API level, as it is only valid to link against older or equivalent
1451	// APIs.
1452
1453	// Current can link against anything.
1454	if String(from.Properties.Sdk_version) != "current" {
1455		// Otherwise we need to check.
1456		if String(to.Properties.Sdk_version) == "current" {
1457			// Current can't be linked against by anything else.
1458			ctx.ModuleErrorf("links %q built against newer API version %q",
1459				ctx.OtherModuleName(to), "current")
1460		} else {
1461			fromApi, err := strconv.Atoi(String(from.Properties.Sdk_version))
1462			if err != nil {
1463				ctx.PropertyErrorf("sdk_version",
1464					"Invalid sdk_version value (must be int or current): %q",
1465					String(from.Properties.Sdk_version))
1466			}
1467			toApi, err := strconv.Atoi(String(to.Properties.Sdk_version))
1468			if err != nil {
1469				ctx.PropertyErrorf("sdk_version",
1470					"Invalid sdk_version value (must be int or current): %q",
1471					String(to.Properties.Sdk_version))
1472			}
1473
1474			if toApi > fromApi {
1475				ctx.ModuleErrorf("links %q built against newer API version %q",
1476					ctx.OtherModuleName(to), String(to.Properties.Sdk_version))
1477			}
1478		}
1479	}
1480
1481	// Also check that the two STL choices are compatible.
1482	fromStl := from.stl.Properties.SelectedStl
1483	toStl := to.stl.Properties.SelectedStl
1484	if fromStl == "" || toStl == "" {
1485		// Libraries that don't use the STL are unrestricted.
1486	} else if fromStl == "ndk_system" || toStl == "ndk_system" {
1487		// We can be permissive with the system "STL" since it is only the C++
1488		// ABI layer, but in the future we should make sure that everyone is
1489		// using either libc++ or nothing.
1490	} else if getNdkStlFamily(from) != getNdkStlFamily(to) {
1491		ctx.ModuleErrorf("uses %q and depends on %q which uses incompatible %q",
1492			from.stl.Properties.SelectedStl, ctx.OtherModuleName(to),
1493			to.stl.Properties.SelectedStl)
1494	}
1495}
1496
1497// Tests whether the dependent library is okay to be double loaded inside a single process.
1498// If a library has a vendor variant and is a (transitive) dependency of an LLNDK library,
1499// it is subject to be double loaded. Such lib should be explicitly marked as double_loadable: true
1500// or as vndk-sp (vndk: { enabled: true, support_system_process: true}).
1501func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
1502	check := func(child, parent android.Module) bool {
1503		to, ok := child.(*Module)
1504		if !ok {
1505			// follow thru cc.Defaults, etc.
1506			return true
1507		}
1508
1509		if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
1510			return false
1511		}
1512
1513		// if target lib has no vendor variant, keep checking dependency graph
1514		if !to.hasVendorVariant() {
1515			return true
1516		}
1517
1518		if to.isVndkSp() || inList(child.Name(), llndkLibraries) || Bool(to.VendorProperties.Double_loadable) {
1519			return false
1520		}
1521
1522		var stringPath []string
1523		for _, m := range ctx.GetWalkPath() {
1524			stringPath = append(stringPath, m.Name())
1525		}
1526		ctx.ModuleErrorf("links a library %q which is not LL-NDK, "+
1527			"VNDK-SP, or explicitly marked as 'double_loadable:true'. "+
1528			"(dependency: %s)", ctx.OtherModuleName(to), strings.Join(stringPath, " -> "))
1529		return false
1530	}
1531	if module, ok := ctx.Module().(*Module); ok {
1532		if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() {
1533			if inList(ctx.ModuleName(), llndkLibraries) || Bool(module.VendorProperties.Double_loadable) {
1534				ctx.WalkDeps(check)
1535			}
1536		}
1537	}
1538}
1539
1540// Convert dependencies to paths.  Returns a PathDeps containing paths
1541func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
1542	var depPaths PathDeps
1543
1544	directStaticDeps := []*Module{}
1545	directSharedDeps := []*Module{}
1546
1547	ctx.VisitDirectDeps(func(dep android.Module) {
1548		depName := ctx.OtherModuleName(dep)
1549		depTag := ctx.OtherModuleDependencyTag(dep)
1550
1551		ccDep, _ := dep.(*Module)
1552		if ccDep == nil {
1553			// handling for a few module types that aren't cc Module but that are also supported
1554			switch depTag {
1555			case genSourceDepTag:
1556				if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
1557					depPaths.GeneratedSources = append(depPaths.GeneratedSources,
1558						genRule.GeneratedSourceFiles()...)
1559				} else {
1560					ctx.ModuleErrorf("module %q is not a gensrcs or genrule", depName)
1561				}
1562				// Support exported headers from a generated_sources dependency
1563				fallthrough
1564			case genHeaderDepTag, genHeaderExportDepTag:
1565				if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
1566					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
1567						genRule.GeneratedDeps()...)
1568					flags := includeDirsToFlags(genRule.GeneratedHeaderDirs())
1569					depPaths.Flags = append(depPaths.Flags, flags)
1570					if depTag == genHeaderExportDepTag {
1571						depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags)
1572						depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps,
1573							genRule.GeneratedDeps()...)
1574						// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
1575						c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags)
1576
1577					}
1578				} else {
1579					ctx.ModuleErrorf("module %q is not a genrule", depName)
1580				}
1581			case linkerFlagsDepTag:
1582				if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
1583					files := genRule.GeneratedSourceFiles()
1584					if len(files) == 1 {
1585						depPaths.LinkerFlagsFile = android.OptionalPathForPath(files[0])
1586					} else if len(files) > 1 {
1587						ctx.ModuleErrorf("module %q can only generate a single file if used for a linker flag file", depName)
1588					}
1589				} else {
1590					ctx.ModuleErrorf("module %q is not a genrule", depName)
1591				}
1592			}
1593			return
1594		}
1595
1596		if depTag == android.ProtoPluginDepTag {
1597			return
1598		}
1599
1600		if dep.Target().Os != ctx.Os() {
1601			ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
1602			return
1603		}
1604		if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
1605			ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
1606			return
1607		}
1608
1609		// re-exporting flags
1610		if depTag == reuseObjTag {
1611			if l, ok := ccDep.compiler.(libraryInterface); ok {
1612				c.staticVariant = ccDep
1613				objs, flags, deps := l.reuseObjs()
1614				depPaths.Objs = depPaths.Objs.Append(objs)
1615				depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
1616				depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...)
1617				return
1618			}
1619		}
1620
1621		if depTag == staticVariantTag {
1622			if _, ok := ccDep.compiler.(libraryInterface); ok {
1623				c.staticVariant = ccDep
1624				return
1625			}
1626		}
1627
1628		// Extract explicitlyVersioned field from the depTag and reset it inside the struct.
1629		// Otherwise, sharedDepTag and lateSharedDepTag with explicitlyVersioned set to true
1630		// won't be matched to sharedDepTag and lateSharedDepTag.
1631		explicitlyVersioned := false
1632		if t, ok := depTag.(dependencyTag); ok {
1633			explicitlyVersioned = t.explicitlyVersioned
1634			t.explicitlyVersioned = false
1635			depTag = t
1636		}
1637
1638		if t, ok := depTag.(dependencyTag); ok && t.library {
1639			depIsStatic := false
1640			switch depTag {
1641			case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
1642				depIsStatic = true
1643			}
1644			if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok && !depIsStatic {
1645				depIsStubs := dependentLibrary.buildStubs()
1646				depHasStubs := ccDep.HasStubsVariants()
1647				depInSameApex := android.DirectlyInApex(c.ApexName(), depName)
1648				depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
1649
1650				var useThisDep bool
1651				if depIsStubs && explicitlyVersioned {
1652					// Always respect dependency to the versioned stubs (i.e. libX#10)
1653					useThisDep = true
1654				} else if !depHasStubs {
1655					// Use non-stub variant if that is the only choice
1656					// (i.e. depending on a lib without stubs.version property)
1657					useThisDep = true
1658				} else if c.IsForPlatform() {
1659					// If not building for APEX, use stubs only when it is from
1660					// an APEX (and not from platform)
1661					useThisDep = (depInPlatform != depIsStubs)
1662					if c.inRecovery() || c.bootstrap() {
1663						// However, for recovery or bootstrap modules,
1664						// always link to non-stub variant
1665						useThisDep = !depIsStubs
1666					}
1667				} else {
1668					// If building for APEX, use stubs only when it is not from
1669					// the same APEX
1670					useThisDep = (depInSameApex != depIsStubs)
1671				}
1672
1673				if !useThisDep {
1674					return // stop processing this dep
1675				}
1676			}
1677
1678			if i, ok := ccDep.linker.(exportedFlagsProducer); ok {
1679				flags := i.exportedFlags()
1680				deps := i.exportedFlagsDeps()
1681				depPaths.Flags = append(depPaths.Flags, flags...)
1682				depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, deps...)
1683
1684				if t.reexportFlags {
1685					depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
1686					depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...)
1687					// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
1688					// Re-exported shared library headers must be included as well since they can help us with type information
1689					// about template instantiations (instantiated from their headers).
1690					c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags...)
1691				}
1692			}
1693
1694			checkLinkType(ctx, c, ccDep, t)
1695		}
1696
1697		var ptr *android.Paths
1698		var depPtr *android.Paths
1699
1700		linkFile := ccDep.outputFile
1701		depFile := android.OptionalPath{}
1702
1703		switch depTag {
1704		case ndkStubDepTag, sharedDepTag, sharedExportDepTag:
1705			ptr = &depPaths.SharedLibs
1706			depPtr = &depPaths.SharedLibsDeps
1707			depFile = ccDep.linker.(libraryInterface).toc()
1708			directSharedDeps = append(directSharedDeps, ccDep)
1709		case earlySharedDepTag:
1710			ptr = &depPaths.EarlySharedLibs
1711			depPtr = &depPaths.EarlySharedLibsDeps
1712			depFile = ccDep.linker.(libraryInterface).toc()
1713			directSharedDeps = append(directSharedDeps, ccDep)
1714		case lateSharedDepTag, ndkLateStubDepTag:
1715			ptr = &depPaths.LateSharedLibs
1716			depPtr = &depPaths.LateSharedLibsDeps
1717			depFile = ccDep.linker.(libraryInterface).toc()
1718		case staticDepTag, staticExportDepTag:
1719			ptr = nil
1720			directStaticDeps = append(directStaticDeps, ccDep)
1721		case lateStaticDepTag:
1722			ptr = &depPaths.LateStaticLibs
1723		case wholeStaticDepTag:
1724			ptr = &depPaths.WholeStaticLibs
1725			staticLib, ok := ccDep.linker.(libraryInterface)
1726			if !ok || !staticLib.static() {
1727				ctx.ModuleErrorf("module %q not a static library", depName)
1728				return
1729			}
1730
1731			if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
1732				postfix := " (required by " + ctx.OtherModuleName(dep) + ")"
1733				for i := range missingDeps {
1734					missingDeps[i] += postfix
1735				}
1736				ctx.AddMissingDependencies(missingDeps)
1737			}
1738			depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs())
1739		case headerDepTag:
1740			// Nothing
1741		case objDepTag:
1742			depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
1743		case crtBeginDepTag:
1744			depPaths.CrtBegin = linkFile
1745		case crtEndDepTag:
1746			depPaths.CrtEnd = linkFile
1747		case dynamicLinkerDepTag:
1748			depPaths.DynamicLinker = linkFile
1749		}
1750
1751		switch depTag {
1752		case staticDepTag, staticExportDepTag, lateStaticDepTag:
1753			staticLib, ok := ccDep.linker.(libraryInterface)
1754			if !ok || !staticLib.static() {
1755				ctx.ModuleErrorf("module %q not a static library", depName)
1756				return
1757			}
1758
1759			// When combining coverage files for shared libraries and executables, coverage files
1760			// in static libraries act as if they were whole static libraries. The same goes for
1761			// source based Abi dump files.
1762			depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
1763				staticLib.objs().coverageFiles...)
1764			depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
1765				staticLib.objs().sAbiDumpFiles...)
1766
1767		}
1768
1769		if ptr != nil {
1770			if !linkFile.Valid() {
1771				ctx.ModuleErrorf("module %q missing output file", depName)
1772				return
1773			}
1774			*ptr = append(*ptr, linkFile.Path())
1775		}
1776
1777		if depPtr != nil {
1778			dep := depFile
1779			if !dep.Valid() {
1780				dep = linkFile
1781			}
1782			*depPtr = append(*depPtr, dep.Path())
1783		}
1784
1785		makeLibName := func(depName string) string {
1786			libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
1787			libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
1788			libName = strings.TrimPrefix(libName, "prebuilt_")
1789			isLLndk := inList(libName, llndkLibraries)
1790			isVendorPublicLib := inList(libName, vendorPublicLibraries)
1791			bothVendorAndCoreVariantsExist := ccDep.hasVendorVariant() || isLLndk
1792
1793			if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.isVndk() && !ccDep.mustUseVendorVariant() {
1794				// The vendor module is a no-vendor-variant VNDK library.  Depend on the
1795				// core module instead.
1796				return libName
1797			} else if c.useVndk() && bothVendorAndCoreVariantsExist {
1798				// The vendor module in Make will have been renamed to not conflict with the core
1799				// module, so update the dependency name here accordingly.
1800				return libName + vendorSuffix
1801			} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
1802				return libName + vendorPublicLibrarySuffix
1803			} else if ccDep.inRecovery() && !ccDep.onlyInRecovery() {
1804				return libName + recoverySuffix
1805			} else {
1806				return libName
1807			}
1808		}
1809
1810		// Export the shared libs to Make.
1811		switch depTag {
1812		case sharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
1813			if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok {
1814				if dependentLibrary.buildStubs() && android.InAnyApex(depName) {
1815					// Add the dependency to the APEX(es) providing the library so that
1816					// m <module> can trigger building the APEXes as well.
1817					for _, an := range android.GetApexesForModule(depName) {
1818						c.Properties.ApexesProvidingSharedLibs = append(
1819							c.Properties.ApexesProvidingSharedLibs, an)
1820					}
1821				}
1822			}
1823
1824			// Note: the order of libs in this list is not important because
1825			// they merely serve as Make dependencies and do not affect this lib itself.
1826			c.Properties.AndroidMkSharedLibs = append(
1827				c.Properties.AndroidMkSharedLibs, makeLibName(depName))
1828		case ndkStubDepTag, ndkLateStubDepTag:
1829			ndkStub := ccDep.linker.(*stubDecorator)
1830			c.Properties.AndroidMkSharedLibs = append(
1831				c.Properties.AndroidMkSharedLibs,
1832				depName+"."+ndkStub.properties.ApiLevel)
1833		case staticDepTag, staticExportDepTag, lateStaticDepTag:
1834			c.Properties.AndroidMkStaticLibs = append(
1835				c.Properties.AndroidMkStaticLibs, makeLibName(depName))
1836		case runtimeDepTag:
1837			c.Properties.AndroidMkRuntimeLibs = append(
1838				c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
1839		case wholeStaticDepTag:
1840			c.Properties.AndroidMkWholeStaticLibs = append(
1841				c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName))
1842		}
1843	})
1844
1845	// use the ordered dependencies as this module's dependencies
1846	depPaths.StaticLibs = append(depPaths.StaticLibs, orderStaticModuleDeps(c, directStaticDeps, directSharedDeps)...)
1847
1848	// Dedup exported flags from dependencies
1849	depPaths.Flags = android.FirstUniqueStrings(depPaths.Flags)
1850	depPaths.GeneratedHeaders = android.FirstUniquePaths(depPaths.GeneratedHeaders)
1851	depPaths.ReexportedFlags = android.FirstUniqueStrings(depPaths.ReexportedFlags)
1852	depPaths.ReexportedFlagsDeps = android.FirstUniquePaths(depPaths.ReexportedFlagsDeps)
1853
1854	if c.sabi != nil {
1855		c.sabi.Properties.ReexportedIncludeFlags = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludeFlags)
1856	}
1857
1858	return depPaths
1859}
1860
1861func (c *Module) InstallInData() bool {
1862	if c.installer == nil {
1863		return false
1864	}
1865	return c.installer.inData()
1866}
1867
1868func (c *Module) InstallInSanitizerDir() bool {
1869	if c.installer == nil {
1870		return false
1871	}
1872	if c.sanitize != nil && c.sanitize.inSanitizerDir() {
1873		return true
1874	}
1875	return c.installer.inSanitizerDir()
1876}
1877
1878func (c *Module) InstallInRecovery() bool {
1879	return c.inRecovery()
1880}
1881
1882func (c *Module) HostToolPath() android.OptionalPath {
1883	if c.installer == nil {
1884		return android.OptionalPath{}
1885	}
1886	return c.installer.hostToolPath()
1887}
1888
1889func (c *Module) IntermPathForModuleOut() android.OptionalPath {
1890	return c.outputFile
1891}
1892
1893func (c *Module) Srcs() android.Paths {
1894	if c.outputFile.Valid() {
1895		return android.Paths{c.outputFile.Path()}
1896	}
1897	return android.Paths{}
1898}
1899
1900func (c *Module) static() bool {
1901	if static, ok := c.linker.(interface {
1902		static() bool
1903	}); ok {
1904		return static.static()
1905	}
1906	return false
1907}
1908
1909func (c *Module) staticBinary() bool {
1910	if static, ok := c.linker.(interface {
1911		staticBinary() bool
1912	}); ok {
1913		return static.staticBinary()
1914	}
1915	return false
1916}
1917
1918func (c *Module) getMakeLinkType() string {
1919	if c.useVndk() {
1920		if inList(c.Name(), vndkCoreLibraries) || inList(c.Name(), vndkSpLibraries) || inList(c.Name(), llndkLibraries) {
1921			if inList(c.Name(), vndkPrivateLibraries) {
1922				return "native:vndk_private"
1923			} else {
1924				return "native:vndk"
1925			}
1926		} else {
1927			return "native:vendor"
1928		}
1929	} else if c.inRecovery() {
1930		return "native:recovery"
1931	} else if c.Target().Os == android.Android && String(c.Properties.Sdk_version) != "" {
1932		return "native:ndk:none:none"
1933		// TODO(b/114741097): use the correct ndk stl once build errors have been fixed
1934		//family, link := getNdkStlFamilyAndLinkType(c)
1935		//return fmt.Sprintf("native:ndk:%s:%s", family, link)
1936	} else if inList(c.Name(), vndkUsingCoreVariantLibraries) {
1937		return "native:platform_vndk"
1938	} else {
1939		return "native:platform"
1940	}
1941}
1942
1943// Overrides ApexModule.IsInstallabeToApex()
1944// Only shared libraries are installable to APEX.
1945func (c *Module) IsInstallableToApex() bool {
1946	if shared, ok := c.linker.(interface {
1947		shared() bool
1948	}); ok {
1949		return shared.shared()
1950	}
1951	return false
1952}
1953
1954func (c *Module) imageVariation() string {
1955	variation := "core"
1956	if c.useVndk() {
1957		variation = "vendor"
1958	} else if c.inRecovery() {
1959		variation = "recovery"
1960	}
1961	return variation
1962}
1963
1964func (c *Module) IDEInfo(dpInfo *android.IdeInfo) {
1965	dpInfo.Srcs = append(dpInfo.Srcs, c.Srcs().Strings()...)
1966}
1967
1968//
1969// Defaults
1970//
1971type Defaults struct {
1972	android.ModuleBase
1973	android.DefaultsModuleBase
1974	android.ApexModuleBase
1975}
1976
1977func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1978}
1979
1980// cc_defaults provides a set of properties that can be inherited by other cc
1981// modules. A module can use the properties from a cc_defaults using
1982// `defaults: ["<:default_module_name>"]`. Properties of both modules are
1983// merged (when possible) by prepending the default module's values to the
1984// depending module's values.
1985func defaultsFactory() android.Module {
1986	return DefaultsFactory()
1987}
1988
1989func DefaultsFactory(props ...interface{}) android.Module {
1990	module := &Defaults{}
1991
1992	module.AddProperties(props...)
1993	module.AddProperties(
1994		&BaseProperties{},
1995		&VendorProperties{},
1996		&BaseCompilerProperties{},
1997		&BaseLinkerProperties{},
1998		&LibraryProperties{},
1999		&FlagExporterProperties{},
2000		&BinaryLinkerProperties{},
2001		&TestProperties{},
2002		&TestBinaryProperties{},
2003		&StlProperties{},
2004		&SanitizeProperties{},
2005		&StripProperties{},
2006		&InstallerProperties{},
2007		&TidyProperties{},
2008		&CoverageProperties{},
2009		&SAbiProperties{},
2010		&VndkProperties{},
2011		&LTOProperties{},
2012		&PgoProperties{},
2013		&XomProperties{},
2014		&android.ProtoProperties{},
2015	)
2016
2017	android.InitDefaultsModule(module)
2018	android.InitApexModule(module)
2019
2020	return module
2021}
2022
2023const (
2024	// coreMode is the variant used for framework-private libraries, or
2025	// SDK libraries. (which framework-private libraries can use)
2026	coreMode = "core"
2027
2028	// vendorMode is the variant used for /vendor code that compiles
2029	// against the VNDK.
2030	vendorMode = "vendor"
2031
2032	recoveryMode = "recovery"
2033)
2034
2035func squashVendorSrcs(m *Module) {
2036	if lib, ok := m.compiler.(*libraryDecorator); ok {
2037		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
2038			lib.baseCompiler.Properties.Target.Vendor.Srcs...)
2039
2040		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
2041			lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
2042	}
2043}
2044
2045func squashRecoverySrcs(m *Module) {
2046	if lib, ok := m.compiler.(*libraryDecorator); ok {
2047		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
2048			lib.baseCompiler.Properties.Target.Recovery.Srcs...)
2049
2050		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
2051			lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
2052	}
2053}
2054
2055func ImageMutator(mctx android.BottomUpMutatorContext) {
2056	if mctx.Os() != android.Android {
2057		return
2058	}
2059
2060	if g, ok := mctx.Module().(*genrule.Module); ok {
2061		if props, ok := g.Extra.(*GenruleExtraProperties); ok {
2062			var coreVariantNeeded bool = false
2063			var vendorVariantNeeded bool = false
2064			var recoveryVariantNeeded bool = false
2065			if mctx.DeviceConfig().VndkVersion() == "" {
2066				coreVariantNeeded = true
2067			} else if Bool(props.Vendor_available) {
2068				coreVariantNeeded = true
2069				vendorVariantNeeded = true
2070			} else if mctx.SocSpecific() || mctx.DeviceSpecific() {
2071				vendorVariantNeeded = true
2072			} else {
2073				coreVariantNeeded = true
2074			}
2075			if Bool(props.Recovery_available) {
2076				recoveryVariantNeeded = true
2077			}
2078
2079			if recoveryVariantNeeded {
2080				primaryArch := mctx.Config().DevicePrimaryArchType()
2081				moduleArch := g.Target().Arch.ArchType
2082				if moduleArch != primaryArch {
2083					recoveryVariantNeeded = false
2084				}
2085			}
2086
2087			var variants []string
2088			if coreVariantNeeded {
2089				variants = append(variants, coreMode)
2090			}
2091			if vendorVariantNeeded {
2092				variants = append(variants, vendorMode)
2093			}
2094			if recoveryVariantNeeded {
2095				variants = append(variants, recoveryMode)
2096			}
2097			mod := mctx.CreateVariations(variants...)
2098			for i, v := range variants {
2099				if v == recoveryMode {
2100					m := mod[i].(*genrule.Module)
2101					m.Extra.(*GenruleExtraProperties).InRecovery = true
2102				}
2103			}
2104		}
2105	}
2106
2107	m, ok := mctx.Module().(*Module)
2108	if !ok {
2109		return
2110	}
2111
2112	// Sanity check
2113	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
2114	productSpecific := mctx.ProductSpecific()
2115
2116	if m.VendorProperties.Vendor_available != nil && vendorSpecific {
2117		mctx.PropertyErrorf("vendor_available",
2118			"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
2119		return
2120	}
2121
2122	if vndkdep := m.vndkdep; vndkdep != nil {
2123		if vndkdep.isVndk() {
2124			if productSpecific {
2125				mctx.PropertyErrorf("product_specific",
2126					"product_specific must not be true when `vndk: {enabled: true}`")
2127				return
2128			}
2129			if vendorSpecific {
2130				if !vndkdep.isVndkExt() {
2131					mctx.PropertyErrorf("vndk",
2132						"must set `extends: \"...\"` to vndk extension")
2133					return
2134				}
2135			} else {
2136				if vndkdep.isVndkExt() {
2137					mctx.PropertyErrorf("vndk",
2138						"must set `vendor: true` to set `extends: %q`",
2139						m.getVndkExtendsModuleName())
2140					return
2141				}
2142				if m.VendorProperties.Vendor_available == nil {
2143					mctx.PropertyErrorf("vndk",
2144						"vendor_available must be set to either true or false when `vndk: {enabled: true}`")
2145					return
2146				}
2147			}
2148		} else {
2149			if vndkdep.isVndkSp() {
2150				mctx.PropertyErrorf("vndk",
2151					"must set `enabled: true` to set `support_system_process: true`")
2152				return
2153			}
2154			if vndkdep.isVndkExt() {
2155				mctx.PropertyErrorf("vndk",
2156					"must set `enabled: true` to set `extends: %q`",
2157					m.getVndkExtendsModuleName())
2158				return
2159			}
2160		}
2161	}
2162
2163	var coreVariantNeeded bool = false
2164	var vendorVariantNeeded bool = false
2165	var recoveryVariantNeeded bool = false
2166
2167	if mctx.DeviceConfig().VndkVersion() == "" {
2168		// If the device isn't compiling against the VNDK, we always
2169		// use the core mode.
2170		coreVariantNeeded = true
2171	} else if _, ok := m.linker.(*llndkStubDecorator); ok {
2172		// LL-NDK stubs only exist in the vendor variant, since the
2173		// real libraries will be used in the core variant.
2174		vendorVariantNeeded = true
2175	} else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
2176		// ... and LL-NDK headers as well
2177		vendorVariantNeeded = true
2178	} else if _, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
2179		// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
2180		// PRODUCT_EXTRA_VNDK_VERSIONS.
2181		vendorVariantNeeded = true
2182	} else if m.hasVendorVariant() && !vendorSpecific {
2183		// This will be available in both /system and /vendor
2184		// or a /system directory that is available to vendor.
2185		coreVariantNeeded = true
2186		vendorVariantNeeded = true
2187	} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
2188		// This will be available in /vendor (or /odm) only
2189		vendorVariantNeeded = true
2190	} else {
2191		// This is either in /system (or similar: /data), or is a
2192		// modules built with the NDK. Modules built with the NDK
2193		// will be restricted using the existing link type checks.
2194		coreVariantNeeded = true
2195	}
2196
2197	if Bool(m.Properties.Recovery_available) {
2198		recoveryVariantNeeded = true
2199	}
2200
2201	if m.ModuleBase.InstallInRecovery() {
2202		recoveryVariantNeeded = true
2203		coreVariantNeeded = false
2204	}
2205
2206	if recoveryVariantNeeded {
2207		primaryArch := mctx.Config().DevicePrimaryArchType()
2208		moduleArch := m.Target().Arch.ArchType
2209		if moduleArch != primaryArch {
2210			recoveryVariantNeeded = false
2211		}
2212	}
2213
2214	var variants []string
2215	if coreVariantNeeded {
2216		variants = append(variants, coreMode)
2217	}
2218	if vendorVariantNeeded {
2219		variants = append(variants, vendorMode)
2220	}
2221	if recoveryVariantNeeded {
2222		variants = append(variants, recoveryMode)
2223	}
2224	mod := mctx.CreateVariations(variants...)
2225	for i, v := range variants {
2226		if v == vendorMode {
2227			m := mod[i].(*Module)
2228			m.Properties.UseVndk = true
2229			squashVendorSrcs(m)
2230		} else if v == recoveryMode {
2231			m := mod[i].(*Module)
2232			m.Properties.InRecovery = true
2233			m.MakeAsPlatform()
2234			squashRecoverySrcs(m)
2235		}
2236	}
2237}
2238
2239func getCurrentNdkPrebuiltVersion(ctx DepsContext) string {
2240	if ctx.Config().PlatformSdkVersionInt() > config.NdkMaxPrebuiltVersionInt {
2241		return strconv.Itoa(config.NdkMaxPrebuiltVersionInt)
2242	}
2243	return ctx.Config().PlatformSdkVersion()
2244}
2245
2246var Bool = proptools.Bool
2247var BoolDefault = proptools.BoolDefault
2248var BoolPtr = proptools.BoolPtr
2249var String = proptools.String
2250var StringPtr = proptools.StringPtr
2251