• 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("link", linkageMutator).Parallel()
38		ctx.BottomUp("vndk", vndkMutator).Parallel()
39		ctx.BottomUp("image", vendorMutator).Parallel()
40		ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
41		ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
42		ctx.BottomUp("begin", beginMutator).Parallel()
43	})
44
45	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
46		ctx.TopDown("asan_deps", sanitizerDepsMutator(asan))
47		ctx.BottomUp("asan", sanitizerMutator(asan)).Parallel()
48
49		ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
50		ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
51
52		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
53		ctx.TopDown("vndk_deps", sabiDepsMutator)
54	})
55
56	pctx.Import("android/soong/cc/config")
57}
58
59type Deps struct {
60	SharedLibs, LateSharedLibs                  []string
61	StaticLibs, LateStaticLibs, WholeStaticLibs []string
62	HeaderLibs                                  []string
63
64	ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
65
66	ObjFiles []string
67
68	GeneratedSources []string
69	GeneratedHeaders []string
70
71	ReexportGeneratedHeaders []string
72
73	CrtBegin, CrtEnd string
74}
75
76type PathDeps struct {
77	// Paths to .so files
78	SharedLibs, LateSharedLibs android.Paths
79	// Paths to the dependencies to use for .so files (.so.toc files)
80	SharedLibsDeps, LateSharedLibsDeps android.Paths
81	// Paths to .a files
82	StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
83
84	// Paths to .o files
85	Objs               Objects
86	StaticLibObjs      Objects
87	WholeStaticLibObjs Objects
88
89	// Paths to generated source files
90	GeneratedSources android.Paths
91	GeneratedHeaders android.Paths
92
93	Flags, ReexportedFlags []string
94	ReexportedFlagsDeps    android.Paths
95
96	// Paths to crt*.o files
97	CrtBegin, CrtEnd android.OptionalPath
98}
99
100type Flags struct {
101	GlobalFlags     []string // Flags that apply to C, C++, and assembly source files
102	ArFlags         []string // Flags that apply to ar
103	AsFlags         []string // Flags that apply to assembly source files
104	CFlags          []string // Flags that apply to C and C++ source files
105	ToolingCFlags   []string // Flags that apply to C and C++ source files parsed by clang LibTooling tools
106	ConlyFlags      []string // Flags that apply to C source files
107	CppFlags        []string // Flags that apply to C++ source files
108	ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools
109	YaccFlags       []string // Flags that apply to Yacc source files
110	protoFlags      []string // Flags that apply to proto source files
111	aidlFlags       []string // Flags that apply to aidl source files
112	rsFlags         []string // Flags that apply to renderscript source files
113	LdFlags         []string // Flags that apply to linker command lines
114	libFlags        []string // Flags to add libraries early to the link order
115	TidyFlags       []string // Flags that apply to clang-tidy
116	SAbiFlags       []string // Flags that apply to header-abi-dumper
117	YasmFlags       []string // Flags that apply to yasm assembly source files
118
119	// Global include flags that apply to C, C++, and assembly source files
120	// These must be after any module include flags, which will be in GlobalFlags.
121	SystemIncludeFlags []string
122
123	Toolchain config.Toolchain
124	Clang     bool
125	Tidy      bool
126	Coverage  bool
127	SAbiDump  bool
128
129	RequiredInstructionSet string
130	DynamicLinker          string
131
132	CFlagsDeps android.Paths // Files depended on by compiler flags
133
134	GroupStaticLibs bool
135}
136
137type ObjectLinkerProperties struct {
138	// names of other cc_object modules to link into this module using partial linking
139	Objs []string `android:"arch_variant"`
140}
141
142// Properties used to compile all C or C++ modules
143type BaseProperties struct {
144	// compile module with clang instead of gcc
145	Clang *bool `android:"arch_variant"`
146
147	// Minimum sdk version supported when compiling against the ndk
148	Sdk_version string
149
150	// don't insert default compiler flags into asflags, cflags,
151	// cppflags, conlyflags, ldflags, or include_dirs
152	No_default_compiler_flags *bool
153
154	// whether this module should be allowed to install onto /vendor as
155	// well as /system. The two variants will be built separately, one
156	// like normal, and the other limited to the set of libraries and
157	// headers that are exposed to /vendor modules.
158	//
159	// The vendor variant may be used with a different (newer) /system,
160	// so it shouldn't have any unversioned runtime dependencies, or
161	// make assumptions about the system that may not be true in the
162	// future.
163	//
164	// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
165	Vendor_available *bool
166
167	AndroidMkSharedLibs []string `blueprint:"mutated"`
168	HideFromMake        bool     `blueprint:"mutated"`
169	PreventInstall      bool     `blueprint:"mutated"`
170
171	UseVndk bool `blueprint:"mutated"`
172}
173
174type UnusedProperties struct {
175	Tags []string
176}
177
178type ModuleContextIntf interface {
179	static() bool
180	staticBinary() bool
181	clang() bool
182	toolchain() config.Toolchain
183	noDefaultCompilerFlags() bool
184	sdk() bool
185	sdkVersion() string
186	vndk() bool
187	isVndk() bool
188	isVndkSp() bool
189	createVndkSourceAbiDump() bool
190	selectedStl() string
191	baseModuleName() string
192}
193
194type ModuleContext interface {
195	android.ModuleContext
196	ModuleContextIntf
197}
198
199type BaseModuleContext interface {
200	android.BaseContext
201	ModuleContextIntf
202}
203
204type DepsContext interface {
205	android.BottomUpMutatorContext
206	ModuleContextIntf
207}
208
209type feature interface {
210	begin(ctx BaseModuleContext)
211	deps(ctx DepsContext, deps Deps) Deps
212	flags(ctx ModuleContext, flags Flags) Flags
213	props() []interface{}
214}
215
216type compiler interface {
217	compilerInit(ctx BaseModuleContext)
218	compilerDeps(ctx DepsContext, deps Deps) Deps
219	compilerFlags(ctx ModuleContext, flags Flags) Flags
220	compilerProps() []interface{}
221
222	appendCflags([]string)
223	appendAsflags([]string)
224	compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects
225}
226
227type linker interface {
228	linkerInit(ctx BaseModuleContext)
229	linkerDeps(ctx DepsContext, deps Deps) Deps
230	linkerFlags(ctx ModuleContext, flags Flags) Flags
231	linkerProps() []interface{}
232
233	link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path
234	appendLdflags([]string)
235}
236
237type installer interface {
238	installerProps() []interface{}
239	install(ctx ModuleContext, path android.Path)
240	inData() bool
241	inSanitizerDir() bool
242	hostToolPath() android.OptionalPath
243}
244
245type dependencyTag struct {
246	blueprint.BaseDependencyTag
247	name    string
248	library bool
249
250	reexportFlags bool
251}
252
253var (
254	sharedDepTag          = dependencyTag{name: "shared", library: true}
255	sharedExportDepTag    = dependencyTag{name: "shared", library: true, reexportFlags: true}
256	lateSharedDepTag      = dependencyTag{name: "late shared", library: true}
257	staticDepTag          = dependencyTag{name: "static", library: true}
258	staticExportDepTag    = dependencyTag{name: "static", library: true, reexportFlags: true}
259	lateStaticDepTag      = dependencyTag{name: "late static", library: true}
260	wholeStaticDepTag     = dependencyTag{name: "whole static", library: true, reexportFlags: true}
261	headerDepTag          = dependencyTag{name: "header", library: true}
262	headerExportDepTag    = dependencyTag{name: "header", library: true, reexportFlags: true}
263	genSourceDepTag       = dependencyTag{name: "gen source"}
264	genHeaderDepTag       = dependencyTag{name: "gen header"}
265	genHeaderExportDepTag = dependencyTag{name: "gen header", reexportFlags: true}
266	objDepTag             = dependencyTag{name: "obj"}
267	crtBeginDepTag        = dependencyTag{name: "crtbegin"}
268	crtEndDepTag          = dependencyTag{name: "crtend"}
269	reuseObjTag           = dependencyTag{name: "reuse objects"}
270	ndkStubDepTag         = dependencyTag{name: "ndk stub", library: true}
271	ndkLateStubDepTag     = dependencyTag{name: "ndk late stub", library: true}
272)
273
274// Module contains the properties and members used by all C/C++ module types, and implements
275// the blueprint.Module interface.  It delegates to compiler, linker, and installer interfaces
276// to construct the output file.  Behavior can be customized with a Customizer interface
277type Module struct {
278	android.ModuleBase
279	android.DefaultableModuleBase
280
281	Properties BaseProperties
282	unused     UnusedProperties
283
284	// initialize before calling Init
285	hod      android.HostOrDeviceSupported
286	multilib android.Multilib
287
288	// delegates, initialize before calling Init
289	features  []feature
290	compiler  compiler
291	linker    linker
292	installer installer
293	stl       *stl
294	sanitize  *sanitize
295	coverage  *coverage
296	sabi      *sabi
297	vndkdep   *vndkdep
298
299	androidMkSharedLibDeps []string
300
301	outputFile android.OptionalPath
302
303	cachedToolchain config.Toolchain
304
305	subAndroidMkOnce map[subAndroidMkProvider]bool
306
307	// Flags used to compile this module
308	flags Flags
309}
310
311func (c *Module) Init() android.Module {
312	c.AddProperties(&c.Properties, &c.unused)
313	if c.compiler != nil {
314		c.AddProperties(c.compiler.compilerProps()...)
315	}
316	if c.linker != nil {
317		c.AddProperties(c.linker.linkerProps()...)
318	}
319	if c.installer != nil {
320		c.AddProperties(c.installer.installerProps()...)
321	}
322	if c.stl != nil {
323		c.AddProperties(c.stl.props()...)
324	}
325	if c.sanitize != nil {
326		c.AddProperties(c.sanitize.props()...)
327	}
328	if c.coverage != nil {
329		c.AddProperties(c.coverage.props()...)
330	}
331	if c.sabi != nil {
332		c.AddProperties(c.sabi.props()...)
333	}
334	if c.vndkdep != nil {
335		c.AddProperties(c.vndkdep.props()...)
336	}
337	for _, feature := range c.features {
338		c.AddProperties(feature.props()...)
339	}
340
341	android.InitAndroidArchModule(c, c.hod, c.multilib)
342
343	android.InitDefaultableModule(c)
344
345	return c
346}
347
348// Returns true for dependency roots (binaries)
349// TODO(ccross): also handle dlopenable libraries
350func (c *Module) isDependencyRoot() bool {
351	if root, ok := c.linker.(interface {
352		isDependencyRoot() bool
353	}); ok {
354		return root.isDependencyRoot()
355	}
356	return false
357}
358
359func (c *Module) vndk() bool {
360	return c.Properties.UseVndk
361}
362
363func (c *Module) isVndk() bool {
364	if c.vndkdep != nil {
365		return c.vndkdep.isVndk()
366	}
367	return false
368}
369
370type baseModuleContext struct {
371	android.BaseContext
372	moduleContextImpl
373}
374
375type depsContext struct {
376	android.BottomUpMutatorContext
377	moduleContextImpl
378}
379
380type moduleContext struct {
381	android.ModuleContext
382	moduleContextImpl
383}
384
385// Vendor returns true for vendor modules excluding VNDK libraries so that
386// they get installed onto the correct partition
387func (ctx *moduleContext) Vendor() bool {
388	return ctx.ModuleContext.Vendor() || (ctx.mod.vndk() && !ctx.mod.isVndk())
389}
390
391type moduleContextImpl struct {
392	mod *Module
393	ctx BaseModuleContext
394}
395
396func (ctx *moduleContextImpl) clang() bool {
397	return ctx.mod.clang(ctx.ctx)
398}
399
400func (ctx *moduleContextImpl) toolchain() config.Toolchain {
401	return ctx.mod.toolchain(ctx.ctx)
402}
403
404func (ctx *moduleContextImpl) static() bool {
405	if static, ok := ctx.mod.linker.(interface {
406		static() bool
407	}); ok {
408		return static.static()
409	}
410	return false
411}
412
413func (ctx *moduleContextImpl) staticBinary() bool {
414	if static, ok := ctx.mod.linker.(interface {
415		staticBinary() bool
416	}); ok {
417		return static.staticBinary()
418	}
419	return false
420}
421
422func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
423	return Bool(ctx.mod.Properties.No_default_compiler_flags)
424}
425
426func (ctx *moduleContextImpl) sdk() bool {
427	if ctx.ctx.Device() && !ctx.vndk() {
428		return ctx.mod.Properties.Sdk_version != ""
429	}
430	return false
431}
432
433func (ctx *moduleContextImpl) sdkVersion() string {
434	if ctx.ctx.Device() {
435		if ctx.vndk() {
436			return "current"
437		} else {
438			return ctx.mod.Properties.Sdk_version
439		}
440	}
441	return ""
442}
443
444func (ctx *moduleContextImpl) vndk() bool {
445	return ctx.mod.vndk()
446}
447
448func (ctx *moduleContextImpl) isVndk() bool {
449	return ctx.mod.isVndk()
450}
451
452func (ctx *moduleContextImpl) isVndkSp() bool {
453	if vndk := ctx.mod.vndkdep; vndk != nil {
454		return vndk.isVndkSp()
455	}
456	return false
457}
458
459// Create source abi dumps if the module belongs to the list of VndkLibraries.
460func (ctx *moduleContextImpl) createVndkSourceAbiDump() bool {
461	return ctx.ctx.Device() && (ctx.mod.isVndk() || inList(ctx.baseModuleName(), llndkLibraries))
462}
463
464func (ctx *moduleContextImpl) selectedStl() string {
465	if stl := ctx.mod.stl; stl != nil {
466		return stl.Properties.SelectedStl
467	}
468	return ""
469}
470
471func (ctx *moduleContextImpl) baseModuleName() string {
472	return ctx.mod.ModuleBase.BaseModuleName()
473}
474
475func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
476	return &Module{
477		hod:      hod,
478		multilib: multilib,
479	}
480}
481
482func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
483	module := newBaseModule(hod, multilib)
484	module.features = []feature{
485		&tidyFeature{},
486	}
487	module.stl = &stl{}
488	module.sanitize = &sanitize{}
489	module.coverage = &coverage{}
490	module.sabi = &sabi{}
491	module.vndkdep = &vndkdep{}
492	return module
493}
494
495func (c *Module) Prebuilt() *android.Prebuilt {
496	if p, ok := c.linker.(prebuiltLinkerInterface); ok {
497		return p.prebuilt()
498	}
499	return nil
500}
501
502func (c *Module) Name() string {
503	name := c.ModuleBase.Name()
504	if p, ok := c.linker.(interface {
505		Name(string) string
506	}); ok {
507		name = p.Name(name)
508	}
509	return name
510}
511
512func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
513	ctx := &moduleContext{
514		ModuleContext: actx,
515		moduleContextImpl: moduleContextImpl{
516			mod: c,
517		},
518	}
519	ctx.ctx = ctx
520
521	flags := Flags{
522		Toolchain: c.toolchain(ctx),
523		Clang:     c.clang(ctx),
524	}
525	if c.compiler != nil {
526		flags = c.compiler.compilerFlags(ctx, flags)
527	}
528	if c.linker != nil {
529		flags = c.linker.linkerFlags(ctx, flags)
530	}
531	if c.stl != nil {
532		flags = c.stl.flags(ctx, flags)
533	}
534	if c.sanitize != nil {
535		flags = c.sanitize.flags(ctx, flags)
536	}
537	if c.coverage != nil {
538		flags = c.coverage.flags(ctx, flags)
539	}
540	for _, feature := range c.features {
541		flags = feature.flags(ctx, flags)
542	}
543	if ctx.Failed() {
544		return
545	}
546
547	flags.CFlags, _ = filterList(flags.CFlags, config.IllegalFlags)
548	flags.CppFlags, _ = filterList(flags.CppFlags, config.IllegalFlags)
549	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, config.IllegalFlags)
550
551	deps := c.depsToPaths(ctx)
552	if ctx.Failed() {
553		return
554	}
555	flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)
556	c.flags = flags
557	// We need access to all the flags seen by a source file.
558	if c.sabi != nil {
559		flags = c.sabi.flags(ctx, flags)
560	}
561	// Optimization to reduce size of build.ninja
562	// Replace the long list of flags for each file with a module-local variable
563	ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
564	ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
565	ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
566	flags.CFlags = []string{"$cflags"}
567	flags.CppFlags = []string{"$cppflags"}
568	flags.AsFlags = []string{"$asflags"}
569
570	var objs Objects
571	if c.compiler != nil {
572		objs = c.compiler.compile(ctx, flags, deps)
573		if ctx.Failed() {
574			return
575		}
576	}
577
578	if c.linker != nil {
579		outputFile := c.linker.link(ctx, flags, deps, objs)
580		if ctx.Failed() {
581			return
582		}
583		c.outputFile = android.OptionalPathForPath(outputFile)
584	}
585
586	if c.installer != nil && !c.Properties.PreventInstall && c.outputFile.Valid() {
587		c.installer.install(ctx, c.outputFile.Path())
588		if ctx.Failed() {
589			return
590		}
591	}
592}
593
594func (c *Module) toolchain(ctx BaseModuleContext) config.Toolchain {
595	if c.cachedToolchain == nil {
596		c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
597	}
598	return c.cachedToolchain
599}
600
601func (c *Module) begin(ctx BaseModuleContext) {
602	if c.compiler != nil {
603		c.compiler.compilerInit(ctx)
604	}
605	if c.linker != nil {
606		c.linker.linkerInit(ctx)
607	}
608	if c.stl != nil {
609		c.stl.begin(ctx)
610	}
611	if c.sanitize != nil {
612		c.sanitize.begin(ctx)
613	}
614	if c.coverage != nil {
615		c.coverage.begin(ctx)
616	}
617	if c.sabi != nil {
618		c.sabi.begin(ctx)
619	}
620	if c.vndkdep != nil {
621		c.vndkdep.begin(ctx)
622	}
623	for _, feature := range c.features {
624		feature.begin(ctx)
625	}
626	if ctx.sdk() {
627		version, err := normalizeNdkApiLevel(ctx.sdkVersion(), ctx.Arch())
628		if err != nil {
629			ctx.PropertyErrorf("sdk_version", err.Error())
630		}
631		c.Properties.Sdk_version = version
632	}
633}
634
635func (c *Module) deps(ctx DepsContext) Deps {
636	deps := Deps{}
637
638	if c.compiler != nil {
639		deps = c.compiler.compilerDeps(ctx, deps)
640	}
641	if c.linker != nil {
642		deps = c.linker.linkerDeps(ctx, deps)
643	}
644	if c.stl != nil {
645		deps = c.stl.deps(ctx, deps)
646	}
647	if c.sanitize != nil {
648		deps = c.sanitize.deps(ctx, deps)
649	}
650	if c.coverage != nil {
651		deps = c.coverage.deps(ctx, deps)
652	}
653	if c.sabi != nil {
654		deps = c.sabi.deps(ctx, deps)
655	}
656	if c.vndkdep != nil {
657		deps = c.vndkdep.deps(ctx, deps)
658	}
659	for _, feature := range c.features {
660		deps = feature.deps(ctx, deps)
661	}
662
663	deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
664	deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
665	deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
666	deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
667	deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
668	deps.HeaderLibs = lastUniqueElements(deps.HeaderLibs)
669
670	for _, lib := range deps.ReexportSharedLibHeaders {
671		if !inList(lib, deps.SharedLibs) {
672			ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib)
673		}
674	}
675
676	for _, lib := range deps.ReexportStaticLibHeaders {
677		if !inList(lib, deps.StaticLibs) {
678			ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs: '%s'", lib)
679		}
680	}
681
682	for _, lib := range deps.ReexportHeaderLibHeaders {
683		if !inList(lib, deps.HeaderLibs) {
684			ctx.PropertyErrorf("export_header_lib_headers", "Header library not in header_libs: '%s'", lib)
685		}
686	}
687
688	for _, gen := range deps.ReexportGeneratedHeaders {
689		if !inList(gen, deps.GeneratedHeaders) {
690			ctx.PropertyErrorf("export_generated_headers", "Generated header module not in generated_headers: '%s'", gen)
691		}
692	}
693
694	return deps
695}
696
697func (c *Module) beginMutator(actx android.BottomUpMutatorContext) {
698	ctx := &baseModuleContext{
699		BaseContext: actx,
700		moduleContextImpl: moduleContextImpl{
701			mod: c,
702		},
703	}
704	ctx.ctx = ctx
705
706	c.begin(ctx)
707}
708
709func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
710	if !c.Enabled() {
711		return
712	}
713
714	ctx := &depsContext{
715		BottomUpMutatorContext: actx,
716		moduleContextImpl: moduleContextImpl{
717			mod: c,
718		},
719	}
720	ctx.ctx = ctx
721
722	deps := c.deps(ctx)
723
724	variantNdkLibs := []string{}
725	variantLateNdkLibs := []string{}
726	if ctx.Os() == android.Android {
727		version := ctx.sdkVersion()
728
729		// Rewrites the names of shared libraries into the names of the NDK
730		// libraries where appropriate. This returns two slices.
731		//
732		// The first is a list of non-variant shared libraries (either rewritten
733		// NDK libraries to the modules in prebuilts/ndk, or not rewritten
734		// because they are not NDK libraries).
735		//
736		// The second is a list of ndk_library modules. These need to be
737		// separated because they are a variation dependency and must be added
738		// in a different manner.
739		rewriteNdkLibs := func(list []string) ([]string, []string) {
740			variantLibs := []string{}
741			nonvariantLibs := []string{}
742			for _, entry := range list {
743				if ctx.sdk() && inList(entry, ndkPrebuiltSharedLibraries) {
744					if !inList(entry, ndkMigratedLibs) {
745						nonvariantLibs = append(nonvariantLibs, entry+".ndk."+version)
746					} else {
747						variantLibs = append(variantLibs, entry+ndkLibrarySuffix)
748					}
749				} else if ctx.vndk() && inList(entry, llndkLibraries) {
750					nonvariantLibs = append(nonvariantLibs, entry+llndkLibrarySuffix)
751				} else {
752					nonvariantLibs = append(nonvariantLibs, entry)
753				}
754			}
755			return nonvariantLibs, variantLibs
756		}
757
758		deps.SharedLibs, variantNdkLibs = rewriteNdkLibs(deps.SharedLibs)
759		deps.LateSharedLibs, variantLateNdkLibs = rewriteNdkLibs(deps.LateSharedLibs)
760		deps.ReexportSharedLibHeaders, _ = rewriteNdkLibs(deps.ReexportSharedLibHeaders)
761	}
762
763	for _, lib := range deps.HeaderLibs {
764		depTag := headerDepTag
765		if inList(lib, deps.ReexportHeaderLibHeaders) {
766			depTag = headerExportDepTag
767		}
768		actx.AddVariationDependencies(nil, depTag, lib)
769	}
770
771	actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
772		deps.WholeStaticLibs...)
773
774	for _, lib := range deps.StaticLibs {
775		depTag := staticDepTag
776		if inList(lib, deps.ReexportStaticLibHeaders) {
777			depTag = staticExportDepTag
778		}
779		actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, depTag, lib)
780	}
781
782	actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
783		deps.LateStaticLibs...)
784
785	for _, lib := range deps.SharedLibs {
786		depTag := sharedDepTag
787		if inList(lib, deps.ReexportSharedLibHeaders) {
788			depTag = sharedExportDepTag
789		}
790		actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, depTag, lib)
791	}
792
793	actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
794		deps.LateSharedLibs...)
795
796	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
797
798	for _, gen := range deps.GeneratedHeaders {
799		depTag := genHeaderDepTag
800		if inList(gen, deps.ReexportGeneratedHeaders) {
801			depTag = genHeaderExportDepTag
802		}
803		actx.AddDependency(c, depTag, gen)
804	}
805
806	actx.AddDependency(c, objDepTag, deps.ObjFiles...)
807
808	if deps.CrtBegin != "" {
809		actx.AddDependency(c, crtBeginDepTag, deps.CrtBegin)
810	}
811	if deps.CrtEnd != "" {
812		actx.AddDependency(c, crtEndDepTag, deps.CrtEnd)
813	}
814
815	version := ctx.sdkVersion()
816	actx.AddVariationDependencies([]blueprint.Variation{
817		{"ndk_api", version}, {"link", "shared"}}, ndkStubDepTag, variantNdkLibs...)
818	actx.AddVariationDependencies([]blueprint.Variation{
819		{"ndk_api", version}, {"link", "shared"}}, ndkLateStubDepTag, variantLateNdkLibs...)
820}
821
822func beginMutator(ctx android.BottomUpMutatorContext) {
823	if c, ok := ctx.Module().(*Module); ok && c.Enabled() {
824		c.beginMutator(ctx)
825	}
826}
827
828func (c *Module) clang(ctx BaseModuleContext) bool {
829	clang := Bool(c.Properties.Clang)
830
831	if c.Properties.Clang == nil {
832		if ctx.Host() {
833			clang = true
834		}
835
836		if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
837			clang = true
838		}
839	}
840
841	if !c.toolchain(ctx).ClangSupported() {
842		clang = false
843	}
844
845	return clang
846}
847
848// Convert dependencies to paths.  Returns a PathDeps containing paths
849func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
850	var depPaths PathDeps
851
852	// Whether a module can link to another module, taking into
853	// account NDK linking.
854	checkLinkType := func(from, to *Module) {
855		if from.Target().Os != android.Android {
856			// Host code is not restricted
857			return
858		}
859		if from.Properties.UseVndk {
860			// Though vendor code is limited by the vendor mutator,
861			// each vendor-available module needs to check
862			// link-type for VNDK.
863			if from.vndkdep != nil {
864				from.vndkdep.vndkCheckLinkType(ctx, to)
865			}
866			return
867		}
868		if from.Properties.Sdk_version == "" {
869			// Platform code can link to anything
870			return
871		}
872		if _, ok := to.linker.(*toolchainLibraryDecorator); ok {
873			// These are always allowed
874			return
875		}
876		if _, ok := to.linker.(*ndkPrebuiltLibraryLinker); ok {
877			// These are allowed, but don't set sdk_version
878			return
879		}
880		if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok {
881			// These are allowed, but don't set sdk_version
882			return
883		}
884		if _, ok := to.linker.(*stubDecorator); ok {
885			// These aren't real libraries, but are the stub shared libraries that are included in
886			// the NDK.
887			return
888		}
889		if to.Properties.Sdk_version == "" {
890			// NDK code linking to platform code is never okay.
891			ctx.ModuleErrorf("depends on non-NDK-built library %q",
892				ctx.OtherModuleName(to))
893		}
894
895		// All this point we know we have two NDK libraries, but we need to
896		// check that we're not linking against anything built against a higher
897		// API level, as it is only valid to link against older or equivalent
898		// APIs.
899
900		if from.Properties.Sdk_version == "current" {
901			// Current can link against anything.
902			return
903		} else if to.Properties.Sdk_version == "current" {
904			// Current can't be linked against by anything else.
905			ctx.ModuleErrorf("links %q built against newer API version %q",
906				ctx.OtherModuleName(to), "current")
907		}
908
909		fromApi, err := strconv.Atoi(from.Properties.Sdk_version)
910		if err != nil {
911			ctx.PropertyErrorf("sdk_version",
912				"Invalid sdk_version value (must be int): %q",
913				from.Properties.Sdk_version)
914		}
915		toApi, err := strconv.Atoi(to.Properties.Sdk_version)
916		if err != nil {
917			ctx.PropertyErrorf("sdk_version",
918				"Invalid sdk_version value (must be int): %q",
919				to.Properties.Sdk_version)
920		}
921
922		if toApi > fromApi {
923			ctx.ModuleErrorf("links %q built against newer API version %q",
924				ctx.OtherModuleName(to), to.Properties.Sdk_version)
925		}
926	}
927
928	ctx.VisitDirectDeps(func(m blueprint.Module) {
929		name := ctx.OtherModuleName(m)
930		tag := ctx.OtherModuleDependencyTag(m)
931
932		a, _ := m.(android.Module)
933		if a == nil {
934			ctx.ModuleErrorf("module %q not an android module", name)
935			return
936		}
937
938		cc, _ := m.(*Module)
939		if cc == nil {
940			switch tag {
941			case android.DefaultsDepTag, android.SourceDepTag:
942			case genSourceDepTag:
943				if genRule, ok := m.(genrule.SourceFileGenerator); ok {
944					depPaths.GeneratedSources = append(depPaths.GeneratedSources,
945						genRule.GeneratedSourceFiles()...)
946				} else {
947					ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
948				}
949				// Support exported headers from a generated_sources dependency
950				fallthrough
951			case genHeaderDepTag, genHeaderExportDepTag:
952				if genRule, ok := m.(genrule.SourceFileGenerator); ok {
953					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
954						genRule.GeneratedSourceFiles()...)
955					flags := includeDirsToFlags(genRule.GeneratedHeaderDirs())
956					depPaths.Flags = append(depPaths.Flags, flags)
957					if tag == genHeaderExportDepTag {
958						depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags)
959						depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps,
960							genRule.GeneratedSourceFiles()...)
961						// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
962						c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags)
963
964					}
965				} else {
966					ctx.ModuleErrorf("module %q is not a genrule", name)
967				}
968			default:
969				ctx.ModuleErrorf("depends on non-cc module %q", name)
970			}
971			return
972		}
973
974		if !a.Enabled() {
975			if ctx.AConfig().AllowMissingDependencies() {
976				ctx.AddMissingDependencies([]string{name})
977			} else {
978				ctx.ModuleErrorf("depends on disabled module %q", name)
979			}
980			return
981		}
982
983		if a.Target().Os != ctx.Os() {
984			ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), name)
985			return
986		}
987
988		if a.Target().Arch.ArchType != ctx.Arch().ArchType {
989			ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), name)
990			return
991		}
992
993		if tag == reuseObjTag {
994			if l, ok := cc.compiler.(libraryInterface); ok {
995				objs, flags, deps := l.reuseObjs()
996				depPaths.Objs = depPaths.Objs.Append(objs)
997				depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
998				depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...)
999				return
1000			}
1001		}
1002
1003		if t, ok := tag.(dependencyTag); ok && t.library {
1004			if i, ok := cc.linker.(exportedFlagsProducer); ok {
1005				flags := i.exportedFlags()
1006				deps := i.exportedFlagsDeps()
1007				depPaths.Flags = append(depPaths.Flags, flags...)
1008				depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, deps...)
1009
1010				if t.reexportFlags {
1011					depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
1012					depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...)
1013					// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
1014					// Re-exported flags from shared library dependencies are not included as those shared libraries
1015					// will be included in the vndk set.
1016					if tag == staticExportDepTag || tag == headerExportDepTag {
1017						c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags...)
1018					}
1019				}
1020			}
1021
1022			checkLinkType(c, cc)
1023		}
1024
1025		var ptr *android.Paths
1026		var depPtr *android.Paths
1027
1028		linkFile := cc.outputFile
1029		depFile := android.OptionalPath{}
1030
1031		switch tag {
1032		case ndkStubDepTag, sharedDepTag, sharedExportDepTag:
1033			ptr = &depPaths.SharedLibs
1034			depPtr = &depPaths.SharedLibsDeps
1035			depFile = cc.linker.(libraryInterface).toc()
1036		case lateSharedDepTag, ndkLateStubDepTag:
1037			ptr = &depPaths.LateSharedLibs
1038			depPtr = &depPaths.LateSharedLibsDeps
1039			depFile = cc.linker.(libraryInterface).toc()
1040		case staticDepTag, staticExportDepTag:
1041			ptr = &depPaths.StaticLibs
1042		case lateStaticDepTag:
1043			ptr = &depPaths.LateStaticLibs
1044		case wholeStaticDepTag:
1045			ptr = &depPaths.WholeStaticLibs
1046			staticLib, ok := cc.linker.(libraryInterface)
1047			if !ok || !staticLib.static() {
1048				ctx.ModuleErrorf("module %q not a static library", name)
1049				return
1050			}
1051
1052			if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
1053				postfix := " (required by " + ctx.OtherModuleName(m) + ")"
1054				for i := range missingDeps {
1055					missingDeps[i] += postfix
1056				}
1057				ctx.AddMissingDependencies(missingDeps)
1058			}
1059			depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs())
1060		case headerDepTag:
1061			// Nothing
1062		case objDepTag:
1063			depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
1064		case crtBeginDepTag:
1065			depPaths.CrtBegin = linkFile
1066		case crtEndDepTag:
1067			depPaths.CrtEnd = linkFile
1068		}
1069
1070		switch tag {
1071		case staticDepTag, staticExportDepTag, lateStaticDepTag:
1072			staticLib, ok := cc.linker.(libraryInterface)
1073			if !ok || !staticLib.static() {
1074				ctx.ModuleErrorf("module %q not a static library", name)
1075				return
1076			}
1077
1078			// When combining coverage files for shared libraries and executables, coverage files
1079			// in static libraries act as if they were whole static libraries. The same goes for
1080			// source based Abi dump files.
1081			depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
1082				staticLib.objs().coverageFiles...)
1083			depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
1084				staticLib.objs().sAbiDumpFiles...)
1085		}
1086
1087		if ptr != nil {
1088			if !linkFile.Valid() {
1089				ctx.ModuleErrorf("module %q missing output file", name)
1090				return
1091			}
1092			*ptr = append(*ptr, linkFile.Path())
1093		}
1094
1095		if depPtr != nil {
1096			dep := depFile
1097			if !dep.Valid() {
1098				dep = linkFile
1099			}
1100			*depPtr = append(*depPtr, dep.Path())
1101		}
1102
1103		// Export the shared libs to the make world. In doing so, .vendor suffix
1104		// is added if the lib has both core and vendor variants and this module
1105		// is building against vndk. This is because the vendor variant will be
1106		// have .vendor suffix in its name in the make world. However, if the
1107		// lib is a vendor-only lib or this lib is not building against vndk,
1108		// then the suffix is not added.
1109		switch tag {
1110		case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
1111			libName := strings.TrimSuffix(name, llndkLibrarySuffix)
1112			libName = strings.TrimPrefix(libName, "prebuilt_")
1113			isLLndk := inList(libName, llndkLibraries)
1114			if c.vndk() && (Bool(cc.Properties.Vendor_available) || isLLndk) {
1115				libName += vendorSuffix
1116			}
1117			// Note: the order of libs in this list is not important because
1118			// they merely serve as dependencies in the make world and do not
1119			// affect this lib itself.
1120			c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, libName)
1121		}
1122	})
1123
1124	// Dedup exported flags from dependencies
1125	depPaths.Flags = firstUniqueElements(depPaths.Flags)
1126
1127	return depPaths
1128}
1129
1130func (c *Module) InstallInData() bool {
1131	if c.installer == nil {
1132		return false
1133	}
1134	return c.installer.inData()
1135}
1136
1137func (c *Module) InstallInSanitizerDir() bool {
1138	if c.installer == nil {
1139		return false
1140	}
1141	if c.sanitize != nil && c.sanitize.inSanitizerDir() {
1142		return true
1143	}
1144	return c.installer.inSanitizerDir()
1145}
1146
1147func (c *Module) HostToolPath() android.OptionalPath {
1148	if c.installer == nil {
1149		return android.OptionalPath{}
1150	}
1151	return c.installer.hostToolPath()
1152}
1153
1154//
1155// Defaults
1156//
1157type Defaults struct {
1158	android.ModuleBase
1159	android.DefaultsModuleBase
1160}
1161
1162func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1163}
1164
1165func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) {
1166}
1167
1168func defaultsFactory() android.Module {
1169	return DefaultsFactory()
1170}
1171
1172func DefaultsFactory(props ...interface{}) android.Module {
1173	module := &Defaults{}
1174
1175	module.AddProperties(props...)
1176	module.AddProperties(
1177		&BaseProperties{},
1178		&BaseCompilerProperties{},
1179		&BaseLinkerProperties{},
1180		&LibraryProperties{},
1181		&FlagExporterProperties{},
1182		&BinaryLinkerProperties{},
1183		&TestProperties{},
1184		&TestBinaryProperties{},
1185		&UnusedProperties{},
1186		&StlProperties{},
1187		&SanitizeProperties{},
1188		&StripProperties{},
1189		&InstallerProperties{},
1190		&TidyProperties{},
1191		&CoverageProperties{},
1192		&SAbiProperties{},
1193		&VndkProperties{},
1194	)
1195
1196	android.InitDefaultsModule(module)
1197
1198	return module
1199}
1200
1201const (
1202	// coreMode is the variant used for framework-private libraries, or
1203	// SDK libraries. (which framework-private libraries can use)
1204	coreMode = "core"
1205
1206	// vendorMode is the variant used for /vendor code that compiles
1207	// against the VNDK.
1208	vendorMode = "vendor"
1209)
1210
1211func vendorMutator(mctx android.BottomUpMutatorContext) {
1212	if mctx.Os() != android.Android {
1213		return
1214	}
1215
1216	m, ok := mctx.Module().(*Module)
1217	if !ok {
1218		return
1219	}
1220
1221	// Sanity check
1222	if Bool(m.Properties.Vendor_available) && mctx.Vendor() {
1223		mctx.PropertyErrorf("vendor_available",
1224			"doesn't make sense at the same time as `vendor: true` or `proprietary: true`")
1225		return
1226	}
1227	if vndk := m.vndkdep; vndk != nil {
1228		if vndk.isVndk() && !Bool(m.Properties.Vendor_available) {
1229			mctx.PropertyErrorf("vndk",
1230				"has to define `vendor_available: true` to enable vndk")
1231			return
1232		}
1233		if !vndk.isVndk() && vndk.isVndkSp() {
1234			mctx.PropertyErrorf("vndk",
1235				"must set `enabled: true` to set `support_system_process: true`")
1236			return
1237		}
1238	}
1239
1240	if !mctx.DeviceConfig().CompileVndk() {
1241		// If the device isn't compiling against the VNDK, we always
1242		// use the core mode.
1243		mctx.CreateVariations(coreMode)
1244	} else if _, ok := m.linker.(*llndkStubDecorator); ok {
1245		// LL-NDK stubs only exist in the vendor variant, since the
1246		// real libraries will be used in the core variant.
1247		mctx.CreateVariations(vendorMode)
1248	} else if Bool(m.Properties.Vendor_available) {
1249		// This will be available in both /system and /vendor
1250		// or a /system directory that is available to vendor.
1251		mod := mctx.CreateVariations(coreMode, vendorMode)
1252		mod[1].(*Module).Properties.UseVndk = true
1253	} else if mctx.Vendor() && m.Properties.Sdk_version == "" {
1254		// This will be available in /vendor only
1255		mod := mctx.CreateVariations(vendorMode)
1256		mod[0].(*Module).Properties.UseVndk = true
1257	} else {
1258		// This is either in /system (or similar: /data), or is a
1259		// modules built with the NDK. Modules built with the NDK
1260		// will be restricted using the existing link type checks.
1261		mctx.CreateVariations(coreMode)
1262	}
1263}
1264
1265// firstUniqueElements returns all unique elements of a slice, keeping the first copy of each
1266// modifies the slice contents in place, and returns a subslice of the original slice
1267func firstUniqueElements(list []string) []string {
1268	k := 0
1269outer:
1270	for i := 0; i < len(list); i++ {
1271		for j := 0; j < k; j++ {
1272			if list[i] == list[j] {
1273				continue outer
1274			}
1275		}
1276		list[k] = list[i]
1277		k++
1278	}
1279	return list[:k]
1280}
1281
1282// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
1283// modifies the slice contents in place, and returns a subslice of the original slice
1284func lastUniqueElements(list []string) []string {
1285	totalSkip := 0
1286	for i := len(list) - 1; i >= totalSkip; i-- {
1287		skip := 0
1288		for j := i - 1; j >= totalSkip; j-- {
1289			if list[i] == list[j] {
1290				skip++
1291			} else {
1292				list[j+skip] = list[j]
1293			}
1294		}
1295		totalSkip += skip
1296	}
1297	return list[totalSkip:]
1298}
1299
1300func getCurrentNdkPrebuiltVersion(ctx DepsContext) string {
1301	if ctx.AConfig().PlatformSdkVersionInt() > config.NdkMaxPrebuiltVersionInt {
1302		return strconv.Itoa(config.NdkMaxPrebuiltVersionInt)
1303	}
1304	return ctx.AConfig().PlatformSdkVersion()
1305}
1306
1307var Bool = proptools.Bool
1308