blob: 8abfae7da02bc441fca64a2775b271ecaf134b99 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001//
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package cc
15
16// This file contains the module types for compiling C/C++ for Android, and converts the properties
17// into the flags and filenames necessary to pass to the compiler. The final creation of the rules
18// is handled in builder.go
19
20import (
21 "blueprint"
22 "blueprint/pathtools"
23 "fmt"
24 "path/filepath"
25 "strings"
26
27 "android/soong/common"
28)
29
30type Config interface {
31 SrcDir() string
32 PrebuiltOS() string
33}
34
35var (
36 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", Config.PrebuiltOS)
37 SrcDir = pctx.VariableConfigMethod("SrcDir", Config.SrcDir)
38
39 LibcRoot = pctx.StaticVariable("LibcRoot", "${SrcDir}/bionic/libc")
40 LibmRoot = pctx.StaticVariable("LibmRoot", "${SrcDir}/bionic/libm")
41)
42
43// Flags used by lots of devices. Putting them in package static variables will save bytes in
44// build.ninja so they aren't repeated for every file
45var (
46 commonGlobalCflags = []string{
47 "-DANDROID",
48 "-fmessage-length=0",
49 "-W",
50 "-Wall",
51 "-Wno-unused",
52 "-Winit-self",
53 "-Wpointer-arith",
54
55 // COMMON_RELEASE_CFLAGS
56 "-DNDEBUG",
57 "-UDEBUG",
58 }
59
60 deviceGlobalCflags = []string{
61 // TARGET_ERROR_FLAGS
62 "-Werror=return-type",
63 "-Werror=non-virtual-dtor",
64 "-Werror=address",
65 "-Werror=sequence-point",
66 }
67
68 hostGlobalCflags = []string{}
69
70 commonGlobalCppflags = []string{
71 "-Wsign-promo",
72 "-std=gnu++11",
73 }
74)
75
76func init() {
77 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
78 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
79 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
80
81 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
82
83 pctx.StaticVariable("commonClangGlobalCflags",
84 strings.Join(clangFilterUnknownCflags(commonGlobalCflags), " "))
85 pctx.StaticVariable("deviceClangGlobalCflags",
86 strings.Join(clangFilterUnknownCflags(deviceGlobalCflags), " "))
87 pctx.StaticVariable("hostClangGlobalCflags",
88 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Tim Kilbournf2948142015-03-11 12:03:03 -070089 pctx.StaticVariable("commonClangGlobalCppflags",
90 strings.Join(clangFilterUnknownCflags(commonGlobalCppflags), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -080091
92 // Everything in this list is a crime against abstraction and dependency tracking.
93 // Do not add anything to this list.
94 pctx.StaticVariable("commonGlobalIncludes", strings.Join([]string{
95 "-isystem ${SrcDir}/system/core/include",
96 "-isystem ${SrcDir}/hardware/libhardware/include",
97 "-isystem ${SrcDir}/hardware/libhardware_legacy/include",
98 "-isystem ${SrcDir}/hardware/ril/include",
99 "-isystem ${SrcDir}/libnativehelper/include",
100 "-isystem ${SrcDir}/frameworks/native/include",
101 "-isystem ${SrcDir}/frameworks/native/opengl/include",
102 "-isystem ${SrcDir}/frameworks/av/include",
103 "-isystem ${SrcDir}/frameworks/base/include",
104 }, " "))
105
106 pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/${HostPrebuiltTag}/host/3.6/bin/")
107}
108
109// CcProperties describes properties used to compile all C or C++ modules
110type ccProperties struct {
111 // srcs: list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
112 Srcs []string `android:"arch_variant,arch_subtract"`
113
114 // cflags: list of module-specific flags that will be used for C and C++ compiles.
115 Cflags []string `android:"arch_variant"`
116
117 // cppflags: list of module-specific flags that will be used for C++ compiles
118 Cppflags []string `android:"arch_variant"`
119
120 // conlyflags: list of module-specific flags that will be used for C compiles
121 Conlyflags []string `android:"arch_variant"`
122
123 // asflags: list of module-specific flags that will be used for .S compiles
124 Asflags []string `android:"arch_variant"`
125
126 // ldflags: list of module-specific flags that will be used for all link steps
127 Ldflags []string `android:"arch_variant"`
128
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700129 // instruction_set: the instruction set architecture to use to compile the C/C++
130 // module.
131 Instruction_set string `android:"arch_variant"`
132
Colin Cross3f40fa42015-01-30 17:27:36 -0800133 // include_dirs: list of directories relative to the root of the source tree that will
134 // be added to the include path using -I.
135 // If possible, don't use this. If adding paths from the current directory use
136 // local_include_dirs, if adding paths from other modules use export_include_dirs in
137 // that module.
138 Include_dirs []string `android:"arch_variant"`
139
140 // local_include_dirs: list of directories relative to the Blueprints file that will
141 // be added to the include path using -I
142 Local_include_dirs []string `android:"arch_variant"`
143
144 // export_include_dirs: list of directories relative to the Blueprints file that will
145 // be added to the include path using -I for any module that links against this module
146 Export_include_dirs []string
147
148 // clang_cflags: list of module-specific flags that will be used for C and C++ compiles when
149 // compiling with clang
150 Clang_cflags []string `android:"arch_variant"`
151
152 // clang_asflags: list of module-specific flags that will be used for .S compiles when
153 // compiling with clang
154 Clang_asflags []string `android:"arch_variant"`
155
156 // system_shared_libs: list of system libraries that will be dynamically linked to
157 // shared library and executable modules. If unset, generally defaults to libc
158 // and libm. Set to [] to prevent linking against libc and libm.
159 System_shared_libs []string
160
161 // whole_static_libs: list of modules whose object files should be linked into this module
162 // in their entirety. For static library modules, all of the .o files from the intermediate
163 // directory of the dependency will be linked into this modules .a file. For a shared library,
164 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
165 Whole_static_libs []string `android:"arch_variant"`
166
167 // static_libs: list of modules that should be statically linked into this module.
168 Static_libs []string `android:"arch_variant"`
169
170 // shared_libs: list of modules that should be dynamically linked into this module.
171 Shared_libs []string `android:"arch_variant"`
172
173 // allow_undefined_symbols: allow the module to contain undefined symbols. By default,
174 // modules cannot contain undefined symbols that are not satisified by their immediate
175 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
176 // This flag should only be necessary for compiling low-level libraries like libc.
177 Allow_undefined_symbols bool
178
179 // nocrt: don't link in crt_begin and crt_end. This flag should only be necessary for
180 // compiling crt or libc.
181 Nocrt bool `android:"arch_variant"`
182
183 // no_default_compiler_flags: don't insert default compiler flags into asflags, cflags,
184 // cppflags, conlyflags, ldflags, or include_dirs
185 No_default_compiler_flags bool
186
187 // clang: compile module with clang instead of gcc
188 Clang bool `android:"arch_variant"`
189
190 // rtti: pass -frtti instead of -fno-rtti
191 Rtti bool
192
193 // host_ldlibs: -l arguments to pass to linker for host-provided shared libraries
194 Host_ldlibs []string `android:"arch_variant"`
195
196 // stl: select the STL library to use. Possible values are "libc++", "libc++_static",
197 // "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
198 // default
199 Stl string
200
201 // Set for combined shared/static libraries to prevent compiling object files a second time
202 SkipCompileObjs bool `blueprint:"mutated"`
203}
204
205type unusedProperties struct {
206 Asan bool
207 Native_coverage bool
208 Strip string
209 Tags []string
210 Required []string
211}
212
213// Building C/C++ code is handled by objects that satisfy this interface via composition
214type ccModuleType interface {
215 common.AndroidModule
216
217 // Return the cflags that are specific to this _type_ of module
218 moduleTypeCflags(common.AndroidModuleContext, toolchain) []string
219
220 // Return the ldflags that are specific to this _type_ of module
221 moduleTypeLdflags(common.AndroidModuleContext, toolchain) []string
222
223 // Create a ccDeps struct that collects the module dependency info. Can also
224 // modify ccFlags in order to add dependency include directories, etc.
225 collectDeps(common.AndroidModuleContext, ccFlags) (ccDeps, ccFlags)
226
227 // Compile objects into final module
228 compileModule(common.AndroidModuleContext, ccFlags, ccDeps, []string)
229
Dan Albertc403f7c2015-03-18 14:01:18 -0700230 // Install the built module.
231 installModule(common.AndroidModuleContext, ccFlags)
232
Colin Cross3f40fa42015-01-30 17:27:36 -0800233 // Return the output file (.o, .a or .so) for use by other modules
234 outputFile() string
235}
236
Colin Crossc472d572015-03-17 15:06:21 -0700237type ccDeps struct {
238 staticLibs, sharedLibs, lateStaticLibs, wholeStaticLibs, objFiles, includeDirs []string
239
240 crtBegin, crtEnd string
241}
242
243type ccFlags struct {
244 globalFlags []string
245 asFlags []string
246 cFlags []string
247 conlyFlags []string
248 cppFlags []string
249 ldFlags []string
250 ldLibs []string
251 includeDirs []string
252 nocrt bool
253 toolchain toolchain
254 clang bool
255
256 extraStaticLibs []string
257 extraSharedLibs []string
258}
259
260// ccBase contains the properties and members used by all C/C++ module types, and implements
261// the blueprint.Module interface. It expects to be embedded into an outer specialization struct,
262// and uses a ccModuleType interface to that struct to create the build steps.
263type ccBase struct {
264 common.AndroidModuleBase
265 module ccModuleType
266
267 properties ccProperties
268 unused unusedProperties
269
270 installPath string
271}
272
273func newCCBase(base *ccBase, module ccModuleType, hod common.HostOrDeviceSupported,
274 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
275
276 base.module = module
277
278 props = append(props, &base.properties, &base.unused)
279
280 return common.InitAndroidModule(module, hod, multilib, props...)
281}
282
Colin Cross3f40fa42015-01-30 17:27:36 -0800283func (c *ccBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
284 toolchain := c.findToolchain(ctx)
285 if ctx.Failed() {
286 return
287 }
288
289 flags := c.flags(ctx, toolchain)
290 if ctx.Failed() {
291 return
292 }
293
294 flags = c.addStlFlags(ctx, flags)
295 if ctx.Failed() {
296 return
297 }
298
299 deps, flags := c.ccModuleType().collectDeps(ctx, flags)
300 if ctx.Failed() {
301 return
302 }
303
304 objFiles := c.compileObjs(ctx, flags, deps)
305 if ctx.Failed() {
306 return
307 }
308
309 c.ccModuleType().compileModule(ctx, flags, deps, objFiles)
310 if ctx.Failed() {
311 return
312 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700313
314 c.ccModuleType().installModule(ctx, flags)
315 if ctx.Failed() {
316 return
317 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800318}
319
320func (c *ccBase) ccModuleType() ccModuleType {
321 return c.module
322}
323
324var _ common.AndroidDynamicDepender = (*ccBase)(nil)
325
326func (c *ccBase) findToolchain(ctx common.AndroidModuleContext) toolchain {
327 arch := ctx.Arch()
328 factory := toolchainFactories[arch.HostOrDevice][arch.ArchType]
329 if factory == nil {
330 panic(fmt.Sprintf("Toolchain not found for %s arch %q",
331 arch.HostOrDevice.String(), arch.String()))
332 }
333 return factory(arch.ArchVariant, arch.CpuVariant)
334}
335
Colin Cross3f40fa42015-01-30 17:27:36 -0800336func (c *ccBase) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
337 return nil
338}
339
340func (c *ccBase) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
341 return nil
342}
343
344func (c *ccBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
345 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Whole_static_libs...)
346 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Static_libs...)
347 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.properties.Shared_libs...)
348
349 return nil
350}
351
352// Create a ccFlags struct that collects the compile flags from global values,
353// per-target values, module type values, and per-module Blueprints properties
354func (c *ccBase) flags(ctx common.AndroidModuleContext, toolchain toolchain) ccFlags {
355
356 arch := ctx.Arch()
357
358 flags := ccFlags{
359 cFlags: c.properties.Cflags,
360 cppFlags: c.properties.Cppflags,
361 conlyFlags: c.properties.Conlyflags,
362 ldFlags: c.properties.Ldflags,
363 asFlags: c.properties.Asflags,
364 nocrt: c.properties.Nocrt,
365 toolchain: toolchain,
366 clang: c.properties.Clang,
367 }
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700368 instructionSet := c.properties.Instruction_set
369 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
370 if err != nil {
371 ctx.ModuleErrorf("%s", err)
372 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800373
374 if arch.HostOrDevice.Host() {
375 // TODO: allow per-module clang disable for host
376 flags.clang = true
377 }
378
379 if flags.clang {
380 flags.cFlags = clangFilterUnknownCflags(flags.cFlags)
381 flags.cFlags = append(flags.cFlags, c.properties.Clang_cflags...)
382 flags.asFlags = append(flags.asFlags, c.properties.Clang_asflags...)
383 flags.cppFlags = clangFilterUnknownCflags(flags.cppFlags)
384 flags.conlyFlags = clangFilterUnknownCflags(flags.conlyFlags)
385 flags.ldFlags = clangFilterUnknownCflags(flags.ldFlags)
386
Colin Crossbdd7b1c2015-03-16 16:21:20 -0700387 flags.cFlags = append(flags.cFlags, "${clangExtraCflags}")
388 flags.conlyFlags = append(flags.conlyFlags, "${clangExtraConlyflags}")
389 if arch.HostOrDevice.Device() {
390 flags.cFlags = append(flags.cFlags, "${clangExtraTargetCflags}")
391 }
392
Colin Cross3f40fa42015-01-30 17:27:36 -0800393 target := "-target " + toolchain.ClangTriple()
394 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
395
396 flags.cFlags = append(flags.cFlags, target, gccPrefix)
397 flags.asFlags = append(flags.asFlags, target, gccPrefix)
398 flags.ldFlags = append(flags.ldFlags, target, gccPrefix)
399
400 if arch.HostOrDevice.Host() {
401 gccToolchain := "--gcc-toolchain=" + toolchain.GccRoot()
402 sysroot := "--sysroot=" + filepath.Join(toolchain.GccRoot(), "sysroot")
403
404 // TODO: also need more -B, -L flags to make host builds hermetic
405 flags.cFlags = append(flags.cFlags, gccToolchain, sysroot)
406 flags.asFlags = append(flags.asFlags, gccToolchain, sysroot)
407 flags.ldFlags = append(flags.ldFlags, gccToolchain, sysroot)
408 }
409 }
410
411 flags.includeDirs = pathtools.PrefixPaths(c.properties.Include_dirs, ctx.Config().(Config).SrcDir())
412 localIncludeDirs := pathtools.PrefixPaths(c.properties.Local_include_dirs, common.ModuleSrcDir(ctx))
413 flags.includeDirs = append(flags.includeDirs, localIncludeDirs...)
414
415 if !c.properties.No_default_compiler_flags {
416 flags.includeDirs = append(flags.includeDirs, []string{
417 common.ModuleSrcDir(ctx),
418 common.ModuleOutDir(ctx),
419 common.ModuleGenDir(ctx),
420 }...)
421
422 if arch.HostOrDevice.Device() && !c.properties.Allow_undefined_symbols {
423 flags.ldFlags = append(flags.ldFlags, "-Wl,--no-undefined")
424 }
425
426 if flags.clang {
Tim Kilbournf2948142015-03-11 12:03:03 -0700427 flags.cppFlags = append(flags.cppFlags, "${commonClangGlobalCppflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800428 flags.globalFlags = []string{
429 "${commonGlobalIncludes}",
430 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700431 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800432 toolchain.ClangCflags(),
433 "${commonClangGlobalCflags}",
434 fmt.Sprintf("${%sClangGlobalCflags}", arch.HostOrDevice),
435 }
436 } else {
Tim Kilbournf2948142015-03-11 12:03:03 -0700437 flags.cppFlags = append(flags.cppFlags, "${commonGlobalCppflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 flags.globalFlags = []string{
439 "${commonGlobalIncludes}",
440 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700441 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800442 toolchain.Cflags(),
443 "${commonGlobalCflags}",
444 fmt.Sprintf("${%sGlobalCflags}", arch.HostOrDevice),
445 }
446 }
447
448 if arch.HostOrDevice.Host() {
449 flags.ldFlags = append(flags.ldFlags, c.properties.Host_ldlibs...)
450 }
451
452 if arch.HostOrDevice.Device() {
453 if c.properties.Rtti {
454 flags.cppFlags = append(flags.cppFlags, "-frtti")
455 } else {
456 flags.cppFlags = append(flags.cppFlags, "-fno-rtti")
457 }
458 }
459
460 flags.asFlags = append(flags.asFlags, "-D__ASSEMBLY__")
461
462 if flags.clang {
463 flags.cppFlags = append(flags.cppFlags, toolchain.ClangCppflags())
464 flags.ldFlags = append(flags.ldFlags, toolchain.ClangLdflags())
465 } else {
466 flags.cppFlags = append(flags.cppFlags, toolchain.Cppflags())
467 flags.ldFlags = append(flags.ldFlags, toolchain.Ldflags())
468 }
469 }
470
471 flags.cFlags = append(flags.cFlags, c.ccModuleType().moduleTypeCflags(ctx, toolchain)...)
472 flags.ldFlags = append(flags.ldFlags, c.ccModuleType().moduleTypeLdflags(ctx, toolchain)...)
473
474 // Optimization to reduce size of build.ninja
475 // Replace the long list of flags for each file with a module-local variable
476 ctx.Variable(pctx, "cflags", strings.Join(flags.cFlags, " "))
477 ctx.Variable(pctx, "cppflags", strings.Join(flags.cppFlags, " "))
478 ctx.Variable(pctx, "asflags", strings.Join(flags.asFlags, " "))
479 flags.cFlags = []string{"$cflags"}
480 flags.cppFlags = []string{"$cppflags"}
481 flags.asFlags = []string{"$asflags"}
482
483 return flags
484}
485
486// Modify ccFlags structs with STL library info
487func (c *ccBase) addStlFlags(ctx common.AndroidModuleContext, flags ccFlags) ccFlags {
488 if !c.properties.No_default_compiler_flags {
489 arch := ctx.Arch()
490 stl := "libc++" // TODO: mingw needs libstdc++
491 if c.properties.Stl != "" {
492 stl = c.properties.Stl
493 }
494
495 stlStatic := false
496 if strings.HasSuffix(stl, "_static") {
497 stlStatic = true
498 }
499
500 switch stl {
501 case "libc++", "libc++_static":
502 flags.cFlags = append(flags.cFlags, "-D_USING_LIBCXX")
503 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/external/libcxx/include")
504 if arch.HostOrDevice.Host() {
505 flags.cppFlags = append(flags.cppFlags, "-nostdinc++")
506 flags.ldFlags = append(flags.ldFlags, "-nodefaultlibs")
507 flags.ldLibs = append(flags.ldLibs, "-lc", "-lm", "-lpthread")
508 }
509 if stlStatic {
510 flags.extraStaticLibs = append(flags.extraStaticLibs, "libc++_static")
511 } else {
512 flags.extraSharedLibs = append(flags.extraSharedLibs, "libc++")
513 }
514 case "stlport", "stlport_static":
515 if arch.HostOrDevice.Device() {
516 flags.includeDirs = append(flags.includeDirs,
517 "${SrcDir}/external/stlport/stlport",
518 "${SrcDir}/bionic/libstdc++/include",
519 "${SrcDir}/bionic")
520 if stlStatic {
521 flags.extraStaticLibs = append(flags.extraStaticLibs, "libstdc++", "libstlport_static")
522 } else {
523 flags.extraSharedLibs = append(flags.extraSharedLibs, "libstdc++", "libstlport")
524 }
525 }
526 case "ndk":
527 panic("TODO")
528 case "libstdc++":
529 // Using bionic's basic libstdc++. Not actually an STL. Only around until the
530 // tree is in good enough shape to not need it.
531 // Host builds will use GNU libstdc++.
532 if arch.HostOrDevice.Device() {
533 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/bionic/libstdc++/include")
534 flags.extraSharedLibs = append(flags.extraSharedLibs, "libstdc++")
535 }
536 case "none":
537 if arch.HostOrDevice.Host() {
538 flags.cppFlags = append(flags.cppFlags, "-nostdinc++")
539 flags.ldFlags = append(flags.ldFlags, "-nodefaultlibs")
540 flags.ldLibs = append(flags.ldLibs, "-lc", "-lm")
541 }
542 default:
543 ctx.ModuleErrorf("stl: %q is not a supported STL", stl)
544 }
545
546 }
547 return flags
548}
549
550// Compile a list of source files into objects a specified subdirectory
551func (c *ccBase) customCompileObjs(ctx common.AndroidModuleContext, flags ccFlags,
552 deps ccDeps, subdir string, srcFiles []string) []string {
553
554 srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
555 srcFiles = common.ExpandGlobs(ctx, srcFiles)
556
557 return TransformSourceToObj(ctx, subdir, srcFiles, ccFlagsToBuilderFlags(flags))
558}
559
560// Compile files listed in c.properties.Srcs into objects
561func (c *ccBase) compileObjs(ctx common.AndroidModuleContext, flags ccFlags,
562 deps ccDeps) []string {
563
564 if c.properties.SkipCompileObjs {
565 return nil
566 }
567
568 return c.customCompileObjs(ctx, flags, deps, "", c.properties.Srcs)
569}
570
571func (c *ccBase) outputFile() string {
572 return ""
573}
574
575func (c *ccBase) collectDepsFromList(ctx common.AndroidModuleContext,
576 names []string) (modules []common.AndroidModule,
577 outputFiles []string, exportedIncludeDirs []string) {
578
579 for _, n := range names {
580 found := false
581 ctx.VisitDirectDeps(func(m blueprint.Module) {
582 otherName := ctx.OtherModuleName(m)
583 if otherName != n {
584 return
585 }
586
587 if a, ok := m.(ccModuleType); ok {
588 if a.Disabled() {
589 // If a cc_library host+device module depends on a library that exists as both
590 // cc_library_shared and cc_library_host_shared, it will end up with two
591 // dependencies with the same name, one of which is marked disabled for each
592 // of host and device. Ignore the disabled one.
593 return
594 }
595 if a.HostOrDevice() != ctx.Arch().HostOrDevice {
596 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
597 otherName)
598 return
599 }
600
601 if outputFile := a.outputFile(); outputFile != "" {
602 if found {
603 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
604 return
605 }
606 outputFiles = append(outputFiles, outputFile)
607 modules = append(modules, a)
608 if i, ok := a.(ccExportedIncludeDirsProducer); ok {
609 exportedIncludeDirs = append(exportedIncludeDirs, i.exportedIncludeDirs()...)
610 }
611 found = true
612 } else {
613 ctx.ModuleErrorf("module %q missing output file", otherName)
614 return
615 }
616 } else {
617 ctx.ModuleErrorf("module %q not an android module", otherName)
618 return
619 }
620 })
621 if !found {
622 ctx.ModuleErrorf("unsatisified dependency on %q", n)
623 }
624 }
625
626 return modules, outputFiles, exportedIncludeDirs
627}
628
629func (c *ccBase) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
630 var deps ccDeps
631 var newIncludeDirs []string
632
633 wholeStaticLibNames := c.properties.Whole_static_libs
634 _, deps.wholeStaticLibs, newIncludeDirs = c.collectDepsFromList(ctx, wholeStaticLibNames)
635
636 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
637
638 staticLibNames := c.properties.Static_libs
639 staticLibNames = append(staticLibNames, flags.extraStaticLibs...)
640 _, deps.staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
641 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
642
643 return deps, flags
644}
645
646// ccDynamic contains the properties and members used by shared libraries and dynamic executables
647type ccDynamic struct {
648 ccBase
649}
650
Colin Crossc472d572015-03-17 15:06:21 -0700651func newCCDynamic(dynamic *ccDynamic, module ccModuleType, hod common.HostOrDeviceSupported,
652 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
653
654 dynamic.properties.System_shared_libs = []string{defaultSystemSharedLibraries}
655
656 return newCCBase(&dynamic.ccBase, module, hod, multilib, props...)
657}
658
Colin Cross3f40fa42015-01-30 17:27:36 -0800659const defaultSystemSharedLibraries = "__default__"
660
661func (c *ccDynamic) systemSharedLibs() []string {
662
663 if len(c.properties.System_shared_libs) == 1 &&
664 c.properties.System_shared_libs[0] == defaultSystemSharedLibraries {
665
666 if c.HostOrDevice().Host() {
667 return []string{}
668 } else {
669 return []string{"libc", "libm"}
670 }
671 }
672 return c.properties.System_shared_libs
673}
674
675var (
676 stlSharedLibs = []string{"libc++", "libstlport", "libstdc++"}
677 stlSharedHostLibs = []string{"libc++"}
678 stlStaticLibs = []string{"libc++_static", "libstlport_static", "libstdc++"}
679 stlStaticHostLibs = []string{"libc++_static"}
680)
681
682func (c *ccDynamic) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
683 deps := c.ccBase.AndroidDynamicDependencies(ctx)
684
685 if c.HostOrDevice().Device() {
686 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.systemSharedLibs()...)
687 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}},
688 "libcompiler_rt-extras",
Colin Cross77b00fa2015-03-16 16:15:49 -0700689 "libgcov",
Colin Cross3f40fa42015-01-30 17:27:36 -0800690 "libatomic",
691 "libgcc")
692
693 if c.properties.Stl != "none" {
694 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedLibs...)
695 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticLibs...)
696 }
697 } else {
698 if c.properties.Stl != "none" {
699 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedHostLibs...)
700 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticHostLibs...)
701 }
702 }
703
704 return deps
705}
706
Colin Cross3f40fa42015-01-30 17:27:36 -0800707func (c *ccDynamic) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
708 var newIncludeDirs []string
709
710 deps, flags := c.ccBase.collectDeps(ctx, flags)
711
712 systemSharedLibs := c.systemSharedLibs()
713 sharedLibNames := make([]string, 0, len(c.properties.Shared_libs)+len(systemSharedLibs)+
714 len(flags.extraSharedLibs))
715 sharedLibNames = append(sharedLibNames, c.properties.Shared_libs...)
716 sharedLibNames = append(sharedLibNames, systemSharedLibs...)
717 sharedLibNames = append(sharedLibNames, flags.extraSharedLibs...)
718 _, deps.sharedLibs, newIncludeDirs = c.collectDepsFromList(ctx, sharedLibNames)
719 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
720
721 if ctx.Arch().HostOrDevice.Device() {
722 var staticLibs []string
Colin Cross77b00fa2015-03-16 16:15:49 -0700723 staticLibNames := []string{"libcompiler_rt-extras"}
Colin Cross3f40fa42015-01-30 17:27:36 -0800724 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
725 deps.staticLibs = append(deps.staticLibs, staticLibs...)
726 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
Colin Cross77b00fa2015-03-16 16:15:49 -0700727
728 // libgcc and libatomic have to be last on the command line
729 staticLibNames = []string{"libgcov", "libatomic", "libgcc"}
730 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
731 deps.lateStaticLibs = append(deps.lateStaticLibs, staticLibs...)
732 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800733 }
734
735 ctx.VisitDirectDeps(func(m blueprint.Module) {
736 if obj, ok := m.(*ccObject); ok {
737 otherName := ctx.OtherModuleName(m)
738 if strings.HasPrefix(otherName, "crtbegin") {
739 if !c.properties.Nocrt {
740 deps.crtBegin = obj.outputFile()
741 }
742 } else if strings.HasPrefix(otherName, "crtend") {
743 if !c.properties.Nocrt {
744 deps.crtEnd = obj.outputFile()
745 }
746 } else {
747 ctx.ModuleErrorf("object module type only support for crtbegin and crtend, found %q",
748 ctx.OtherModuleName(m))
749 }
750 }
751 })
752
753 flags.includeDirs = append(flags.includeDirs, deps.includeDirs...)
754
755 return deps, flags
756}
757
758type ccExportedIncludeDirsProducer interface {
759 exportedIncludeDirs() []string
760}
761
762//
763// Combined static+shared libraries
764//
765
766type ccLibrary struct {
767 ccDynamic
768
769 primary *ccLibrary
770 primaryObjFiles []string
771 objFiles []string
772 exportIncludeDirs []string
773 out string
774
775 libraryProperties struct {
776 BuildStatic bool `blueprint:"mutated"`
777 BuildShared bool `blueprint:"mutated"`
778 IsShared bool `blueprint:"mutated"`
779 IsStatic bool `blueprint:"mutated"`
780
781 Static struct {
782 Srcs []string `android:"arch_variant"`
783 Cflags []string `android:"arch_variant"`
784 } `android:"arch_variant"`
785 Shared struct {
786 Srcs []string `android:"arch_variant"`
787 Cflags []string `android:"arch_variant"`
788 } `android:"arch_variant"`
789 }
790}
791
Colin Crossc472d572015-03-17 15:06:21 -0700792func newCCLibrary(library *ccLibrary, hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
793 return newCCDynamic(&library.ccDynamic, library, hod, common.MultilibBoth,
794 &library.libraryProperties)
795}
796
Colin Cross3f40fa42015-01-30 17:27:36 -0800797func NewCCLibrary() (blueprint.Module, []interface{}) {
798 module := &ccLibrary{}
Colin Crossc472d572015-03-17 15:06:21 -0700799
Colin Cross3f40fa42015-01-30 17:27:36 -0800800 module.libraryProperties.BuildShared = true
801 module.libraryProperties.BuildStatic = true
802
Colin Crossc472d572015-03-17 15:06:21 -0700803 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800804}
805
806func (c *ccLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
807 if c.libraryProperties.IsShared {
808 deps := c.ccDynamic.AndroidDynamicDependencies(ctx)
809 if c.HostOrDevice().Device() {
810 deps = append(deps, "crtbegin_so", "crtend_so")
811 }
812 return deps
813 } else {
814 return c.ccBase.AndroidDynamicDependencies(ctx)
815 }
816}
817
818func (c *ccLibrary) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
819 if c.libraryProperties.IsStatic {
820 deps, flags := c.ccBase.collectDeps(ctx, flags)
821 wholeStaticLibNames := c.properties.Whole_static_libs
822 wholeStaticLibs, _, _ := c.collectDepsFromList(ctx, wholeStaticLibNames)
823
824 for _, m := range wholeStaticLibs {
825 if staticLib, ok := m.(*ccLibrary); ok && staticLib.libraryProperties.IsStatic {
826 deps.objFiles = append(deps.objFiles, staticLib.allObjFiles()...)
827 } else {
828 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
829 }
830 }
831
832 return deps, flags
833 } else if c.libraryProperties.IsShared {
834 return c.ccDynamic.collectDeps(ctx, flags)
835 } else {
836 panic("Not shared or static")
837 }
838}
839
840func (c *ccLibrary) outputFile() string {
841 return c.out
842}
843
844func (c *ccLibrary) allObjFiles() []string {
845 return c.objFiles
846}
847
848func (c *ccLibrary) exportedIncludeDirs() []string {
849 return c.exportIncludeDirs
850}
851
852func (c *ccLibrary) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
853 return []string{"-fPIC"}
854}
855
856func (c *ccLibrary) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
857 if c.libraryProperties.IsShared {
858 libName := ctx.ModuleName()
859 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
860 sharedFlag := "-Wl,-shared"
861 if c.properties.Clang || ctx.Arch().HostOrDevice.Host() {
862 sharedFlag = "-shared"
863 }
864 if ctx.Arch().HostOrDevice.Device() {
865 return []string{
866 "-nostdlib",
867 "-Wl,--gc-sections",
868 sharedFlag,
Colin Cross6072ad42015-03-16 16:22:04 -0700869 "-Wl,-soname," + libName + sharedLibraryExtension,
Colin Cross3f40fa42015-01-30 17:27:36 -0800870 }
871 } else {
872 return []string{
873 "-Wl,--gc-sections",
874 sharedFlag,
Colin Cross6072ad42015-03-16 16:22:04 -0700875 "-Wl,-soname," + libName + sharedLibraryExtension,
Colin Cross3f40fa42015-01-30 17:27:36 -0800876 }
877 }
878 } else {
879 return nil
880 }
881}
882
883func (c *ccLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
884 flags ccFlags, deps ccDeps, objFiles []string) {
885
886 staticFlags := flags
887 staticFlags.cFlags = append(staticFlags.cFlags, c.libraryProperties.Static.Cflags...)
888 objFilesStatic := c.customCompileObjs(ctx, staticFlags, deps, common.DeviceStaticLibrary,
889 c.libraryProperties.Static.Srcs)
890
891 objFiles = append(objFiles, objFilesStatic...)
892
893 var includeDirs []string
894
895 wholeStaticLibNames := c.properties.Whole_static_libs
896 wholeStaticLibs, _, newIncludeDirs := c.collectDepsFromList(ctx, wholeStaticLibNames)
897 includeDirs = append(includeDirs, newIncludeDirs...)
898
899 for _, m := range wholeStaticLibs {
900 if staticLib, ok := m.(*ccLibrary); ok && staticLib.libraryProperties.IsStatic {
901 objFiles = append(objFiles, staticLib.allObjFiles()...)
902 } else {
903 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
904 }
905 }
906
907 staticLibNames := c.properties.Static_libs
908 _, _, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
909 includeDirs = append(includeDirs, newIncludeDirs...)
910
911 ctx.VisitDirectDeps(func(m blueprint.Module) {
912 if obj, ok := m.(*ccObject); ok {
913 otherName := ctx.OtherModuleName(m)
914 if !strings.HasPrefix(otherName, "crtbegin") && !strings.HasPrefix(otherName, "crtend") {
915 objFiles = append(objFiles, obj.outputFile())
916 }
917 }
918 })
919
920 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
921
922 TransformObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
923
924 c.objFiles = objFiles
925 c.out = outputFile
926 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
927 common.ModuleSrcDir(ctx))
928
929 ctx.CheckbuildFile(outputFile)
930}
931
932func (c *ccLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
933 flags ccFlags, deps ccDeps, objFiles []string) {
934
935 sharedFlags := flags
936 sharedFlags.cFlags = append(sharedFlags.cFlags, c.libraryProperties.Shared.Cflags...)
937 objFilesShared := c.customCompileObjs(ctx, sharedFlags, deps, common.DeviceSharedLibrary,
938 c.libraryProperties.Shared.Srcs)
939
940 objFiles = append(objFiles, objFilesShared...)
941
942 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
943
Colin Cross77b00fa2015-03-16 16:15:49 -0700944 TransformObjToDynamicBinary(ctx, objFiles, deps.sharedLibs, deps.staticLibs,
945 deps.lateStaticLibs, deps.wholeStaticLibs, deps.crtBegin, deps.crtEnd,
946 ccFlagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -0800947
948 c.out = outputFile
949 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
950 common.ModuleSrcDir(ctx))
Colin Cross3f40fa42015-01-30 17:27:36 -0800951}
952
953func (c *ccLibrary) compileModule(ctx common.AndroidModuleContext,
954 flags ccFlags, deps ccDeps, objFiles []string) {
955
956 // Reuse the object files from the matching static library if it exists
957 if c.primary == c {
958 c.primaryObjFiles = objFiles
959 } else {
960 objFiles = append([]string(nil), c.primary.primaryObjFiles...)
961 }
962
963 if c.libraryProperties.IsStatic {
964 c.compileStaticLibrary(ctx, flags, deps, objFiles)
965 } else {
966 c.compileSharedLibrary(ctx, flags, deps, objFiles)
967 }
968}
969
Dan Albertc403f7c2015-03-18 14:01:18 -0700970func (c *ccLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
971 // Static libraries do not get installed.
972}
973
974func (c *ccLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
975 installDir := "lib"
976 if flags.toolchain.Is64Bit() {
977 installDir = "lib64"
978 }
979
980 ctx.InstallFile(installDir, c.out)
981}
982
983func (c *ccLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
984 if c.libraryProperties.IsStatic {
985 c.installStaticLibrary(ctx, flags)
986 } else {
987 c.installSharedLibrary(ctx, flags)
988 }
989}
990
Colin Cross3f40fa42015-01-30 17:27:36 -0800991//
992// Objects (for crt*.o)
993//
994
995type ccObject struct {
996 ccBase
997 out string
998}
999
1000func NewCCObject() (blueprint.Module, []interface{}) {
1001 module := &ccObject{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001002
Colin Crossc472d572015-03-17 15:06:21 -07001003 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001004}
1005
1006func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1007 // object files can't have any dynamic dependencies
1008 return nil
1009}
1010
1011func (c *ccObject) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1012 deps, flags := c.ccBase.collectDeps(ctx, flags)
1013 ctx.VisitDirectDeps(func(m blueprint.Module) {
1014 if obj, ok := m.(*ccObject); ok {
1015 deps.objFiles = append(deps.objFiles, obj.outputFile())
1016 } else {
1017 ctx.ModuleErrorf("Unknown module type for dependency %q", ctx.OtherModuleName(m))
1018 }
1019 })
1020
1021 return deps, flags
1022}
1023
1024func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
1025 flags ccFlags, deps ccDeps, objFiles []string) {
1026
1027 objFiles = append(objFiles, deps.objFiles...)
1028
1029 var outputFile string
1030 if len(objFiles) == 1 {
1031 outputFile = objFiles[0]
1032 } else {
1033 outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+".o")
1034 TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1035 }
1036
1037 c.out = outputFile
1038
1039 ctx.CheckbuildFile(outputFile)
1040}
1041
Dan Albertc403f7c2015-03-18 14:01:18 -07001042func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1043 // Object files do not get installed.
1044}
1045
Colin Cross3f40fa42015-01-30 17:27:36 -08001046func (c *ccObject) outputFile() string {
1047 return c.out
1048}
1049
1050//
1051// Executables
1052//
1053
1054type ccBinary struct {
1055 ccDynamic
Dan Albertc403f7c2015-03-18 14:01:18 -07001056 out string
Colin Cross3f40fa42015-01-30 17:27:36 -08001057 binaryProperties binaryProperties
1058}
1059
1060type binaryProperties struct {
1061 // static_executable: compile executable with -static
1062 Static_executable bool
1063
1064 // stem: set the name of the output
1065 Stem string `android:"arch_variant"`
1066
1067 // prefix_symbols: if set, add an extra objcopy --prefix-symbols= step
1068 Prefix_symbols string
1069}
1070
1071func (c *ccBinary) getStem(ctx common.AndroidModuleContext) string {
1072 if c.binaryProperties.Stem != "" {
1073 return c.binaryProperties.Stem
1074 }
1075 return ctx.ModuleName()
1076}
1077
1078func (c *ccBinary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1079 deps := c.ccDynamic.AndroidDynamicDependencies(ctx)
1080 if c.HostOrDevice().Device() {
1081 if c.binaryProperties.Static_executable {
1082 deps = append(deps, "crtbegin_static", "crtend_android")
1083 } else {
1084 deps = append(deps, "crtbegin_dynamic", "crtend_android")
1085 }
1086 }
1087 return deps
1088}
1089
1090func NewCCBinary() (blueprint.Module, []interface{}) {
1091 module := &ccBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001092
Colin Crossc472d572015-03-17 15:06:21 -07001093 return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported, common.MultilibFirst,
1094 &module.binaryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001095}
1096
1097func (c *ccBinary) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
1098 return []string{"-fpie"}
1099}
1100
1101func (c *ccBinary) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
1102 if ctx.Arch().HostOrDevice.Device() {
1103 linker := "/system/bin/linker"
1104 if toolchain.Is64Bit() {
1105 linker = "/system/bin/linker64"
1106 }
1107
1108 return []string{
1109 "-nostdlib",
1110 "-Bdynamic",
1111 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1112 "-Wl,--gc-sections",
1113 "-Wl,-z,nocopyreloc",
1114 }
1115 }
1116
1117 return nil
1118}
1119
1120func (c *ccBinary) compileModule(ctx common.AndroidModuleContext,
1121 flags ccFlags, deps ccDeps, objFiles []string) {
1122
1123 if !c.binaryProperties.Static_executable && inList("libc", c.properties.Static_libs) {
1124 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1125 "from static libs or set static_executable: true")
1126 }
1127
1128 outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
Dan Albertc403f7c2015-03-18 14:01:18 -07001129 c.out = outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001130
Colin Cross77b00fa2015-03-16 16:15:49 -07001131 TransformObjToDynamicBinary(ctx, objFiles, deps.sharedLibs, deps.staticLibs,
1132 deps.lateStaticLibs, deps.wholeStaticLibs, deps.crtBegin, deps.crtEnd,
1133 ccFlagsToBuilderFlags(flags), outputFile)
Dan Albertc403f7c2015-03-18 14:01:18 -07001134}
Colin Cross3f40fa42015-01-30 17:27:36 -08001135
Dan Albertc403f7c2015-03-18 14:01:18 -07001136func (c *ccBinary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1137 ctx.InstallFile("bin", c.out)
1138}
1139
1140type ccTest struct {
1141 ccBinary
1142}
1143
1144var (
1145 gtestLibs = []string{"libgtest", "libgtest_main"}
1146)
1147
1148func (c *ccTest) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1149 deps, flags := c.ccBinary.collectDeps(ctx, flags)
1150
1151 flags.cFlags = append(flags.cFlags, "-DGTEST_HAS_STD_STRING")
1152 if c.HostOrDevice().Host() {
1153 flags.cFlags = append(flags.cFlags, "-O0", "-g")
1154 flags.ldLibs = append(flags.ldLibs, "-lpthread")
1155 }
1156
1157 // TODO(danalbert): Make gtest export its dependencies.
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001158 flags.includeDirs = append(flags.includeDirs,
1159 filepath.Join(ctx.Config().(Config).SrcDir(), "external/gtest/include"))
Dan Albertc403f7c2015-03-18 14:01:18 -07001160
1161 _, staticLibs, _ := c.collectDepsFromList(ctx, gtestLibs)
1162 deps.staticLibs = append(deps.staticLibs, staticLibs...)
1163
1164 return deps, flags
1165}
1166
1167func (c *ccTest) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1168 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, gtestLibs...)
1169 deps := c.ccBinary.AndroidDynamicDependencies(ctx)
1170 return append(deps, gtestLibs...)
1171}
1172
1173func (c *ccTest) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1174 if c.HostOrDevice().Device() {
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001175 ctx.InstallFile("../data/nativetest/"+ctx.ModuleName(), c.out)
Dan Albertc403f7c2015-03-18 14:01:18 -07001176 } else {
1177 c.ccBinary.installModule(ctx, flags)
1178 }
1179}
1180
1181func NewCCTest() (blueprint.Module, []interface{}) {
1182 module := &ccTest{}
1183 return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported,
1184 common.MultilibFirst, &module.binaryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001185}
1186
1187//
1188// Static library
1189//
1190
1191func NewCCLibraryStatic() (blueprint.Module, []interface{}) {
1192 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001193 module.libraryProperties.BuildStatic = true
1194
Colin Crossc472d572015-03-17 15:06:21 -07001195 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001196}
1197
1198//
1199// Shared libraries
1200//
1201
1202func NewCCLibraryShared() (blueprint.Module, []interface{}) {
1203 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001204 module.libraryProperties.BuildShared = true
1205
Colin Crossc472d572015-03-17 15:06:21 -07001206 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001207}
1208
1209//
1210// Host static library
1211//
1212
1213func NewCCLibraryHostStatic() (blueprint.Module, []interface{}) {
1214 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001215 module.libraryProperties.BuildStatic = true
1216
Colin Crossc472d572015-03-17 15:06:21 -07001217 return newCCLibrary(module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001218}
1219
1220//
1221// Host Shared libraries
1222//
1223
1224func NewCCLibraryHostShared() (blueprint.Module, []interface{}) {
1225 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001226 module.libraryProperties.BuildShared = true
1227
Colin Crossc472d572015-03-17 15:06:21 -07001228 return newCCLibrary(module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001229}
1230
1231//
1232// Host Binaries
1233//
1234
1235func NewCCBinaryHost() (blueprint.Module, []interface{}) {
1236 module := &ccBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001237
Colin Crossc472d572015-03-17 15:06:21 -07001238 return newCCDynamic(&module.ccDynamic, module, common.HostSupported, common.MultilibFirst)
Colin Cross3f40fa42015-01-30 17:27:36 -08001239}
1240
1241//
1242// Device libraries shipped with gcc
1243//
1244
1245type toolchainLibrary struct {
1246 ccLibrary
1247}
1248
1249func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1250 // toolchain libraries can't have any dependencies
1251 return nil
1252}
1253
1254func (*toolchainLibrary) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1255 // toolchain libraries can't have any dependencies
1256 return ccDeps{}, flags
1257}
1258
1259func NewToolchainLibrary() (blueprint.Module, []interface{}) {
1260 module := &toolchainLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001261
Colin Crossc472d572015-03-17 15:06:21 -07001262 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001263}
1264
1265func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
1266 flags ccFlags, deps ccDeps, objFiles []string) {
1267
1268 libName := ctx.ModuleName() + staticLibraryExtension
1269 outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
1270
1271 CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
1272
1273 c.out = outputFile
1274
1275 ctx.CheckbuildFile(outputFile)
1276}
1277
Dan Albertc403f7c2015-03-18 14:01:18 -07001278func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1279 // Toolchain libraries do not get installed.
1280}
1281
Colin Cross3f40fa42015-01-30 17:27:36 -08001282func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
1283 if c, ok := mctx.Module().(*ccLibrary); ok {
1284 var modules []blueprint.Module
1285 if c.libraryProperties.BuildStatic && c.libraryProperties.BuildShared {
1286 modules = mctx.CreateLocalVariations("static", "shared")
1287 modules[0].(*ccLibrary).libraryProperties.IsStatic = true
1288 modules[1].(*ccLibrary).libraryProperties.IsShared = true
1289 } else if c.libraryProperties.BuildStatic {
1290 modules = mctx.CreateLocalVariations("static")
1291 modules[0].(*ccLibrary).libraryProperties.IsStatic = true
1292 } else if c.libraryProperties.BuildShared {
1293 modules = mctx.CreateLocalVariations("shared")
1294 modules[0].(*ccLibrary).libraryProperties.IsShared = true
1295 } else {
1296 panic("ccLibrary not static or shared")
1297 }
1298 primary := modules[0].(*ccLibrary)
1299 for _, m := range modules {
1300 m.(*ccLibrary).primary = primary
1301 if m != primary {
1302 m.(*ccLibrary).properties.SkipCompileObjs = true
1303 }
1304 }
1305 } else if _, ok := mctx.Module().(*toolchainLibrary); ok {
1306 mctx.CreateLocalVariations("static")
1307 }
1308}