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