• 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	"fmt"
23	"path/filepath"
24	"strings"
25
26	"github.com/google/blueprint"
27	"github.com/google/blueprint/proptools"
28
29	"android/soong"
30	"android/soong/common"
31	"android/soong/genrule"
32)
33
34func init() {
35	soong.RegisterModuleType("cc_library_static", libraryStaticFactory)
36	soong.RegisterModuleType("cc_library_shared", librarySharedFactory)
37	soong.RegisterModuleType("cc_library", libraryFactory)
38	soong.RegisterModuleType("cc_object", objectFactory)
39	soong.RegisterModuleType("cc_binary", binaryFactory)
40	soong.RegisterModuleType("cc_test", testFactory)
41	soong.RegisterModuleType("cc_benchmark", benchmarkFactory)
42	soong.RegisterModuleType("cc_defaults", defaultsFactory)
43
44	soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
45	soong.RegisterModuleType("ndk_prebuilt_library", ndkPrebuiltLibraryFactory)
46	soong.RegisterModuleType("ndk_prebuilt_object", ndkPrebuiltObjectFactory)
47	soong.RegisterModuleType("ndk_prebuilt_static_stl", ndkPrebuiltStaticStlFactory)
48	soong.RegisterModuleType("ndk_prebuilt_shared_stl", ndkPrebuiltSharedStlFactory)
49
50	soong.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory)
51	soong.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory)
52	soong.RegisterModuleType("cc_binary_host", binaryHostFactory)
53	soong.RegisterModuleType("cc_test_host", testHostFactory)
54	soong.RegisterModuleType("cc_benchmark_host", benchmarkHostFactory)
55
56	// LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
57	// the Go initialization order because this package depends on common, so common's init
58	// functions will run first.
59	common.RegisterBottomUpMutator("link", linkageMutator)
60	common.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
61	common.RegisterBottomUpMutator("deps", depsMutator)
62}
63
64var (
65	HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
66
67	LibcRoot = pctx.SourcePathVariable("LibcRoot", "bionic/libc")
68	LibmRoot = pctx.SourcePathVariable("LibmRoot", "bionic/libm")
69)
70
71// Flags used by lots of devices.  Putting them in package static variables will save bytes in
72// build.ninja so they aren't repeated for every file
73var (
74	commonGlobalCflags = []string{
75		"-DANDROID",
76		"-fmessage-length=0",
77		"-W",
78		"-Wall",
79		"-Wno-unused",
80		"-Winit-self",
81		"-Wpointer-arith",
82		"-fdebug-prefix-map=/proc/self/cwd=",
83
84		// COMMON_RELEASE_CFLAGS
85		"-DNDEBUG",
86		"-UDEBUG",
87	}
88
89	deviceGlobalCflags = []string{
90		"-fdiagnostics-color",
91
92		// TARGET_ERROR_FLAGS
93		"-Werror=return-type",
94		"-Werror=non-virtual-dtor",
95		"-Werror=address",
96		"-Werror=sequence-point",
97		"-Werror=date-time",
98	}
99
100	hostGlobalCflags = []string{}
101
102	commonGlobalCppflags = []string{
103		"-Wsign-promo",
104	}
105
106	noOverrideGlobalCflags = []string{
107		"-Werror=int-to-pointer-cast",
108		"-Werror=pointer-to-int-cast",
109	}
110
111	illegalFlags = []string{
112		"-w",
113	}
114)
115
116func init() {
117	pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
118	pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
119	pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
120	pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
121
122	pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
123
124	pctx.StaticVariable("commonClangGlobalCflags",
125		strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
126	pctx.StaticVariable("deviceClangGlobalCflags",
127		strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
128	pctx.StaticVariable("hostClangGlobalCflags",
129		strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
130	pctx.StaticVariable("noOverrideClangGlobalCflags",
131		strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
132
133	pctx.StaticVariable("commonClangGlobalCppflags",
134		strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
135
136	// Everything in this list is a crime against abstraction and dependency tracking.
137	// Do not add anything to this list.
138	pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
139		[]string{
140			"system/core/include",
141			"system/media/audio/include",
142			"hardware/libhardware/include",
143			"hardware/libhardware_legacy/include",
144			"hardware/ril/include",
145			"libnativehelper/include",
146			"frameworks/native/include",
147			"frameworks/native/opengl/include",
148			"frameworks/av/include",
149			"frameworks/base/include",
150		})
151	// This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
152	// with this, since there is no associated library.
153	pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
154		[]string{"libnativehelper/include/nativehelper"})
155
156	pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
157	pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
158		if override := config.(common.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
159			return override, nil
160		}
161		return "${clangDefaultBase}", nil
162	})
163	pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
164		if override := config.(common.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
165			return override, nil
166		}
167		return "clang-2690385", nil
168	})
169	pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}/bin")
170}
171
172type Deps struct {
173	SharedLibs, LateSharedLibs                  []string
174	StaticLibs, LateStaticLibs, WholeStaticLibs []string
175
176	ObjFiles common.Paths
177
178	Cflags, ReexportedCflags []string
179
180	CrtBegin, CrtEnd string
181}
182
183type PathDeps struct {
184	SharedLibs, LateSharedLibs                  common.Paths
185	StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths
186
187	ObjFiles               common.Paths
188	WholeStaticLibObjFiles common.Paths
189
190	Cflags, ReexportedCflags []string
191
192	CrtBegin, CrtEnd common.OptionalPath
193}
194
195type Flags struct {
196	GlobalFlags []string // Flags that apply to C, C++, and assembly source files
197	AsFlags     []string // Flags that apply to assembly source files
198	CFlags      []string // Flags that apply to C and C++ source files
199	ConlyFlags  []string // Flags that apply to C source files
200	CppFlags    []string // Flags that apply to C++ source files
201	YaccFlags   []string // Flags that apply to Yacc source files
202	LdFlags     []string // Flags that apply to linker command lines
203
204	Nocrt     bool
205	Toolchain Toolchain
206	Clang     bool
207
208	RequiredInstructionSet string
209}
210
211type BaseCompilerProperties struct {
212	// list of source files used to compile the C/C++ module.  May be .c, .cpp, or .S files.
213	Srcs []string `android:"arch_variant"`
214
215	// list of source files that should not be used to build the C/C++ module.
216	// This is most useful in the arch/multilib variants to remove non-common files
217	Exclude_srcs []string `android:"arch_variant"`
218
219	// list of module-specific flags that will be used for C and C++ compiles.
220	Cflags []string `android:"arch_variant"`
221
222	// list of module-specific flags that will be used for C++ compiles
223	Cppflags []string `android:"arch_variant"`
224
225	// list of module-specific flags that will be used for C compiles
226	Conlyflags []string `android:"arch_variant"`
227
228	// list of module-specific flags that will be used for .S compiles
229	Asflags []string `android:"arch_variant"`
230
231	// list of module-specific flags that will be used for C and C++ compiles when
232	// compiling with clang
233	Clang_cflags []string `android:"arch_variant"`
234
235	// list of module-specific flags that will be used for .S compiles when
236	// compiling with clang
237	Clang_asflags []string `android:"arch_variant"`
238
239	// list of module-specific flags that will be used for .y and .yy compiles
240	Yaccflags []string
241
242	// the instruction set architecture to use to compile the C/C++
243	// module.
244	Instruction_set string `android:"arch_variant"`
245
246	// list of directories relative to the root of the source tree that will
247	// be added to the include path using -I.
248	// If possible, don't use this.  If adding paths from the current directory use
249	// local_include_dirs, if adding paths from other modules use export_include_dirs in
250	// that module.
251	Include_dirs []string `android:"arch_variant"`
252
253	// list of files relative to the root of the source tree that will be included
254	// using -include.
255	// If possible, don't use this.
256	Include_files []string `android:"arch_variant"`
257
258	// list of directories relative to the Blueprints file that will
259	// be added to the include path using -I
260	Local_include_dirs []string `android:"arch_variant"`
261
262	// list of files relative to the Blueprints file that will be included
263	// using -include.
264	// If possible, don't use this.
265	Local_include_files []string `android:"arch_variant"`
266
267	// pass -frtti instead of -fno-rtti
268	Rtti *bool
269
270	Debug, Release struct {
271		// list of module-specific flags that will be used for C and C++ compiles in debug or
272		// release builds
273		Cflags []string `android:"arch_variant"`
274	} `android:"arch_variant"`
275}
276
277type BaseLinkerProperties struct {
278	// list of modules whose object files should be linked into this module
279	// in their entirety.  For static library modules, all of the .o files from the intermediate
280	// directory of the dependency will be linked into this modules .a file.  For a shared library,
281	// the dependency's .a file will be linked into this module using -Wl,--whole-archive.
282	Whole_static_libs []string `android:"arch_variant"`
283
284	// list of modules that should be statically linked into this module.
285	Static_libs []string `android:"arch_variant"`
286
287	// list of modules that should be dynamically linked into this module.
288	Shared_libs []string `android:"arch_variant"`
289
290	// list of module-specific flags that will be used for all link steps
291	Ldflags []string `android:"arch_variant"`
292
293	// don't insert default compiler flags into asflags, cflags,
294	// cppflags, conlyflags, ldflags, or include_dirs
295	No_default_compiler_flags *bool
296
297	// list of system libraries that will be dynamically linked to
298	// shared library and executable modules.  If unset, generally defaults to libc
299	// and libm.  Set to [] to prevent linking against libc and libm.
300	System_shared_libs []string
301
302	// allow the module to contain undefined symbols.  By default,
303	// modules cannot contain undefined symbols that are not satisified by their immediate
304	// dependencies.  Set this flag to true to remove --no-undefined from the linker flags.
305	// This flag should only be necessary for compiling low-level libraries like libc.
306	Allow_undefined_symbols *bool
307
308	// don't link in libgcc.a
309	No_libgcc *bool
310
311	// -l arguments to pass to linker for host-provided shared libraries
312	Host_ldlibs []string `android:"arch_variant"`
313}
314
315type LibraryCompilerProperties struct {
316	Static struct {
317		Srcs         []string `android:"arch_variant"`
318		Exclude_srcs []string `android:"arch_variant"`
319		Cflags       []string `android:"arch_variant"`
320	} `android:"arch_variant"`
321	Shared struct {
322		Srcs         []string `android:"arch_variant"`
323		Exclude_srcs []string `android:"arch_variant"`
324		Cflags       []string `android:"arch_variant"`
325	} `android:"arch_variant"`
326}
327
328type LibraryLinkerProperties struct {
329	Static struct {
330		Whole_static_libs []string `android:"arch_variant"`
331		Static_libs       []string `android:"arch_variant"`
332		Shared_libs       []string `android:"arch_variant"`
333	} `android:"arch_variant"`
334	Shared struct {
335		Whole_static_libs []string `android:"arch_variant"`
336		Static_libs       []string `android:"arch_variant"`
337		Shared_libs       []string `android:"arch_variant"`
338	} `android:"arch_variant"`
339
340	// local file name to pass to the linker as --version_script
341	Version_script *string `android:"arch_variant"`
342	// local file name to pass to the linker as -unexported_symbols_list
343	Unexported_symbols_list *string `android:"arch_variant"`
344	// local file name to pass to the linker as -force_symbols_not_weak_list
345	Force_symbols_not_weak_list *string `android:"arch_variant"`
346	// local file name to pass to the linker as -force_symbols_weak_list
347	Force_symbols_weak_list *string `android:"arch_variant"`
348
349	// list of directories relative to the Blueprints file that will
350	// be added to the include path using -I for any module that links against this module
351	Export_include_dirs []string `android:"arch_variant"`
352
353	// don't link in crt_begin and crt_end.  This flag should only be necessary for
354	// compiling crt or libc.
355	Nocrt *bool `android:"arch_variant"`
356}
357
358type BinaryLinkerProperties struct {
359	// compile executable with -static
360	Static_executable *bool
361
362	// set the name of the output
363	Stem string `android:"arch_variant"`
364
365	// append to the name of the output
366	Suffix string `android:"arch_variant"`
367
368	// if set, add an extra objcopy --prefix-symbols= step
369	Prefix_symbols string
370}
371
372type TestLinkerProperties struct {
373	// if set, build against the gtest library. Defaults to true.
374	Gtest bool
375
376	// Create a separate binary for each source file.  Useful when there is
377	// global state that can not be torn down and reset between each test suite.
378	Test_per_src *bool
379}
380
381// Properties used to compile all C or C++ modules
382type BaseProperties struct {
383	// compile module with clang instead of gcc
384	Clang *bool `android:"arch_variant"`
385
386	// Minimum sdk version supported when compiling against the ndk
387	Sdk_version string
388
389	// don't insert default compiler flags into asflags, cflags,
390	// cppflags, conlyflags, ldflags, or include_dirs
391	No_default_compiler_flags *bool
392}
393
394type InstallerProperties struct {
395	// install to a subdirectory of the default install path for the module
396	Relative_install_path string
397}
398
399type UnusedProperties struct {
400	Native_coverage  *bool
401	Required         []string
402	Sanitize         []string `android:"arch_variant"`
403	Sanitize_recover []string
404	Strip            string
405	Tags             []string
406}
407
408type ModuleContextIntf interface {
409	module() *Module
410	static() bool
411	staticBinary() bool
412	clang() bool
413	toolchain() Toolchain
414	noDefaultCompilerFlags() bool
415	sdk() bool
416	sdkVersion() string
417}
418
419type ModuleContext interface {
420	common.AndroidModuleContext
421	ModuleContextIntf
422}
423
424type BaseModuleContext interface {
425	common.AndroidBaseContext
426	ModuleContextIntf
427}
428
429type Customizer interface {
430	CustomizeProperties(BaseModuleContext)
431	Properties() []interface{}
432}
433
434type feature interface {
435	begin(ctx BaseModuleContext)
436	deps(ctx BaseModuleContext, deps Deps) Deps
437	flags(ctx ModuleContext, flags Flags) Flags
438	props() []interface{}
439}
440
441type compiler interface {
442	feature
443	compile(ctx ModuleContext, flags Flags) common.Paths
444}
445
446type linker interface {
447	feature
448	link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
449}
450
451type installer interface {
452	props() []interface{}
453	install(ctx ModuleContext, path common.Path)
454	inData() bool
455}
456
457// Module contains the properties and members used by all C/C++ module types, and implements
458// the blueprint.Module interface.  It delegates to compiler, linker, and installer interfaces
459// to construct the output file.  Behavior can be customized with a Customizer interface
460type Module struct {
461	common.AndroidModuleBase
462	common.DefaultableModule
463
464	Properties BaseProperties
465	unused     UnusedProperties
466
467	// initialize before calling Init
468	hod      common.HostOrDeviceSupported
469	multilib common.Multilib
470
471	// delegates, initialize before calling Init
472	customizer Customizer
473	features   []feature
474	compiler   compiler
475	linker     linker
476	installer  installer
477
478	deps       Deps
479	outputFile common.OptionalPath
480
481	cachedToolchain Toolchain
482}
483
484func (c *Module) Init() (blueprint.Module, []interface{}) {
485	props := []interface{}{&c.Properties, &c.unused}
486	if c.customizer != nil {
487		props = append(props, c.customizer.Properties()...)
488	}
489	if c.compiler != nil {
490		props = append(props, c.compiler.props()...)
491	}
492	if c.linker != nil {
493		props = append(props, c.linker.props()...)
494	}
495	if c.installer != nil {
496		props = append(props, c.installer.props()...)
497	}
498	for _, feature := range c.features {
499		props = append(props, feature.props()...)
500	}
501
502	_, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
503
504	return common.InitDefaultableModule(c, c, props...)
505}
506
507type baseModuleContext struct {
508	common.AndroidBaseContext
509	moduleContextImpl
510}
511
512type moduleContext struct {
513	common.AndroidModuleContext
514	moduleContextImpl
515}
516
517type moduleContextImpl struct {
518	mod *Module
519	ctx BaseModuleContext
520}
521
522func (ctx *moduleContextImpl) module() *Module {
523	return ctx.mod
524}
525
526func (ctx *moduleContextImpl) clang() bool {
527	return ctx.mod.clang(ctx.ctx)
528}
529
530func (ctx *moduleContextImpl) toolchain() Toolchain {
531	return ctx.mod.toolchain(ctx.ctx)
532}
533
534func (ctx *moduleContextImpl) static() bool {
535	if ctx.mod.linker == nil {
536		panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
537	}
538	if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
539		return linker.static()
540	} else {
541		panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
542	}
543}
544
545func (ctx *moduleContextImpl) staticBinary() bool {
546	if ctx.mod.linker == nil {
547		panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
548	}
549	if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
550		return linker.staticBinary()
551	} else {
552		panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
553	}
554}
555
556func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
557	return Bool(ctx.mod.Properties.No_default_compiler_flags)
558}
559
560func (ctx *moduleContextImpl) sdk() bool {
561	return ctx.mod.Properties.Sdk_version != ""
562}
563
564func (ctx *moduleContextImpl) sdkVersion() string {
565	return ctx.mod.Properties.Sdk_version
566}
567
568func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
569	return &Module{
570		hod:      hod,
571		multilib: multilib,
572	}
573}
574
575func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
576	module := newBaseModule(hod, multilib)
577	module.features = []feature{
578		&stlFeature{},
579	}
580	return module
581}
582
583func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
584	ctx := &moduleContext{
585		AndroidModuleContext: actx,
586		moduleContextImpl: moduleContextImpl{
587			mod: c,
588		},
589	}
590	ctx.ctx = ctx
591
592	flags := Flags{
593		Toolchain: c.toolchain(ctx),
594		Clang:     c.clang(ctx),
595	}
596
597	if c.compiler != nil {
598		flags = c.compiler.flags(ctx, flags)
599	}
600	if c.linker != nil {
601		flags = c.linker.flags(ctx, flags)
602	}
603	for _, feature := range c.features {
604		flags = feature.flags(ctx, flags)
605	}
606	if ctx.Failed() {
607		return
608	}
609
610	flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
611	flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
612	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
613
614	// Optimization to reduce size of build.ninja
615	// Replace the long list of flags for each file with a module-local variable
616	ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
617	ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
618	ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
619	flags.CFlags = []string{"$cflags"}
620	flags.CppFlags = []string{"$cppflags"}
621	flags.AsFlags = []string{"$asflags"}
622
623	deps := c.depsToPaths(actx, c.deps)
624	if ctx.Failed() {
625		return
626	}
627
628	flags.CFlags = append(flags.CFlags, deps.Cflags...)
629
630	var objFiles common.Paths
631	if c.compiler != nil {
632		objFiles = c.compiler.compile(ctx, flags)
633		if ctx.Failed() {
634			return
635		}
636	}
637
638	if c.linker != nil {
639		outputFile := c.linker.link(ctx, flags, deps, objFiles)
640		if ctx.Failed() {
641			return
642		}
643		c.outputFile = common.OptionalPathForPath(outputFile)
644
645		if c.installer != nil {
646			c.installer.install(ctx, outputFile)
647			if ctx.Failed() {
648				return
649			}
650		}
651	}
652}
653
654func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
655	if c.cachedToolchain == nil {
656		arch := ctx.Arch()
657		hod := ctx.HostOrDevice()
658		ht := ctx.HostType()
659		factory := toolchainFactories[hod][ht][arch.ArchType]
660		if factory == nil {
661			ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
662			return nil
663		}
664		c.cachedToolchain = factory(arch)
665	}
666	return c.cachedToolchain
667}
668
669func (c *Module) begin(ctx BaseModuleContext) {
670	if c.compiler != nil {
671		c.compiler.begin(ctx)
672	}
673	if c.linker != nil {
674		c.linker.begin(ctx)
675	}
676	for _, feature := range c.features {
677		feature.begin(ctx)
678	}
679}
680
681func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
682	ctx := &baseModuleContext{
683		AndroidBaseContext: actx,
684		moduleContextImpl: moduleContextImpl{
685			mod: c,
686		},
687	}
688	ctx.ctx = ctx
689
690	if c.customizer != nil {
691		c.customizer.CustomizeProperties(ctx)
692	}
693
694	c.begin(ctx)
695
696	c.deps = Deps{}
697
698	if c.compiler != nil {
699		c.deps = c.compiler.deps(ctx, c.deps)
700	}
701	if c.linker != nil {
702		c.deps = c.linker.deps(ctx, c.deps)
703	}
704	for _, feature := range c.features {
705		c.deps = feature.deps(ctx, c.deps)
706	}
707
708	c.deps.WholeStaticLibs = lastUniqueElements(c.deps.WholeStaticLibs)
709	c.deps.StaticLibs = lastUniqueElements(c.deps.StaticLibs)
710	c.deps.LateStaticLibs = lastUniqueElements(c.deps.LateStaticLibs)
711	c.deps.SharedLibs = lastUniqueElements(c.deps.SharedLibs)
712	c.deps.LateSharedLibs = lastUniqueElements(c.deps.LateSharedLibs)
713
714	staticLibs := c.deps.WholeStaticLibs
715	staticLibs = append(staticLibs, c.deps.StaticLibs...)
716	staticLibs = append(staticLibs, c.deps.LateStaticLibs...)
717	actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticLibs...)
718
719	sharedLibs := c.deps.SharedLibs
720	sharedLibs = append(sharedLibs, c.deps.LateSharedLibs...)
721	actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedLibs...)
722
723	actx.AddDependency(ctx.module(), c.deps.ObjFiles.Strings()...)
724	if c.deps.CrtBegin != "" {
725		actx.AddDependency(ctx.module(), c.deps.CrtBegin)
726	}
727	if c.deps.CrtEnd != "" {
728		actx.AddDependency(ctx.module(), c.deps.CrtEnd)
729	}
730}
731
732func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
733	if c, ok := ctx.Module().(*Module); ok {
734		c.depsMutator(ctx)
735	}
736}
737
738func (c *Module) clang(ctx BaseModuleContext) bool {
739	clang := Bool(c.Properties.Clang)
740
741	if c.Properties.Clang == nil {
742		if ctx.Host() {
743			clang = true
744		}
745
746		if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
747			clang = true
748		}
749	}
750
751	if !c.toolchain(ctx).ClangSupported() {
752		clang = false
753	}
754
755	return clang
756}
757
758func (c *Module) depsToPathsFromList(ctx common.AndroidModuleContext,
759	names []string) (modules []common.AndroidModule,
760	outputFiles common.Paths, exportedFlags []string) {
761
762	for _, n := range names {
763		found := false
764		ctx.VisitDirectDeps(func(m blueprint.Module) {
765			otherName := ctx.OtherModuleName(m)
766			if otherName != n {
767				return
768			}
769
770			if a, ok := m.(*Module); ok {
771				if !a.Enabled() {
772					ctx.ModuleErrorf("depends on disabled module %q", otherName)
773					return
774				}
775				if a.HostOrDevice() != ctx.HostOrDevice() {
776					ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
777						otherName)
778					return
779				}
780
781				if outputFile := a.outputFile; outputFile.Valid() {
782					if found {
783						ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
784						return
785					}
786					outputFiles = append(outputFiles, outputFile.Path())
787					modules = append(modules, a)
788					if i, ok := a.linker.(exportedFlagsProducer); ok {
789						exportedFlags = append(exportedFlags, i.exportedFlags()...)
790					}
791					found = true
792				} else {
793					ctx.ModuleErrorf("module %q missing output file", otherName)
794					return
795				}
796			} else {
797				ctx.ModuleErrorf("module %q not an android module", otherName)
798				return
799			}
800		})
801		if !found && !inList(n, ctx.GetMissingDependencies()) {
802			ctx.ModuleErrorf("unsatisified dependency on %q", n)
803		}
804	}
805
806	return modules, outputFiles, exportedFlags
807}
808
809// Convert dependency names to paths.  Takes a Deps containing names and returns a PathDeps
810// containing paths
811func (c *Module) depsToPaths(ctx common.AndroidModuleContext, deps Deps) PathDeps {
812	var depPaths PathDeps
813	var newCflags []string
814
815	var wholeStaticLibModules []common.AndroidModule
816
817	wholeStaticLibModules, depPaths.WholeStaticLibs, newCflags =
818		c.depsToPathsFromList(ctx, deps.WholeStaticLibs)
819	depPaths.Cflags = append(depPaths.Cflags, newCflags...)
820	depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, newCflags...)
821
822	for _, am := range wholeStaticLibModules {
823		if m, ok := am.(*Module); ok {
824			if staticLib, ok := m.linker.(*libraryLinker); ok && staticLib.static() {
825				if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
826					postfix := " (required by " + ctx.OtherModuleName(m) + ")"
827					for i := range missingDeps {
828						missingDeps[i] += postfix
829					}
830					ctx.AddMissingDependencies(missingDeps)
831				}
832				depPaths.WholeStaticLibObjFiles =
833					append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
834			} else {
835				ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
836			}
837		} else {
838			ctx.ModuleErrorf("module %q not an android module", ctx.OtherModuleName(m))
839		}
840	}
841
842	_, depPaths.StaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.StaticLibs)
843	depPaths.Cflags = append(depPaths.Cflags, newCflags...)
844
845	_, depPaths.LateStaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateStaticLibs)
846	depPaths.Cflags = append(depPaths.Cflags, newCflags...)
847
848	_, depPaths.SharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.SharedLibs)
849	depPaths.Cflags = append(depPaths.Cflags, newCflags...)
850
851	_, depPaths.LateSharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateSharedLibs)
852	depPaths.Cflags = append(depPaths.Cflags, newCflags...)
853
854	ctx.VisitDirectDeps(func(bm blueprint.Module) {
855		if m, ok := bm.(*Module); ok {
856			otherName := ctx.OtherModuleName(m)
857			if otherName == deps.CrtBegin {
858				depPaths.CrtBegin = m.outputFile
859			} else if otherName == deps.CrtEnd {
860				depPaths.CrtEnd = m.outputFile
861			} else {
862				output := m.outputFile
863				if output.Valid() {
864					depPaths.ObjFiles = append(depPaths.ObjFiles, output.Path())
865				} else {
866					ctx.ModuleErrorf("module %s did not provide an output file", otherName)
867				}
868			}
869		}
870	})
871
872	return depPaths
873}
874
875func (c *Module) InstallInData() bool {
876	if c.installer == nil {
877		return false
878	}
879	return c.installer.inData()
880}
881
882// Compiler
883
884type baseCompiler struct {
885	Properties BaseCompilerProperties
886}
887
888var _ compiler = (*baseCompiler)(nil)
889
890func (compiler *baseCompiler) props() []interface{} {
891	return []interface{}{&compiler.Properties}
892}
893
894func (compiler *baseCompiler) begin(ctx BaseModuleContext)                {}
895func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps { return deps }
896
897// Create a Flags struct that collects the compile flags from global values,
898// per-target values, module type values, and per-module Blueprints properties
899func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
900	toolchain := ctx.toolchain()
901
902	flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
903	flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
904	flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
905	flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
906	flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
907
908	// Include dir cflags
909	rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
910	localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
911	flags.GlobalFlags = append(flags.GlobalFlags,
912		includeDirsToFlags(localIncludeDirs),
913		includeDirsToFlags(rootIncludeDirs))
914
915	rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
916	localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
917
918	flags.GlobalFlags = append(flags.GlobalFlags,
919		includeFilesToFlags(rootIncludeFiles),
920		includeFilesToFlags(localIncludeFiles))
921
922	if !ctx.noDefaultCompilerFlags() {
923		if !ctx.sdk() || ctx.Host() {
924			flags.GlobalFlags = append(flags.GlobalFlags,
925				"${commonGlobalIncludes}",
926				toolchain.IncludeFlags(),
927				"${commonNativehelperInclude}")
928		}
929
930		flags.GlobalFlags = append(flags.GlobalFlags, []string{
931			"-I" + common.PathForModuleSrc(ctx).String(),
932			"-I" + common.PathForModuleOut(ctx).String(),
933			"-I" + common.PathForModuleGen(ctx).String(),
934		}...)
935	}
936
937	instructionSet := compiler.Properties.Instruction_set
938	if flags.RequiredInstructionSet != "" {
939		instructionSet = flags.RequiredInstructionSet
940	}
941	instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
942	if flags.Clang {
943		instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
944	}
945	if err != nil {
946		ctx.ModuleErrorf("%s", err)
947	}
948
949	// TODO: debug
950	flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
951
952	if flags.Clang {
953		flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
954		flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
955		flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
956		flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
957		flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
958		flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
959
960		target := "-target " + toolchain.ClangTriple()
961		gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
962
963		flags.CFlags = append(flags.CFlags, target, gccPrefix)
964		flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
965		flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
966	}
967
968	if !ctx.noDefaultCompilerFlags() {
969		flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
970
971		if flags.Clang {
972			flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
973			flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
974			flags.GlobalFlags = append(flags.GlobalFlags,
975				toolchain.ClangCflags(),
976				"${commonClangGlobalCflags}",
977				fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
978
979			flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
980		} else {
981			flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
982			flags.GlobalFlags = append(flags.GlobalFlags,
983				toolchain.Cflags(),
984				"${commonGlobalCflags}",
985				fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
986		}
987
988		if Bool(ctx.AConfig().ProductVariables.Brillo) {
989			flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
990		}
991
992		if ctx.Device() {
993			if Bool(compiler.Properties.Rtti) {
994				flags.CppFlags = append(flags.CppFlags, "-frtti")
995			} else {
996				flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
997			}
998		}
999
1000		flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
1001
1002		if flags.Clang {
1003			flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
1004		} else {
1005			flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
1006		}
1007	}
1008
1009	if flags.Clang {
1010		flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1011	} else {
1012		flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
1013	}
1014	flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1015
1016	if !ctx.sdk() {
1017		if ctx.Host() && !flags.Clang {
1018			// The host GCC doesn't support C++14 (and is deprecated, so likely
1019			// never will). Build these modules with C++11.
1020			flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1021		} else {
1022			flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1023		}
1024	}
1025
1026	// We can enforce some rules more strictly in the code we own. strict
1027	// indicates if this is code that we can be stricter with. If we have
1028	// rules that we want to apply to *our* code (but maybe can't for
1029	// vendor/device specific things), we could extend this to be a ternary
1030	// value.
1031	strict := true
1032	if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1033		strict = false
1034	}
1035
1036	// Can be used to make some annotations stricter for code we can fix
1037	// (such as when we mark functions as deprecated).
1038	if strict {
1039		flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1040	}
1041
1042	return flags
1043}
1044
1045func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1046	// Compile files listed in c.Properties.Srcs into objects
1047	objFiles := compiler.compileObjs(ctx, flags, "", compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
1048	if ctx.Failed() {
1049		return nil
1050	}
1051
1052	var genSrcs common.Paths
1053	ctx.VisitDirectDeps(func(module blueprint.Module) {
1054		if gen, ok := module.(genrule.SourceFileGenerator); ok {
1055			genSrcs = append(genSrcs, gen.GeneratedSourceFiles()...)
1056		}
1057	})
1058
1059	if len(genSrcs) != 0 {
1060		genObjs := TransformSourceToObj(ctx, "", genSrcs, flagsToBuilderFlags(flags), nil)
1061		objFiles = append(objFiles, genObjs...)
1062	}
1063
1064	return objFiles
1065}
1066
1067// Compile a list of source files into objects a specified subdirectory
1068func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
1069	subdir string, srcFiles, excludes []string) common.Paths {
1070
1071	buildFlags := flagsToBuilderFlags(flags)
1072
1073	inputFiles := ctx.ExpandSources(srcFiles, excludes)
1074	srcPaths, deps := genSources(ctx, inputFiles, buildFlags)
1075
1076	return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
1077}
1078
1079// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1080type baseLinker struct {
1081	Properties        BaseLinkerProperties
1082	dynamicProperties struct {
1083		VariantIsShared       bool `blueprint:"mutated"`
1084		VariantIsStatic       bool `blueprint:"mutated"`
1085		VariantIsStaticBinary bool `blueprint:"mutated"`
1086	}
1087}
1088
1089func (linker *baseLinker) begin(ctx BaseModuleContext) {}
1090
1091func (linker *baseLinker) props() []interface{} {
1092	return []interface{}{&linker.Properties, &linker.dynamicProperties}
1093}
1094
1095func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1096	deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1097	deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1098	deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
1099
1100	if ctx.ModuleName() != "libcompiler_rt-extras" {
1101		deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
1102	}
1103
1104	if ctx.Device() {
1105		// libgcc and libatomic have to be last on the command line
1106		deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1107		if !Bool(linker.Properties.No_libgcc) {
1108			deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
1109		}
1110
1111		if !linker.static() {
1112			if linker.Properties.System_shared_libs != nil {
1113				deps.LateSharedLibs = append(deps.LateSharedLibs,
1114					linker.Properties.System_shared_libs...)
1115			} else if !ctx.sdk() {
1116				deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1117			}
1118		}
1119
1120		if ctx.sdk() {
1121			version := ctx.sdkVersion()
1122			deps.SharedLibs = append(deps.SharedLibs,
1123				"ndk_libc."+version,
1124				"ndk_libm."+version,
1125			)
1126		}
1127	}
1128
1129	return deps
1130}
1131
1132func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1133	toolchain := ctx.toolchain()
1134
1135	flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1136
1137	if !ctx.noDefaultCompilerFlags() {
1138		if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1139			flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1140		}
1141
1142		if flags.Clang {
1143			flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1144		} else {
1145			flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1146		}
1147
1148		if ctx.Host() {
1149			flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1150		}
1151	}
1152
1153	if !flags.Clang {
1154		flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1155	}
1156
1157	return flags
1158}
1159
1160func (linker *baseLinker) static() bool {
1161	return linker.dynamicProperties.VariantIsStatic
1162}
1163
1164func (linker *baseLinker) staticBinary() bool {
1165	return linker.dynamicProperties.VariantIsStaticBinary
1166}
1167
1168func (linker *baseLinker) setStatic(static bool) {
1169	linker.dynamicProperties.VariantIsStatic = static
1170}
1171
1172type baseLinkerInterface interface {
1173	// Returns true if the build options for the module have selected a static or shared build
1174	buildStatic() bool
1175	buildShared() bool
1176
1177	// Sets whether a specific variant is static or shared
1178	setStatic(bool)
1179
1180	// Returns whether a specific variant is a static library or binary
1181	static() bool
1182
1183	// Returns whether a module is a static binary
1184	staticBinary() bool
1185}
1186
1187type exportedFlagsProducer interface {
1188	exportedFlags() []string
1189}
1190
1191type baseInstaller struct {
1192	Properties InstallerProperties
1193
1194	dir   string
1195	dir64 string
1196	data  bool
1197
1198	path common.OutputPath
1199}
1200
1201var _ installer = (*baseInstaller)(nil)
1202
1203func (installer *baseInstaller) props() []interface{} {
1204	return []interface{}{&installer.Properties}
1205}
1206
1207func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1208	subDir := installer.dir
1209	if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1210		subDir = installer.dir64
1211	}
1212	dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1213	installer.path = ctx.InstallFile(dir, file)
1214}
1215
1216func (installer *baseInstaller) inData() bool {
1217	return installer.data
1218}
1219
1220//
1221// Combined static+shared libraries
1222//
1223
1224type libraryCompiler struct {
1225	baseCompiler
1226
1227	linker     *libraryLinker
1228	Properties LibraryCompilerProperties
1229
1230	// For reusing static library objects for shared library
1231	reuseFrom     *libraryCompiler
1232	reuseObjFiles common.Paths
1233}
1234
1235var _ compiler = (*libraryCompiler)(nil)
1236
1237func (library *libraryCompiler) props() []interface{} {
1238	props := library.baseCompiler.props()
1239	return append(props, &library.Properties)
1240}
1241
1242func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1243	flags = library.baseCompiler.flags(ctx, flags)
1244
1245	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1246	// all code is position independent, and then those warnings get promoted to
1247	// errors.
1248	if ctx.HostType() != common.Windows {
1249		flags.CFlags = append(flags.CFlags, "-fPIC")
1250	}
1251
1252	if library.linker.static() {
1253		flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
1254	} else {
1255		flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
1256	}
1257
1258	return flags
1259}
1260
1261func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1262	var objFiles common.Paths
1263
1264	if library.reuseFrom != library && library.reuseFrom.Properties.Static.Cflags == nil &&
1265		library.Properties.Shared.Cflags == nil {
1266		objFiles = append(common.Paths(nil), library.reuseFrom.reuseObjFiles...)
1267	} else {
1268		objFiles = library.baseCompiler.compile(ctx, flags)
1269		library.reuseObjFiles = objFiles
1270	}
1271
1272	if library.linker.static() {
1273		objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
1274			library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs)...)
1275	} else {
1276		objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
1277			library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs)...)
1278	}
1279
1280	return objFiles
1281}
1282
1283type libraryLinker struct {
1284	baseLinker
1285
1286	Properties LibraryLinkerProperties
1287
1288	dynamicProperties struct {
1289		BuildStatic bool `blueprint:"mutated"`
1290		BuildShared bool `blueprint:"mutated"`
1291	}
1292
1293	exportFlags []string
1294
1295	// If we're used as a whole_static_lib, our missing dependencies need
1296	// to be given
1297	wholeStaticMissingDeps []string
1298
1299	// For whole_static_libs
1300	objFiles common.Paths
1301}
1302
1303var _ linker = (*libraryLinker)(nil)
1304var _ exportedFlagsProducer = (*libraryLinker)(nil)
1305
1306func (library *libraryLinker) props() []interface{} {
1307	props := library.baseLinker.props()
1308	return append(props, &library.Properties, &library.dynamicProperties)
1309}
1310
1311func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1312	flags = library.baseLinker.flags(ctx, flags)
1313
1314	flags.Nocrt = Bool(library.Properties.Nocrt)
1315
1316	if !library.static() {
1317		libName := ctx.ModuleName()
1318		// GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1319		sharedFlag := "-Wl,-shared"
1320		if flags.Clang || ctx.Host() {
1321			sharedFlag = "-shared"
1322		}
1323		if ctx.Device() {
1324			flags.LdFlags = append(flags.LdFlags,
1325				"-nostdlib",
1326				"-Wl,--gc-sections",
1327			)
1328		}
1329
1330		if ctx.Darwin() {
1331			flags.LdFlags = append(flags.LdFlags,
1332				"-dynamiclib",
1333				"-single_module",
1334				//"-read_only_relocs suppress",
1335				"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
1336			)
1337		} else {
1338			flags.LdFlags = append(flags.LdFlags,
1339				sharedFlag,
1340				"-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
1341			)
1342		}
1343	}
1344
1345	return flags
1346}
1347
1348func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1349	deps = library.baseLinker.deps(ctx, deps)
1350	if library.static() {
1351		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1352		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1353		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1354	} else {
1355		if ctx.Device() && !Bool(library.Properties.Nocrt) {
1356			if !ctx.sdk() {
1357				deps.CrtBegin = "crtbegin_so"
1358				deps.CrtEnd = "crtend_so"
1359			} else {
1360				deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1361				deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1362			}
1363		}
1364		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1365		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1366		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1367	}
1368
1369	return deps
1370}
1371
1372func (library *libraryLinker) exportedFlags() []string {
1373	return library.exportFlags
1374}
1375
1376func (library *libraryLinker) linkStatic(ctx ModuleContext,
1377	flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1378
1379	objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
1380	library.objFiles = objFiles
1381
1382	outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
1383
1384	if ctx.Darwin() {
1385		TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
1386	} else {
1387		TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
1388	}
1389
1390	library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
1391
1392	ctx.CheckbuildFile(outputFile)
1393
1394	return outputFile
1395}
1396
1397func (library *libraryLinker) linkShared(ctx ModuleContext,
1398	flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1399
1400	outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
1401
1402	var linkerDeps common.Paths
1403
1404	versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1405	unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1406	forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1407	forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
1408	if !ctx.Darwin() {
1409		if versionScript.Valid() {
1410			flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
1411			linkerDeps = append(linkerDeps, versionScript.Path())
1412		}
1413		if unexportedSymbols.Valid() {
1414			ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1415		}
1416		if forceNotWeakSymbols.Valid() {
1417			ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1418		}
1419		if forceWeakSymbols.Valid() {
1420			ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1421		}
1422	} else {
1423		if versionScript.Valid() {
1424			ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1425		}
1426		if unexportedSymbols.Valid() {
1427			flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
1428			linkerDeps = append(linkerDeps, unexportedSymbols.Path())
1429		}
1430		if forceNotWeakSymbols.Valid() {
1431			flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
1432			linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
1433		}
1434		if forceWeakSymbols.Valid() {
1435			flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
1436			linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
1437		}
1438	}
1439
1440	sharedLibs := deps.SharedLibs
1441	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1442
1443	TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1444		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1445		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile)
1446
1447	return outputFile
1448}
1449
1450func (library *libraryLinker) link(ctx ModuleContext,
1451	flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1452
1453	var out common.Path
1454	if library.static() {
1455		out = library.linkStatic(ctx, flags, deps, objFiles)
1456	} else {
1457		out = library.linkShared(ctx, flags, deps, objFiles)
1458	}
1459
1460	includeDirs := common.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)
1461	library.exportFlags = []string{includeDirsToFlags(includeDirs)}
1462	library.exportFlags = append(library.exportFlags, deps.ReexportedCflags...)
1463
1464	return out
1465}
1466
1467func (library *libraryLinker) buildStatic() bool {
1468	return library.dynamicProperties.BuildStatic
1469}
1470
1471func (library *libraryLinker) buildShared() bool {
1472	return library.dynamicProperties.BuildShared
1473}
1474
1475func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1476	return library.wholeStaticMissingDeps
1477}
1478
1479type libraryInstaller struct {
1480	baseInstaller
1481
1482	linker *libraryLinker
1483}
1484
1485func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1486	if !library.linker.static() {
1487		library.baseInstaller.install(ctx, file)
1488	}
1489}
1490
1491func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1492	module := newModule(hod, common.MultilibBoth)
1493
1494	linker := &libraryLinker{}
1495	linker.dynamicProperties.BuildShared = shared
1496	linker.dynamicProperties.BuildStatic = static
1497	module.linker = linker
1498
1499	module.compiler = &libraryCompiler{
1500		linker: linker,
1501	}
1502	module.installer = &libraryInstaller{
1503		baseInstaller: baseInstaller{
1504			dir:   "lib",
1505			dir64: "lib64",
1506		},
1507		linker: linker,
1508	}
1509
1510	return module
1511}
1512
1513func libraryFactory() (blueprint.Module, []interface{}) {
1514	module := NewLibrary(common.HostAndDeviceSupported, true, true)
1515	return module.Init()
1516}
1517
1518//
1519// Objects (for crt*.o)
1520//
1521
1522type objectLinker struct {
1523}
1524
1525func objectFactory() (blueprint.Module, []interface{}) {
1526	module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1527	module.compiler = &baseCompiler{}
1528	module.linker = &objectLinker{}
1529	return module.Init()
1530}
1531
1532func (*objectLinker) props() []interface{} {
1533	return nil
1534}
1535
1536func (*objectLinker) begin(ctx BaseModuleContext) {}
1537
1538func (*objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1539	// object files can't have any dynamic dependencies
1540	return deps
1541}
1542
1543func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
1544	return flags
1545}
1546
1547func (object *objectLinker) link(ctx ModuleContext,
1548	flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1549
1550	objFiles = append(objFiles, deps.ObjFiles...)
1551
1552	var outputFile common.Path
1553	if len(objFiles) == 1 {
1554		outputFile = objFiles[0]
1555	} else {
1556		output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
1557		TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
1558		outputFile = output
1559	}
1560
1561	ctx.CheckbuildFile(outputFile)
1562	return outputFile
1563}
1564
1565//
1566// Executables
1567//
1568
1569type binaryLinker struct {
1570	baseLinker
1571
1572	Properties BinaryLinkerProperties
1573
1574	hostToolPath common.OptionalPath
1575}
1576
1577var _ linker = (*binaryLinker)(nil)
1578
1579func (binary *binaryLinker) props() []interface{} {
1580	return append(binary.baseLinker.props(), &binary.Properties)
1581}
1582
1583func (binary *binaryLinker) buildStatic() bool {
1584	return Bool(binary.Properties.Static_executable)
1585}
1586
1587func (binary *binaryLinker) buildShared() bool {
1588	return !Bool(binary.Properties.Static_executable)
1589}
1590
1591func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
1592	stem := ctx.ModuleName()
1593	if binary.Properties.Stem != "" {
1594		stem = binary.Properties.Stem
1595	}
1596
1597	return stem + binary.Properties.Suffix
1598}
1599
1600func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1601	deps = binary.baseLinker.deps(ctx, deps)
1602	if ctx.Device() {
1603		if !ctx.sdk() {
1604			if Bool(binary.Properties.Static_executable) {
1605				deps.CrtBegin = "crtbegin_static"
1606			} else {
1607				deps.CrtBegin = "crtbegin_dynamic"
1608			}
1609			deps.CrtEnd = "crtend_android"
1610		} else {
1611			if Bool(binary.Properties.Static_executable) {
1612				deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
1613			} else {
1614				deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
1615			}
1616			deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
1617		}
1618
1619		if Bool(binary.Properties.Static_executable) {
1620			if inList("libc++_static", deps.StaticLibs) {
1621				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
1622			}
1623			// static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1624			// --start-group/--end-group along with libgcc.  If they are in deps.StaticLibs,
1625			// move them to the beginning of deps.LateStaticLibs
1626			var groupLibs []string
1627			deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
1628				[]string{"libc", "libc_nomalloc", "libcompiler_rt"})
1629			deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
1630		}
1631	}
1632
1633	if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1634		ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1635			"from static libs or set static_executable: true")
1636	}
1637	return deps
1638}
1639
1640func NewBinary(hod common.HostOrDeviceSupported) *Module {
1641	module := newModule(hod, common.MultilibFirst)
1642	module.compiler = &baseCompiler{}
1643	module.linker = &binaryLinker{}
1644	module.installer = &baseInstaller{
1645		dir: "bin",
1646	}
1647	return module
1648}
1649
1650func binaryFactory() (blueprint.Module, []interface{}) {
1651	module := NewBinary(common.HostAndDeviceSupported)
1652	return module.Init()
1653}
1654
1655func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
1656	if ctx.Darwin() {
1657		binary.Properties.Static_executable = proptools.BoolPtr(false)
1658	}
1659	if Bool(binary.Properties.Static_executable) {
1660		binary.dynamicProperties.VariantIsStaticBinary = true
1661	}
1662}
1663
1664func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1665	flags = binary.baseLinker.flags(ctx, flags)
1666
1667	if ctx.Host() {
1668		flags.LdFlags = append(flags.LdFlags, "-pie")
1669		if ctx.HostType() == common.Windows {
1670			flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1671		}
1672	}
1673
1674	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1675	// all code is position independent, and then those warnings get promoted to
1676	// errors.
1677	if ctx.HostType() != common.Windows {
1678		flags.CFlags = append(flags.CFlags, "-fpie")
1679	}
1680
1681	if ctx.Device() {
1682		if Bool(binary.Properties.Static_executable) {
1683			// Clang driver needs -static to create static executable.
1684			// However, bionic/linker uses -shared to overwrite.
1685			// Linker for x86 targets does not allow coexistance of -static and -shared,
1686			// so we add -static only if -shared is not used.
1687			if !inList("-shared", flags.LdFlags) {
1688				flags.LdFlags = append(flags.LdFlags, "-static")
1689			}
1690
1691			flags.LdFlags = append(flags.LdFlags,
1692				"-nostdlib",
1693				"-Bstatic",
1694				"-Wl,--gc-sections",
1695			)
1696
1697		} else {
1698			linker := "/system/bin/linker"
1699			if flags.Toolchain.Is64Bit() {
1700				linker += "64"
1701			}
1702
1703			flags.LdFlags = append(flags.LdFlags,
1704				"-pie",
1705				"-nostdlib",
1706				"-Bdynamic",
1707				fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1708				"-Wl,--gc-sections",
1709				"-Wl,-z,nocopyreloc",
1710			)
1711		}
1712	} else if ctx.Darwin() {
1713		flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
1714	}
1715
1716	return flags
1717}
1718
1719func (binary *binaryLinker) link(ctx ModuleContext,
1720	flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1721
1722	outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
1723	if ctx.HostOrDevice().Host() {
1724		binary.hostToolPath = common.OptionalPathForPath(outputFile)
1725	}
1726	ret := outputFile
1727
1728	if binary.Properties.Prefix_symbols != "" {
1729		afterPrefixSymbols := outputFile
1730		outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate")
1731		TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1732			flagsToBuilderFlags(flags), afterPrefixSymbols)
1733	}
1734
1735	var linkerDeps common.Paths
1736
1737	sharedLibs := deps.SharedLibs
1738	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1739
1740	TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
1741		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
1742		flagsToBuilderFlags(flags), outputFile)
1743
1744	return ret
1745}
1746
1747func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1748	return binary.hostToolPath
1749}
1750
1751func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
1752	if m, ok := mctx.Module().(*Module); ok {
1753		if test, ok := m.linker.(*testLinker); ok {
1754			if Bool(test.Properties.Test_per_src) {
1755				testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
1756				for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1757					testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
1758				}
1759				tests := mctx.CreateLocalVariations(testNames...)
1760				for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1761					tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
1762					tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
1763				}
1764			}
1765		}
1766	}
1767}
1768
1769type testLinker struct {
1770	binaryLinker
1771	Properties TestLinkerProperties
1772}
1773
1774func (test *testLinker) props() []interface{} {
1775	return append(test.binaryLinker.props(), &test.Properties)
1776}
1777
1778func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
1779	flags = test.binaryLinker.flags(ctx, flags)
1780
1781	if !test.Properties.Gtest {
1782		return flags
1783	}
1784
1785	flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
1786	if ctx.Host() {
1787		flags.CFlags = append(flags.CFlags, "-O0", "-g")
1788
1789		if ctx.HostType() == common.Windows {
1790			flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
1791		} else {
1792			flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
1793			flags.LdFlags = append(flags.LdFlags, "-lpthread")
1794		}
1795	} else {
1796		flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
1797	}
1798
1799	// TODO(danalbert): Make gtest export its dependencies.
1800	flags.CFlags = append(flags.CFlags,
1801		"-I"+common.PathForSource(ctx, "external/gtest/include").String())
1802
1803	return flags
1804}
1805
1806func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1807	if test.Properties.Gtest {
1808		deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
1809	}
1810	deps = test.binaryLinker.deps(ctx, deps)
1811	return deps
1812}
1813
1814type testInstaller struct {
1815	baseInstaller
1816}
1817
1818func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
1819	installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
1820	installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
1821	installer.baseInstaller.install(ctx, file)
1822}
1823
1824func NewTest(hod common.HostOrDeviceSupported) *Module {
1825	module := newModule(hod, common.MultilibBoth)
1826	module.compiler = &baseCompiler{}
1827	linker := &testLinker{}
1828	linker.Properties.Gtest = true
1829	module.linker = linker
1830	module.installer = &testInstaller{
1831		baseInstaller: baseInstaller{
1832			dir:   "nativetest",
1833			dir64: "nativetest64",
1834			data:  true,
1835		},
1836	}
1837	return module
1838}
1839
1840func testFactory() (blueprint.Module, []interface{}) {
1841	module := NewTest(common.HostAndDeviceSupported)
1842	return module.Init()
1843}
1844
1845type benchmarkLinker struct {
1846	binaryLinker
1847}
1848
1849func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1850	deps = benchmark.binaryLinker.deps(ctx, deps)
1851	deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
1852	return deps
1853}
1854
1855func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
1856	module := newModule(hod, common.MultilibFirst)
1857	module.compiler = &baseCompiler{}
1858	module.linker = &benchmarkLinker{}
1859	module.installer = &baseInstaller{
1860		dir:   "nativetest",
1861		dir64: "nativetest64",
1862		data:  true,
1863	}
1864	return module
1865}
1866
1867func benchmarkFactory() (blueprint.Module, []interface{}) {
1868	module := NewBenchmark(common.HostAndDeviceSupported)
1869	return module.Init()
1870}
1871
1872//
1873// Static library
1874//
1875
1876func libraryStaticFactory() (blueprint.Module, []interface{}) {
1877	module := NewLibrary(common.HostAndDeviceSupported, false, true)
1878	return module.Init()
1879}
1880
1881//
1882// Shared libraries
1883//
1884
1885func librarySharedFactory() (blueprint.Module, []interface{}) {
1886	module := NewLibrary(common.HostAndDeviceSupported, true, false)
1887	return module.Init()
1888}
1889
1890//
1891// Host static library
1892//
1893
1894func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
1895	module := NewLibrary(common.HostSupported, false, true)
1896	return module.Init()
1897}
1898
1899//
1900// Host Shared libraries
1901//
1902
1903func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
1904	module := NewLibrary(common.HostSupported, true, false)
1905	return module.Init()
1906}
1907
1908//
1909// Host Binaries
1910//
1911
1912func binaryHostFactory() (blueprint.Module, []interface{}) {
1913	module := NewBinary(common.HostSupported)
1914	return module.Init()
1915}
1916
1917//
1918// Host Tests
1919//
1920
1921func testHostFactory() (blueprint.Module, []interface{}) {
1922	module := NewTest(common.HostSupported)
1923	return module.Init()
1924}
1925
1926//
1927// Host Benchmarks
1928//
1929
1930func benchmarkHostFactory() (blueprint.Module, []interface{}) {
1931	module := NewBenchmark(common.HostSupported)
1932	return module.Init()
1933}
1934
1935//
1936// Defaults
1937//
1938type Defaults struct {
1939	common.AndroidModuleBase
1940	common.DefaultsModule
1941}
1942
1943func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
1944}
1945
1946func defaultsFactory() (blueprint.Module, []interface{}) {
1947	module := &Defaults{}
1948
1949	propertyStructs := []interface{}{
1950		&BaseProperties{},
1951		&BaseCompilerProperties{},
1952		&BaseLinkerProperties{},
1953		&LibraryCompilerProperties{},
1954		&LibraryLinkerProperties{},
1955		&BinaryLinkerProperties{},
1956		&TestLinkerProperties{},
1957		&UnusedProperties{},
1958		&StlProperties{},
1959	}
1960
1961	_, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
1962		common.MultilibDefault, propertyStructs...)
1963
1964	return common.InitDefaultsModule(module, module, propertyStructs...)
1965}
1966
1967//
1968// Device libraries shipped with gcc
1969//
1970
1971type toolchainLibraryLinker struct {
1972	baseLinker
1973}
1974
1975var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
1976
1977func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1978	// toolchain libraries can't have any dependencies
1979	return deps
1980}
1981
1982func (*toolchainLibraryLinker) buildStatic() bool {
1983	return true
1984}
1985
1986func (*toolchainLibraryLinker) buildShared() bool {
1987	return false
1988}
1989
1990func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
1991	module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1992	module.compiler = &baseCompiler{}
1993	module.linker = &toolchainLibraryLinker{}
1994	module.Properties.Clang = proptools.BoolPtr(false)
1995	return module.Init()
1996}
1997
1998func (library *toolchainLibraryLinker) link(ctx ModuleContext,
1999	flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
2000
2001	libName := ctx.ModuleName() + staticLibraryExtension
2002	outputFile := common.PathForModuleOut(ctx, libName)
2003
2004	if flags.Clang {
2005		ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2006	}
2007
2008	CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
2009
2010	ctx.CheckbuildFile(outputFile)
2011
2012	return outputFile
2013}
2014
2015// NDK prebuilt libraries.
2016//
2017// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2018// either (with the exception of the shared STLs, which are installed to the app's directory rather
2019// than to the system image).
2020
2021func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2022	return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2023		version, toolchain.Name()))
2024}
2025
2026func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
2027	ext string, version string) common.Path {
2028
2029	// NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2030	// We want to translate to just NAME.EXT
2031	name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2032	dir := getNdkLibDir(ctx, toolchain, version)
2033	return dir.Join(ctx, name+ext)
2034}
2035
2036type ndkPrebuiltObjectLinker struct {
2037	objectLinker
2038}
2039
2040func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2041	// NDK objects can't have any dependencies
2042	return deps
2043}
2044
2045func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2046	module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2047	module.linker = &ndkPrebuiltObjectLinker{}
2048	return module.Init()
2049}
2050
2051func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2052	deps PathDeps, objFiles common.Paths) common.Path {
2053	// A null build step, but it sets up the output path.
2054	if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2055		ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2056	}
2057
2058	return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
2059}
2060
2061type ndkPrebuiltLibraryLinker struct {
2062	libraryLinker
2063	Properties struct {
2064		Export_include_dirs []string `android:"arch_variant"`
2065	}
2066}
2067
2068var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2069var _ exportedFlagsProducer = (*libraryLinker)(nil)
2070
2071func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
2072	return []interface{}{&ndk.Properties}
2073}
2074
2075func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2076	// NDK libraries can't have any dependencies
2077	return deps
2078}
2079
2080func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2081	module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2082	linker := &ndkPrebuiltLibraryLinker{}
2083	linker.dynamicProperties.BuildShared = true
2084	module.linker = linker
2085	return module.Init()
2086}
2087
2088func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2089	deps PathDeps, objFiles common.Paths) common.Path {
2090	// A null build step, but it sets up the output path.
2091	if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2092		ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2093	}
2094
2095	includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2096	ndk.exportFlags = []string{common.JoinWithPrefix(includeDirs.Strings(), "-isystem ")}
2097
2098	return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2099		ctx.sdkVersion())
2100}
2101
2102// The NDK STLs are slightly different from the prebuilt system libraries:
2103//     * Are not specific to each platform version.
2104//     * The libraries are not in a predictable location for each STL.
2105
2106type ndkPrebuiltStlLinker struct {
2107	ndkPrebuiltLibraryLinker
2108}
2109
2110func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2111	module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2112	linker := &ndkPrebuiltStlLinker{}
2113	linker.dynamicProperties.BuildShared = true
2114	module.linker = linker
2115	return module.Init()
2116}
2117
2118func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2119	module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2120	linker := &ndkPrebuiltStlLinker{}
2121	linker.dynamicProperties.BuildStatic = true
2122	module.linker = linker
2123	return module.Init()
2124}
2125
2126func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
2127	gccVersion := toolchain.GccVersion()
2128	var libDir string
2129	switch stl {
2130	case "libstlport":
2131		libDir = "cxx-stl/stlport/libs"
2132	case "libc++":
2133		libDir = "cxx-stl/llvm-libc++/libs"
2134	case "libgnustl":
2135		libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2136	}
2137
2138	if libDir != "" {
2139		ndkSrcRoot := "prebuilts/ndk/current/sources"
2140		return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
2141	}
2142
2143	ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
2144	return common.PathForSource(ctx, "")
2145}
2146
2147func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2148	deps PathDeps, objFiles common.Paths) common.Path {
2149	// A null build step, but it sets up the output path.
2150	if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2151		ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2152	}
2153
2154	includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2155	ndk.exportFlags = []string{includeDirsToFlags(includeDirs)}
2156
2157	libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
2158	libExt := flags.Toolchain.ShlibSuffix()
2159	if ndk.dynamicProperties.BuildStatic {
2160		libExt = staticLibraryExtension
2161	}
2162
2163	stlName := strings.TrimSuffix(libName, "_shared")
2164	stlName = strings.TrimSuffix(stlName, "_static")
2165	libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
2166	return libDir.Join(ctx, libName+libExt)
2167}
2168
2169func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
2170	if m, ok := mctx.Module().(*Module); ok {
2171		if m.linker != nil {
2172			if linker, ok := m.linker.(baseLinkerInterface); ok {
2173				var modules []blueprint.Module
2174				if linker.buildStatic() && linker.buildShared() {
2175					modules = mctx.CreateLocalVariations("static", "shared")
2176					modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2177					modules[0].(*Module).installer = nil
2178					modules[1].(*Module).linker.(baseLinkerInterface).setStatic(false)
2179				} else if linker.buildStatic() {
2180					modules = mctx.CreateLocalVariations("static")
2181					modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2182					modules[0].(*Module).installer = nil
2183				} else if linker.buildShared() {
2184					modules = mctx.CreateLocalVariations("shared")
2185					modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2186				} else {
2187					panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2188				}
2189
2190				if _, ok := m.compiler.(*libraryCompiler); ok {
2191					reuseFrom := modules[0].(*Module).compiler.(*libraryCompiler)
2192					for _, m := range modules {
2193						m.(*Module).compiler.(*libraryCompiler).reuseFrom = reuseFrom
2194					}
2195				}
2196			}
2197		}
2198	}
2199}
2200
2201// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2202// modifies the slice contents in place, and returns a subslice of the original slice
2203func lastUniqueElements(list []string) []string {
2204	totalSkip := 0
2205	for i := len(list) - 1; i >= totalSkip; i-- {
2206		skip := 0
2207		for j := i - 1; j >= totalSkip; j-- {
2208			if list[i] == list[j] {
2209				skip++
2210			} else {
2211				list[j+skip] = list[j]
2212			}
2213		}
2214		totalSkip += skip
2215	}
2216	return list[totalSkip:]
2217}
2218
2219var Bool = proptools.Bool
2220