blob: d27bdd0d3f8404108121ddc6c9b596033778adf9 [file] [log] [blame]
Colin Cross5049f022015-03-18 13:28:46 -07001// Copyright 2015 Google Inc. All rights reserved.
Colin Cross3f40fa42015-01-30 17:27:36 -08002//
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 "blueprint"
23 "blueprint/pathtools"
24 "fmt"
25 "path/filepath"
26 "strings"
27
28 "android/soong/common"
Colin Cross5049f022015-03-18 13:28:46 -070029 "android/soong/genrule"
Colin Cross3f40fa42015-01-30 17:27:36 -080030)
31
32type Config interface {
33 SrcDir() string
34 PrebuiltOS() string
35}
36
37var (
38 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", Config.PrebuiltOS)
39 SrcDir = pctx.VariableConfigMethod("SrcDir", Config.SrcDir)
40
41 LibcRoot = pctx.StaticVariable("LibcRoot", "${SrcDir}/bionic/libc")
42 LibmRoot = pctx.StaticVariable("LibmRoot", "${SrcDir}/bionic/libm")
43)
44
45// Flags used by lots of devices. Putting them in package static variables will save bytes in
46// build.ninja so they aren't repeated for every file
47var (
48 commonGlobalCflags = []string{
49 "-DANDROID",
50 "-fmessage-length=0",
51 "-W",
52 "-Wall",
53 "-Wno-unused",
54 "-Winit-self",
55 "-Wpointer-arith",
56
57 // COMMON_RELEASE_CFLAGS
58 "-DNDEBUG",
59 "-UDEBUG",
60 }
61
62 deviceGlobalCflags = []string{
63 // TARGET_ERROR_FLAGS
64 "-Werror=return-type",
65 "-Werror=non-virtual-dtor",
66 "-Werror=address",
67 "-Werror=sequence-point",
68 }
69
70 hostGlobalCflags = []string{}
71
72 commonGlobalCppflags = []string{
73 "-Wsign-promo",
74 "-std=gnu++11",
75 }
76)
77
78func init() {
79 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
80 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
81 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
82
83 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
84
85 pctx.StaticVariable("commonClangGlobalCflags",
86 strings.Join(clangFilterUnknownCflags(commonGlobalCflags), " "))
87 pctx.StaticVariable("deviceClangGlobalCflags",
88 strings.Join(clangFilterUnknownCflags(deviceGlobalCflags), " "))
89 pctx.StaticVariable("hostClangGlobalCflags",
90 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Tim Kilbournf2948142015-03-11 12:03:03 -070091 pctx.StaticVariable("commonClangGlobalCppflags",
92 strings.Join(clangFilterUnknownCflags(commonGlobalCppflags), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -080093
94 // Everything in this list is a crime against abstraction and dependency tracking.
95 // Do not add anything to this list.
96 pctx.StaticVariable("commonGlobalIncludes", strings.Join([]string{
97 "-isystem ${SrcDir}/system/core/include",
98 "-isystem ${SrcDir}/hardware/libhardware/include",
99 "-isystem ${SrcDir}/hardware/libhardware_legacy/include",
100 "-isystem ${SrcDir}/hardware/ril/include",
101 "-isystem ${SrcDir}/libnativehelper/include",
102 "-isystem ${SrcDir}/frameworks/native/include",
103 "-isystem ${SrcDir}/frameworks/native/opengl/include",
104 "-isystem ${SrcDir}/frameworks/av/include",
105 "-isystem ${SrcDir}/frameworks/base/include",
106 }, " "))
107
108 pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/${HostPrebuiltTag}/host/3.6/bin/")
109}
110
111// CcProperties describes properties used to compile all C or C++ modules
112type ccProperties struct {
113 // srcs: list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
114 Srcs []string `android:"arch_variant,arch_subtract"`
115
116 // cflags: list of module-specific flags that will be used for C and C++ compiles.
117 Cflags []string `android:"arch_variant"`
118
119 // cppflags: list of module-specific flags that will be used for C++ compiles
120 Cppflags []string `android:"arch_variant"`
121
122 // conlyflags: list of module-specific flags that will be used for C compiles
123 Conlyflags []string `android:"arch_variant"`
124
125 // asflags: list of module-specific flags that will be used for .S compiles
126 Asflags []string `android:"arch_variant"`
127
128 // ldflags: list of module-specific flags that will be used for all link steps
129 Ldflags []string `android:"arch_variant"`
130
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700131 // instruction_set: the instruction set architecture to use to compile the C/C++
132 // module.
133 Instruction_set string `android:"arch_variant"`
134
Colin Cross3f40fa42015-01-30 17:27:36 -0800135 // include_dirs: list of directories relative to the root of the source tree that will
136 // be added to the include path using -I.
137 // If possible, don't use this. If adding paths from the current directory use
138 // local_include_dirs, if adding paths from other modules use export_include_dirs in
139 // that module.
140 Include_dirs []string `android:"arch_variant"`
141
142 // local_include_dirs: list of directories relative to the Blueprints file that will
143 // be added to the include path using -I
144 Local_include_dirs []string `android:"arch_variant"`
145
146 // export_include_dirs: list of directories relative to the Blueprints file that will
147 // be added to the include path using -I for any module that links against this module
148 Export_include_dirs []string
149
150 // clang_cflags: list of module-specific flags that will be used for C and C++ compiles when
151 // compiling with clang
152 Clang_cflags []string `android:"arch_variant"`
153
154 // clang_asflags: list of module-specific flags that will be used for .S compiles when
155 // compiling with clang
156 Clang_asflags []string `android:"arch_variant"`
157
158 // system_shared_libs: list of system libraries that will be dynamically linked to
159 // shared library and executable modules. If unset, generally defaults to libc
160 // and libm. Set to [] to prevent linking against libc and libm.
161 System_shared_libs []string
162
163 // whole_static_libs: list of modules whose object files should be linked into this module
164 // in their entirety. For static library modules, all of the .o files from the intermediate
165 // directory of the dependency will be linked into this modules .a file. For a shared library,
166 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
167 Whole_static_libs []string `android:"arch_variant"`
168
169 // static_libs: list of modules that should be statically linked into this module.
170 Static_libs []string `android:"arch_variant"`
171
172 // shared_libs: list of modules that should be dynamically linked into this module.
173 Shared_libs []string `android:"arch_variant"`
174
175 // allow_undefined_symbols: allow the module to contain undefined symbols. By default,
176 // modules cannot contain undefined symbols that are not satisified by their immediate
177 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
178 // This flag should only be necessary for compiling low-level libraries like libc.
179 Allow_undefined_symbols bool
180
181 // nocrt: don't link in crt_begin and crt_end. This flag should only be necessary for
182 // compiling crt or libc.
183 Nocrt bool `android:"arch_variant"`
184
185 // no_default_compiler_flags: don't insert default compiler flags into asflags, cflags,
186 // cppflags, conlyflags, ldflags, or include_dirs
187 No_default_compiler_flags bool
188
189 // clang: compile module with clang instead of gcc
190 Clang bool `android:"arch_variant"`
191
192 // rtti: pass -frtti instead of -fno-rtti
193 Rtti bool
194
195 // host_ldlibs: -l arguments to pass to linker for host-provided shared libraries
196 Host_ldlibs []string `android:"arch_variant"`
197
198 // stl: select the STL library to use. Possible values are "libc++", "libc++_static",
199 // "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
200 // default
201 Stl string
202
203 // Set for combined shared/static libraries to prevent compiling object files a second time
204 SkipCompileObjs bool `blueprint:"mutated"`
Colin Crossaf19a292015-03-18 12:07:10 -0700205
206 Debug struct {
207 Cflags []string `android:"arch_variant"`
208 } `android:"arch_variant"`
209 Release struct {
210 Cflags []string `android:"arch_variant"`
211 } `android:"arch_variant"`
Colin Crossefd8e482015-03-18 17:17:35 -0700212
213 // Minimum sdk version supported when compiling against the ndk
214 Sdk_version string
Colin Cross3f40fa42015-01-30 17:27:36 -0800215}
216
217type unusedProperties struct {
218 Asan bool
219 Native_coverage bool
220 Strip string
221 Tags []string
222 Required []string
223}
224
225// Building C/C++ code is handled by objects that satisfy this interface via composition
226type ccModuleType interface {
227 common.AndroidModule
228
229 // Return the cflags that are specific to this _type_ of module
230 moduleTypeCflags(common.AndroidModuleContext, toolchain) []string
231
232 // Return the ldflags that are specific to this _type_ of module
233 moduleTypeLdflags(common.AndroidModuleContext, toolchain) []string
234
235 // Create a ccDeps struct that collects the module dependency info. Can also
236 // modify ccFlags in order to add dependency include directories, etc.
237 collectDeps(common.AndroidModuleContext, ccFlags) (ccDeps, ccFlags)
238
239 // Compile objects into final module
240 compileModule(common.AndroidModuleContext, ccFlags, ccDeps, []string)
241
Dan Albertc403f7c2015-03-18 14:01:18 -0700242 // Install the built module.
243 installModule(common.AndroidModuleContext, ccFlags)
244
Colin Cross3f40fa42015-01-30 17:27:36 -0800245 // Return the output file (.o, .a or .so) for use by other modules
246 outputFile() string
247}
248
Colin Crossc472d572015-03-17 15:06:21 -0700249type ccDeps struct {
250 staticLibs, sharedLibs, lateStaticLibs, wholeStaticLibs, objFiles, includeDirs []string
251
252 crtBegin, crtEnd string
253}
254
255type ccFlags struct {
256 globalFlags []string
257 asFlags []string
258 cFlags []string
259 conlyFlags []string
260 cppFlags []string
261 ldFlags []string
262 ldLibs []string
263 includeDirs []string
264 nocrt bool
265 toolchain toolchain
266 clang bool
267
268 extraStaticLibs []string
269 extraSharedLibs []string
270}
271
272// ccBase contains the properties and members used by all C/C++ module types, and implements
273// the blueprint.Module interface. It expects to be embedded into an outer specialization struct,
274// and uses a ccModuleType interface to that struct to create the build steps.
275type ccBase struct {
276 common.AndroidModuleBase
277 module ccModuleType
278
279 properties ccProperties
280 unused unusedProperties
281
282 installPath string
283}
284
285func newCCBase(base *ccBase, module ccModuleType, hod common.HostOrDeviceSupported,
286 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
287
288 base.module = module
289
290 props = append(props, &base.properties, &base.unused)
291
Colin Cross5049f022015-03-18 13:28:46 -0700292 return common.InitAndroidArchModule(module, hod, multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700293}
294
Colin Cross3f40fa42015-01-30 17:27:36 -0800295func (c *ccBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
296 toolchain := c.findToolchain(ctx)
297 if ctx.Failed() {
298 return
299 }
300
301 flags := c.flags(ctx, toolchain)
302 if ctx.Failed() {
303 return
304 }
305
306 flags = c.addStlFlags(ctx, flags)
307 if ctx.Failed() {
308 return
309 }
310
311 deps, flags := c.ccModuleType().collectDeps(ctx, flags)
312 if ctx.Failed() {
313 return
314 }
315
Colin Crossed9f8682015-03-18 17:17:35 -0700316 flags.includeDirs = append(flags.includeDirs, deps.includeDirs...)
317
Colin Cross3f40fa42015-01-30 17:27:36 -0800318 objFiles := c.compileObjs(ctx, flags, deps)
319 if ctx.Failed() {
320 return
321 }
322
Colin Cross5049f022015-03-18 13:28:46 -0700323 generatedObjFiles := c.compileGeneratedObjs(ctx, flags, deps)
324 if ctx.Failed() {
325 return
326 }
327
328 objFiles = append(objFiles, generatedObjFiles...)
329
Colin Cross3f40fa42015-01-30 17:27:36 -0800330 c.ccModuleType().compileModule(ctx, flags, deps, objFiles)
331 if ctx.Failed() {
332 return
333 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700334
335 c.ccModuleType().installModule(ctx, flags)
336 if ctx.Failed() {
337 return
338 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800339}
340
341func (c *ccBase) ccModuleType() ccModuleType {
342 return c.module
343}
344
345var _ common.AndroidDynamicDepender = (*ccBase)(nil)
346
347func (c *ccBase) findToolchain(ctx common.AndroidModuleContext) toolchain {
348 arch := ctx.Arch()
349 factory := toolchainFactories[arch.HostOrDevice][arch.ArchType]
350 if factory == nil {
351 panic(fmt.Sprintf("Toolchain not found for %s arch %q",
352 arch.HostOrDevice.String(), arch.String()))
353 }
354 return factory(arch.ArchVariant, arch.CpuVariant)
355}
356
Colin Cross3f40fa42015-01-30 17:27:36 -0800357func (c *ccBase) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
358 return nil
359}
360
361func (c *ccBase) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
362 return nil
363}
364
365func (c *ccBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
366 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Whole_static_libs...)
367 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Static_libs...)
368 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.properties.Shared_libs...)
369
370 return nil
371}
372
373// Create a ccFlags struct that collects the compile flags from global values,
374// per-target values, module type values, and per-module Blueprints properties
375func (c *ccBase) flags(ctx common.AndroidModuleContext, toolchain toolchain) ccFlags {
376
377 arch := ctx.Arch()
378
379 flags := ccFlags{
380 cFlags: c.properties.Cflags,
381 cppFlags: c.properties.Cppflags,
382 conlyFlags: c.properties.Conlyflags,
383 ldFlags: c.properties.Ldflags,
384 asFlags: c.properties.Asflags,
385 nocrt: c.properties.Nocrt,
386 toolchain: toolchain,
387 clang: c.properties.Clang,
388 }
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700389 instructionSet := c.properties.Instruction_set
390 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
391 if err != nil {
392 ctx.ModuleErrorf("%s", err)
393 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800394
Colin Crossaf19a292015-03-18 12:07:10 -0700395 // TODO: debug
396 flags.cFlags = append(flags.cFlags, c.properties.Release.Cflags...)
397
Colin Cross3f40fa42015-01-30 17:27:36 -0800398 if arch.HostOrDevice.Host() {
399 // TODO: allow per-module clang disable for host
400 flags.clang = true
401 }
402
403 if flags.clang {
404 flags.cFlags = clangFilterUnknownCflags(flags.cFlags)
405 flags.cFlags = append(flags.cFlags, c.properties.Clang_cflags...)
406 flags.asFlags = append(flags.asFlags, c.properties.Clang_asflags...)
407 flags.cppFlags = clangFilterUnknownCflags(flags.cppFlags)
408 flags.conlyFlags = clangFilterUnknownCflags(flags.conlyFlags)
409 flags.ldFlags = clangFilterUnknownCflags(flags.ldFlags)
410
Colin Crossbdd7b1c2015-03-16 16:21:20 -0700411 flags.cFlags = append(flags.cFlags, "${clangExtraCflags}")
412 flags.conlyFlags = append(flags.conlyFlags, "${clangExtraConlyflags}")
413 if arch.HostOrDevice.Device() {
414 flags.cFlags = append(flags.cFlags, "${clangExtraTargetCflags}")
415 }
416
Colin Cross3f40fa42015-01-30 17:27:36 -0800417 target := "-target " + toolchain.ClangTriple()
418 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
419
420 flags.cFlags = append(flags.cFlags, target, gccPrefix)
421 flags.asFlags = append(flags.asFlags, target, gccPrefix)
422 flags.ldFlags = append(flags.ldFlags, target, gccPrefix)
423
424 if arch.HostOrDevice.Host() {
425 gccToolchain := "--gcc-toolchain=" + toolchain.GccRoot()
426 sysroot := "--sysroot=" + filepath.Join(toolchain.GccRoot(), "sysroot")
427
428 // TODO: also need more -B, -L flags to make host builds hermetic
429 flags.cFlags = append(flags.cFlags, gccToolchain, sysroot)
430 flags.asFlags = append(flags.asFlags, gccToolchain, sysroot)
431 flags.ldFlags = append(flags.ldFlags, gccToolchain, sysroot)
432 }
433 }
434
435 flags.includeDirs = pathtools.PrefixPaths(c.properties.Include_dirs, ctx.Config().(Config).SrcDir())
436 localIncludeDirs := pathtools.PrefixPaths(c.properties.Local_include_dirs, common.ModuleSrcDir(ctx))
437 flags.includeDirs = append(flags.includeDirs, localIncludeDirs...)
438
439 if !c.properties.No_default_compiler_flags {
440 flags.includeDirs = append(flags.includeDirs, []string{
441 common.ModuleSrcDir(ctx),
442 common.ModuleOutDir(ctx),
443 common.ModuleGenDir(ctx),
444 }...)
445
Colin Crossefd8e482015-03-18 17:17:35 -0700446 if c.properties.Sdk_version == "" {
447 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/libnativehelper/include/nativehelper")
448 }
449
Colin Cross3f40fa42015-01-30 17:27:36 -0800450 if arch.HostOrDevice.Device() && !c.properties.Allow_undefined_symbols {
451 flags.ldFlags = append(flags.ldFlags, "-Wl,--no-undefined")
452 }
453
454 if flags.clang {
Tim Kilbournf2948142015-03-11 12:03:03 -0700455 flags.cppFlags = append(flags.cppFlags, "${commonClangGlobalCppflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800456 flags.globalFlags = []string{
457 "${commonGlobalIncludes}",
458 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700459 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800460 toolchain.ClangCflags(),
461 "${commonClangGlobalCflags}",
462 fmt.Sprintf("${%sClangGlobalCflags}", arch.HostOrDevice),
463 }
464 } else {
Tim Kilbournf2948142015-03-11 12:03:03 -0700465 flags.cppFlags = append(flags.cppFlags, "${commonGlobalCppflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800466 flags.globalFlags = []string{
467 "${commonGlobalIncludes}",
468 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700469 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800470 toolchain.Cflags(),
471 "${commonGlobalCflags}",
472 fmt.Sprintf("${%sGlobalCflags}", arch.HostOrDevice),
473 }
474 }
475
476 if arch.HostOrDevice.Host() {
477 flags.ldFlags = append(flags.ldFlags, c.properties.Host_ldlibs...)
478 }
479
480 if arch.HostOrDevice.Device() {
481 if c.properties.Rtti {
482 flags.cppFlags = append(flags.cppFlags, "-frtti")
483 } else {
484 flags.cppFlags = append(flags.cppFlags, "-fno-rtti")
485 }
486 }
487
488 flags.asFlags = append(flags.asFlags, "-D__ASSEMBLY__")
489
490 if flags.clang {
491 flags.cppFlags = append(flags.cppFlags, toolchain.ClangCppflags())
492 flags.ldFlags = append(flags.ldFlags, toolchain.ClangLdflags())
493 } else {
494 flags.cppFlags = append(flags.cppFlags, toolchain.Cppflags())
495 flags.ldFlags = append(flags.ldFlags, toolchain.Ldflags())
496 }
497 }
498
499 flags.cFlags = append(flags.cFlags, c.ccModuleType().moduleTypeCflags(ctx, toolchain)...)
500 flags.ldFlags = append(flags.ldFlags, c.ccModuleType().moduleTypeLdflags(ctx, toolchain)...)
501
502 // Optimization to reduce size of build.ninja
503 // Replace the long list of flags for each file with a module-local variable
504 ctx.Variable(pctx, "cflags", strings.Join(flags.cFlags, " "))
505 ctx.Variable(pctx, "cppflags", strings.Join(flags.cppFlags, " "))
506 ctx.Variable(pctx, "asflags", strings.Join(flags.asFlags, " "))
507 flags.cFlags = []string{"$cflags"}
508 flags.cppFlags = []string{"$cppflags"}
509 flags.asFlags = []string{"$asflags"}
510
511 return flags
512}
513
514// Modify ccFlags structs with STL library info
515func (c *ccBase) addStlFlags(ctx common.AndroidModuleContext, flags ccFlags) ccFlags {
516 if !c.properties.No_default_compiler_flags {
517 arch := ctx.Arch()
518 stl := "libc++" // TODO: mingw needs libstdc++
519 if c.properties.Stl != "" {
520 stl = c.properties.Stl
521 }
522
523 stlStatic := false
524 if strings.HasSuffix(stl, "_static") {
525 stlStatic = true
526 }
527
528 switch stl {
529 case "libc++", "libc++_static":
530 flags.cFlags = append(flags.cFlags, "-D_USING_LIBCXX")
531 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/external/libcxx/include")
532 if arch.HostOrDevice.Host() {
533 flags.cppFlags = append(flags.cppFlags, "-nostdinc++")
534 flags.ldFlags = append(flags.ldFlags, "-nodefaultlibs")
535 flags.ldLibs = append(flags.ldLibs, "-lc", "-lm", "-lpthread")
536 }
537 if stlStatic {
538 flags.extraStaticLibs = append(flags.extraStaticLibs, "libc++_static")
539 } else {
540 flags.extraSharedLibs = append(flags.extraSharedLibs, "libc++")
541 }
542 case "stlport", "stlport_static":
543 if arch.HostOrDevice.Device() {
544 flags.includeDirs = append(flags.includeDirs,
545 "${SrcDir}/external/stlport/stlport",
546 "${SrcDir}/bionic/libstdc++/include",
547 "${SrcDir}/bionic")
548 if stlStatic {
549 flags.extraStaticLibs = append(flags.extraStaticLibs, "libstdc++", "libstlport_static")
550 } else {
551 flags.extraSharedLibs = append(flags.extraSharedLibs, "libstdc++", "libstlport")
552 }
553 }
554 case "ndk":
555 panic("TODO")
556 case "libstdc++":
557 // Using bionic's basic libstdc++. Not actually an STL. Only around until the
558 // tree is in good enough shape to not need it.
559 // Host builds will use GNU libstdc++.
560 if arch.HostOrDevice.Device() {
561 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/bionic/libstdc++/include")
562 flags.extraSharedLibs = append(flags.extraSharedLibs, "libstdc++")
563 }
564 case "none":
565 if arch.HostOrDevice.Host() {
566 flags.cppFlags = append(flags.cppFlags, "-nostdinc++")
567 flags.ldFlags = append(flags.ldFlags, "-nodefaultlibs")
568 flags.ldLibs = append(flags.ldLibs, "-lc", "-lm")
569 }
570 default:
571 ctx.ModuleErrorf("stl: %q is not a supported STL", stl)
572 }
573
574 }
575 return flags
576}
577
578// Compile a list of source files into objects a specified subdirectory
579func (c *ccBase) customCompileObjs(ctx common.AndroidModuleContext, flags ccFlags,
580 deps ccDeps, subdir string, srcFiles []string) []string {
581
582 srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
583 srcFiles = common.ExpandGlobs(ctx, srcFiles)
584
585 return TransformSourceToObj(ctx, subdir, srcFiles, ccFlagsToBuilderFlags(flags))
586}
587
588// Compile files listed in c.properties.Srcs into objects
589func (c *ccBase) compileObjs(ctx common.AndroidModuleContext, flags ccFlags,
590 deps ccDeps) []string {
591
592 if c.properties.SkipCompileObjs {
593 return nil
594 }
595
596 return c.customCompileObjs(ctx, flags, deps, "", c.properties.Srcs)
597}
598
Colin Cross5049f022015-03-18 13:28:46 -0700599// Compile generated source files from dependencies
600func (c *ccBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags ccFlags,
601 deps ccDeps) []string {
602 var srcs []string
603
604 if c.properties.SkipCompileObjs {
605 return nil
606 }
607
608 ctx.VisitDirectDeps(func(module blueprint.Module) {
609 if gen, ok := module.(genrule.SourceFileGenerator); ok {
610 srcs = append(srcs, gen.GeneratedSourceFiles()...)
611 }
612 })
613
614 if len(srcs) == 0 {
615 return nil
616 }
617
618 return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags))
619}
620
Colin Cross3f40fa42015-01-30 17:27:36 -0800621func (c *ccBase) outputFile() string {
622 return ""
623}
624
625func (c *ccBase) collectDepsFromList(ctx common.AndroidModuleContext,
626 names []string) (modules []common.AndroidModule,
627 outputFiles []string, exportedIncludeDirs []string) {
628
629 for _, n := range names {
630 found := false
631 ctx.VisitDirectDeps(func(m blueprint.Module) {
632 otherName := ctx.OtherModuleName(m)
633 if otherName != n {
634 return
635 }
636
637 if a, ok := m.(ccModuleType); ok {
638 if a.Disabled() {
639 // If a cc_library host+device module depends on a library that exists as both
640 // cc_library_shared and cc_library_host_shared, it will end up with two
641 // dependencies with the same name, one of which is marked disabled for each
642 // of host and device. Ignore the disabled one.
643 return
644 }
645 if a.HostOrDevice() != ctx.Arch().HostOrDevice {
646 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
647 otherName)
648 return
649 }
650
651 if outputFile := a.outputFile(); outputFile != "" {
652 if found {
653 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
654 return
655 }
656 outputFiles = append(outputFiles, outputFile)
657 modules = append(modules, a)
658 if i, ok := a.(ccExportedIncludeDirsProducer); ok {
659 exportedIncludeDirs = append(exportedIncludeDirs, i.exportedIncludeDirs()...)
660 }
661 found = true
662 } else {
663 ctx.ModuleErrorf("module %q missing output file", otherName)
664 return
665 }
666 } else {
667 ctx.ModuleErrorf("module %q not an android module", otherName)
668 return
669 }
670 })
671 if !found {
672 ctx.ModuleErrorf("unsatisified dependency on %q", n)
673 }
674 }
675
676 return modules, outputFiles, exportedIncludeDirs
677}
678
679func (c *ccBase) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
680 var deps ccDeps
681 var newIncludeDirs []string
682
683 wholeStaticLibNames := c.properties.Whole_static_libs
684 _, deps.wholeStaticLibs, newIncludeDirs = c.collectDepsFromList(ctx, wholeStaticLibNames)
685
686 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
687
688 staticLibNames := c.properties.Static_libs
689 staticLibNames = append(staticLibNames, flags.extraStaticLibs...)
690 _, deps.staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
691 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
692
693 return deps, flags
694}
695
696// ccDynamic contains the properties and members used by shared libraries and dynamic executables
697type ccDynamic struct {
698 ccBase
699}
700
Colin Crossc472d572015-03-17 15:06:21 -0700701func newCCDynamic(dynamic *ccDynamic, module ccModuleType, hod common.HostOrDeviceSupported,
702 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
703
704 dynamic.properties.System_shared_libs = []string{defaultSystemSharedLibraries}
705
706 return newCCBase(&dynamic.ccBase, module, hod, multilib, props...)
707}
708
Colin Cross3f40fa42015-01-30 17:27:36 -0800709const defaultSystemSharedLibraries = "__default__"
710
711func (c *ccDynamic) systemSharedLibs() []string {
712
713 if len(c.properties.System_shared_libs) == 1 &&
714 c.properties.System_shared_libs[0] == defaultSystemSharedLibraries {
715
716 if c.HostOrDevice().Host() {
717 return []string{}
718 } else {
719 return []string{"libc", "libm"}
720 }
721 }
722 return c.properties.System_shared_libs
723}
724
725var (
726 stlSharedLibs = []string{"libc++", "libstlport", "libstdc++"}
727 stlSharedHostLibs = []string{"libc++"}
728 stlStaticLibs = []string{"libc++_static", "libstlport_static", "libstdc++"}
729 stlStaticHostLibs = []string{"libc++_static"}
730)
731
732func (c *ccDynamic) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
733 deps := c.ccBase.AndroidDynamicDependencies(ctx)
734
735 if c.HostOrDevice().Device() {
736 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.systemSharedLibs()...)
737 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}},
738 "libcompiler_rt-extras",
Colin Cross77b00fa2015-03-16 16:15:49 -0700739 "libgcov",
Colin Cross3f40fa42015-01-30 17:27:36 -0800740 "libatomic",
741 "libgcc")
742
743 if c.properties.Stl != "none" {
744 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedLibs...)
745 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticLibs...)
746 }
747 } else {
748 if c.properties.Stl != "none" {
749 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedHostLibs...)
750 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticHostLibs...)
751 }
752 }
753
754 return deps
755}
756
Colin Cross3f40fa42015-01-30 17:27:36 -0800757func (c *ccDynamic) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
758 var newIncludeDirs []string
759
760 deps, flags := c.ccBase.collectDeps(ctx, flags)
761
762 systemSharedLibs := c.systemSharedLibs()
763 sharedLibNames := make([]string, 0, len(c.properties.Shared_libs)+len(systemSharedLibs)+
764 len(flags.extraSharedLibs))
765 sharedLibNames = append(sharedLibNames, c.properties.Shared_libs...)
766 sharedLibNames = append(sharedLibNames, systemSharedLibs...)
767 sharedLibNames = append(sharedLibNames, flags.extraSharedLibs...)
768 _, deps.sharedLibs, newIncludeDirs = c.collectDepsFromList(ctx, sharedLibNames)
769 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
770
771 if ctx.Arch().HostOrDevice.Device() {
772 var staticLibs []string
Colin Cross77b00fa2015-03-16 16:15:49 -0700773 staticLibNames := []string{"libcompiler_rt-extras"}
Colin Cross3f40fa42015-01-30 17:27:36 -0800774 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
775 deps.staticLibs = append(deps.staticLibs, staticLibs...)
776 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
Colin Cross77b00fa2015-03-16 16:15:49 -0700777
778 // libgcc and libatomic have to be last on the command line
779 staticLibNames = []string{"libgcov", "libatomic", "libgcc"}
780 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
781 deps.lateStaticLibs = append(deps.lateStaticLibs, staticLibs...)
782 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800783 }
784
785 ctx.VisitDirectDeps(func(m blueprint.Module) {
786 if obj, ok := m.(*ccObject); ok {
787 otherName := ctx.OtherModuleName(m)
788 if strings.HasPrefix(otherName, "crtbegin") {
789 if !c.properties.Nocrt {
790 deps.crtBegin = obj.outputFile()
791 }
792 } else if strings.HasPrefix(otherName, "crtend") {
793 if !c.properties.Nocrt {
794 deps.crtEnd = obj.outputFile()
795 }
796 } else {
797 ctx.ModuleErrorf("object module type only support for crtbegin and crtend, found %q",
798 ctx.OtherModuleName(m))
799 }
800 }
801 })
802
Colin Cross3f40fa42015-01-30 17:27:36 -0800803 return deps, flags
804}
805
806type ccExportedIncludeDirsProducer interface {
807 exportedIncludeDirs() []string
808}
809
810//
811// Combined static+shared libraries
812//
813
814type ccLibrary struct {
815 ccDynamic
816
817 primary *ccLibrary
818 primaryObjFiles []string
819 objFiles []string
820 exportIncludeDirs []string
821 out string
822
823 libraryProperties struct {
824 BuildStatic bool `blueprint:"mutated"`
825 BuildShared bool `blueprint:"mutated"`
826 IsShared bool `blueprint:"mutated"`
827 IsStatic bool `blueprint:"mutated"`
828
829 Static struct {
830 Srcs []string `android:"arch_variant"`
831 Cflags []string `android:"arch_variant"`
832 } `android:"arch_variant"`
833 Shared struct {
834 Srcs []string `android:"arch_variant"`
835 Cflags []string `android:"arch_variant"`
836 } `android:"arch_variant"`
837 }
838}
839
Colin Crossc472d572015-03-17 15:06:21 -0700840func newCCLibrary(library *ccLibrary, hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
841 return newCCDynamic(&library.ccDynamic, library, hod, common.MultilibBoth,
842 &library.libraryProperties)
843}
844
Colin Cross3f40fa42015-01-30 17:27:36 -0800845func NewCCLibrary() (blueprint.Module, []interface{}) {
846 module := &ccLibrary{}
Colin Crossc472d572015-03-17 15:06:21 -0700847
Colin Cross3f40fa42015-01-30 17:27:36 -0800848 module.libraryProperties.BuildShared = true
849 module.libraryProperties.BuildStatic = true
850
Colin Crossc472d572015-03-17 15:06:21 -0700851 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800852}
853
854func (c *ccLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
855 if c.libraryProperties.IsShared {
856 deps := c.ccDynamic.AndroidDynamicDependencies(ctx)
857 if c.HostOrDevice().Device() {
858 deps = append(deps, "crtbegin_so", "crtend_so")
859 }
860 return deps
861 } else {
862 return c.ccBase.AndroidDynamicDependencies(ctx)
863 }
864}
865
866func (c *ccLibrary) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
867 if c.libraryProperties.IsStatic {
868 deps, flags := c.ccBase.collectDeps(ctx, flags)
869 wholeStaticLibNames := c.properties.Whole_static_libs
870 wholeStaticLibs, _, _ := c.collectDepsFromList(ctx, wholeStaticLibNames)
871
872 for _, m := range wholeStaticLibs {
873 if staticLib, ok := m.(*ccLibrary); ok && staticLib.libraryProperties.IsStatic {
874 deps.objFiles = append(deps.objFiles, staticLib.allObjFiles()...)
875 } else {
876 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
877 }
878 }
879
Colin Crossed9f8682015-03-18 17:17:35 -0700880 // Collect exported includes from shared lib dependencies
881 sharedLibNames := c.properties.Shared_libs
882 _, _, newIncludeDirs := c.collectDepsFromList(ctx, sharedLibNames)
883 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
884
Colin Cross3f40fa42015-01-30 17:27:36 -0800885 return deps, flags
886 } else if c.libraryProperties.IsShared {
887 return c.ccDynamic.collectDeps(ctx, flags)
888 } else {
889 panic("Not shared or static")
890 }
891}
892
893func (c *ccLibrary) outputFile() string {
894 return c.out
895}
896
897func (c *ccLibrary) allObjFiles() []string {
898 return c.objFiles
899}
900
901func (c *ccLibrary) exportedIncludeDirs() []string {
902 return c.exportIncludeDirs
903}
904
905func (c *ccLibrary) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
906 return []string{"-fPIC"}
907}
908
909func (c *ccLibrary) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
910 if c.libraryProperties.IsShared {
911 libName := ctx.ModuleName()
912 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
913 sharedFlag := "-Wl,-shared"
914 if c.properties.Clang || ctx.Arch().HostOrDevice.Host() {
915 sharedFlag = "-shared"
916 }
917 if ctx.Arch().HostOrDevice.Device() {
918 return []string{
919 "-nostdlib",
920 "-Wl,--gc-sections",
921 sharedFlag,
Colin Cross6072ad42015-03-16 16:22:04 -0700922 "-Wl,-soname," + libName + sharedLibraryExtension,
Colin Cross3f40fa42015-01-30 17:27:36 -0800923 }
924 } else {
925 return []string{
926 "-Wl,--gc-sections",
927 sharedFlag,
Colin Cross6072ad42015-03-16 16:22:04 -0700928 "-Wl,-soname," + libName + sharedLibraryExtension,
Colin Cross3f40fa42015-01-30 17:27:36 -0800929 }
930 }
931 } else {
932 return nil
933 }
934}
935
936func (c *ccLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
937 flags ccFlags, deps ccDeps, objFiles []string) {
938
939 staticFlags := flags
940 staticFlags.cFlags = append(staticFlags.cFlags, c.libraryProperties.Static.Cflags...)
941 objFilesStatic := c.customCompileObjs(ctx, staticFlags, deps, common.DeviceStaticLibrary,
942 c.libraryProperties.Static.Srcs)
943
944 objFiles = append(objFiles, objFilesStatic...)
945
946 var includeDirs []string
947
948 wholeStaticLibNames := c.properties.Whole_static_libs
949 wholeStaticLibs, _, newIncludeDirs := c.collectDepsFromList(ctx, wholeStaticLibNames)
950 includeDirs = append(includeDirs, newIncludeDirs...)
951
952 for _, m := range wholeStaticLibs {
953 if staticLib, ok := m.(*ccLibrary); ok && staticLib.libraryProperties.IsStatic {
954 objFiles = append(objFiles, staticLib.allObjFiles()...)
955 } else {
956 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
957 }
958 }
959
960 staticLibNames := c.properties.Static_libs
961 _, _, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
962 includeDirs = append(includeDirs, newIncludeDirs...)
963
964 ctx.VisitDirectDeps(func(m blueprint.Module) {
965 if obj, ok := m.(*ccObject); ok {
966 otherName := ctx.OtherModuleName(m)
967 if !strings.HasPrefix(otherName, "crtbegin") && !strings.HasPrefix(otherName, "crtend") {
968 objFiles = append(objFiles, obj.outputFile())
969 }
970 }
971 })
972
973 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
974
975 TransformObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
976
977 c.objFiles = objFiles
978 c.out = outputFile
979 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
980 common.ModuleSrcDir(ctx))
981
982 ctx.CheckbuildFile(outputFile)
983}
984
985func (c *ccLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
986 flags ccFlags, deps ccDeps, objFiles []string) {
987
988 sharedFlags := flags
989 sharedFlags.cFlags = append(sharedFlags.cFlags, c.libraryProperties.Shared.Cflags...)
990 objFilesShared := c.customCompileObjs(ctx, sharedFlags, deps, common.DeviceSharedLibrary,
991 c.libraryProperties.Shared.Srcs)
992
993 objFiles = append(objFiles, objFilesShared...)
994
995 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
996
Colin Cross77b00fa2015-03-16 16:15:49 -0700997 TransformObjToDynamicBinary(ctx, objFiles, deps.sharedLibs, deps.staticLibs,
998 deps.lateStaticLibs, deps.wholeStaticLibs, deps.crtBegin, deps.crtEnd,
999 ccFlagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001000
1001 c.out = outputFile
1002 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
1003 common.ModuleSrcDir(ctx))
Colin Cross3f40fa42015-01-30 17:27:36 -08001004}
1005
1006func (c *ccLibrary) compileModule(ctx common.AndroidModuleContext,
1007 flags ccFlags, deps ccDeps, objFiles []string) {
1008
1009 // Reuse the object files from the matching static library if it exists
1010 if c.primary == c {
1011 c.primaryObjFiles = objFiles
1012 } else {
1013 objFiles = append([]string(nil), c.primary.primaryObjFiles...)
1014 }
1015
1016 if c.libraryProperties.IsStatic {
1017 c.compileStaticLibrary(ctx, flags, deps, objFiles)
1018 } else {
1019 c.compileSharedLibrary(ctx, flags, deps, objFiles)
1020 }
1021}
1022
Dan Albertc403f7c2015-03-18 14:01:18 -07001023func (c *ccLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
1024 // Static libraries do not get installed.
1025}
1026
1027func (c *ccLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
1028 installDir := "lib"
1029 if flags.toolchain.Is64Bit() {
1030 installDir = "lib64"
1031 }
1032
1033 ctx.InstallFile(installDir, c.out)
1034}
1035
1036func (c *ccLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1037 if c.libraryProperties.IsStatic {
1038 c.installStaticLibrary(ctx, flags)
1039 } else {
1040 c.installSharedLibrary(ctx, flags)
1041 }
1042}
1043
Colin Cross3f40fa42015-01-30 17:27:36 -08001044//
1045// Objects (for crt*.o)
1046//
1047
1048type ccObject struct {
1049 ccBase
1050 out string
1051}
1052
1053func NewCCObject() (blueprint.Module, []interface{}) {
1054 module := &ccObject{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001055
Colin Crossc472d572015-03-17 15:06:21 -07001056 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001057}
1058
1059func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1060 // object files can't have any dynamic dependencies
1061 return nil
1062}
1063
1064func (c *ccObject) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1065 deps, flags := c.ccBase.collectDeps(ctx, flags)
1066 ctx.VisitDirectDeps(func(m blueprint.Module) {
1067 if obj, ok := m.(*ccObject); ok {
1068 deps.objFiles = append(deps.objFiles, obj.outputFile())
1069 } else {
1070 ctx.ModuleErrorf("Unknown module type for dependency %q", ctx.OtherModuleName(m))
1071 }
1072 })
1073
1074 return deps, flags
1075}
1076
1077func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
1078 flags ccFlags, deps ccDeps, objFiles []string) {
1079
1080 objFiles = append(objFiles, deps.objFiles...)
1081
1082 var outputFile string
1083 if len(objFiles) == 1 {
1084 outputFile = objFiles[0]
1085 } else {
1086 outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+".o")
1087 TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1088 }
1089
1090 c.out = outputFile
1091
1092 ctx.CheckbuildFile(outputFile)
1093}
1094
Dan Albertc403f7c2015-03-18 14:01:18 -07001095func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1096 // Object files do not get installed.
1097}
1098
Colin Cross3f40fa42015-01-30 17:27:36 -08001099func (c *ccObject) outputFile() string {
1100 return c.out
1101}
1102
1103//
1104// Executables
1105//
1106
1107type ccBinary struct {
1108 ccDynamic
Dan Albertc403f7c2015-03-18 14:01:18 -07001109 out string
Colin Cross3f40fa42015-01-30 17:27:36 -08001110 binaryProperties binaryProperties
1111}
1112
1113type binaryProperties struct {
1114 // static_executable: compile executable with -static
1115 Static_executable bool
1116
1117 // stem: set the name of the output
1118 Stem string `android:"arch_variant"`
1119
1120 // prefix_symbols: if set, add an extra objcopy --prefix-symbols= step
1121 Prefix_symbols string
1122}
1123
1124func (c *ccBinary) getStem(ctx common.AndroidModuleContext) string {
1125 if c.binaryProperties.Stem != "" {
1126 return c.binaryProperties.Stem
1127 }
1128 return ctx.ModuleName()
1129}
1130
1131func (c *ccBinary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1132 deps := c.ccDynamic.AndroidDynamicDependencies(ctx)
1133 if c.HostOrDevice().Device() {
1134 if c.binaryProperties.Static_executable {
1135 deps = append(deps, "crtbegin_static", "crtend_android")
1136 } else {
1137 deps = append(deps, "crtbegin_dynamic", "crtend_android")
1138 }
1139 }
1140 return deps
1141}
1142
1143func NewCCBinary() (blueprint.Module, []interface{}) {
1144 module := &ccBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001145
Colin Crossc472d572015-03-17 15:06:21 -07001146 return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported, common.MultilibFirst,
1147 &module.binaryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001148}
1149
1150func (c *ccBinary) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
1151 return []string{"-fpie"}
1152}
1153
1154func (c *ccBinary) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
1155 if ctx.Arch().HostOrDevice.Device() {
1156 linker := "/system/bin/linker"
1157 if toolchain.Is64Bit() {
1158 linker = "/system/bin/linker64"
1159 }
1160
1161 return []string{
1162 "-nostdlib",
1163 "-Bdynamic",
1164 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1165 "-Wl,--gc-sections",
1166 "-Wl,-z,nocopyreloc",
1167 }
1168 }
1169
1170 return nil
1171}
1172
1173func (c *ccBinary) compileModule(ctx common.AndroidModuleContext,
1174 flags ccFlags, deps ccDeps, objFiles []string) {
1175
1176 if !c.binaryProperties.Static_executable && inList("libc", c.properties.Static_libs) {
1177 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1178 "from static libs or set static_executable: true")
1179 }
1180
1181 outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
Dan Albertc403f7c2015-03-18 14:01:18 -07001182 c.out = outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001183
Colin Cross77b00fa2015-03-16 16:15:49 -07001184 TransformObjToDynamicBinary(ctx, objFiles, deps.sharedLibs, deps.staticLibs,
1185 deps.lateStaticLibs, deps.wholeStaticLibs, deps.crtBegin, deps.crtEnd,
1186 ccFlagsToBuilderFlags(flags), outputFile)
Dan Albertc403f7c2015-03-18 14:01:18 -07001187}
Colin Cross3f40fa42015-01-30 17:27:36 -08001188
Dan Albertc403f7c2015-03-18 14:01:18 -07001189func (c *ccBinary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1190 ctx.InstallFile("bin", c.out)
1191}
1192
1193type ccTest struct {
1194 ccBinary
1195}
1196
1197var (
1198 gtestLibs = []string{"libgtest", "libgtest_main"}
1199)
1200
1201func (c *ccTest) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1202 deps, flags := c.ccBinary.collectDeps(ctx, flags)
1203
1204 flags.cFlags = append(flags.cFlags, "-DGTEST_HAS_STD_STRING")
1205 if c.HostOrDevice().Host() {
1206 flags.cFlags = append(flags.cFlags, "-O0", "-g")
1207 flags.ldLibs = append(flags.ldLibs, "-lpthread")
1208 }
1209
1210 // TODO(danalbert): Make gtest export its dependencies.
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001211 flags.includeDirs = append(flags.includeDirs,
1212 filepath.Join(ctx.Config().(Config).SrcDir(), "external/gtest/include"))
Dan Albertc403f7c2015-03-18 14:01:18 -07001213
1214 _, staticLibs, _ := c.collectDepsFromList(ctx, gtestLibs)
1215 deps.staticLibs = append(deps.staticLibs, staticLibs...)
1216
1217 return deps, flags
1218}
1219
1220func (c *ccTest) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1221 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, gtestLibs...)
1222 deps := c.ccBinary.AndroidDynamicDependencies(ctx)
1223 return append(deps, gtestLibs...)
1224}
1225
1226func (c *ccTest) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1227 if c.HostOrDevice().Device() {
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001228 ctx.InstallFile("../data/nativetest/"+ctx.ModuleName(), c.out)
Dan Albertc403f7c2015-03-18 14:01:18 -07001229 } else {
1230 c.ccBinary.installModule(ctx, flags)
1231 }
1232}
1233
1234func NewCCTest() (blueprint.Module, []interface{}) {
1235 module := &ccTest{}
1236 return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported,
1237 common.MultilibFirst, &module.binaryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001238}
1239
1240//
1241// Static library
1242//
1243
1244func NewCCLibraryStatic() (blueprint.Module, []interface{}) {
1245 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001246 module.libraryProperties.BuildStatic = true
1247
Colin Crossc472d572015-03-17 15:06:21 -07001248 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001249}
1250
1251//
1252// Shared libraries
1253//
1254
1255func NewCCLibraryShared() (blueprint.Module, []interface{}) {
1256 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001257 module.libraryProperties.BuildShared = true
1258
Colin Crossc472d572015-03-17 15:06:21 -07001259 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001260}
1261
1262//
1263// Host static library
1264//
1265
1266func NewCCLibraryHostStatic() (blueprint.Module, []interface{}) {
1267 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001268 module.libraryProperties.BuildStatic = true
1269
Colin Crossc472d572015-03-17 15:06:21 -07001270 return newCCLibrary(module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001271}
1272
1273//
1274// Host Shared libraries
1275//
1276
1277func NewCCLibraryHostShared() (blueprint.Module, []interface{}) {
1278 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001279 module.libraryProperties.BuildShared = true
1280
Colin Crossc472d572015-03-17 15:06:21 -07001281 return newCCLibrary(module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001282}
1283
1284//
1285// Host Binaries
1286//
1287
1288func NewCCBinaryHost() (blueprint.Module, []interface{}) {
1289 module := &ccBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001290
Colin Crossc472d572015-03-17 15:06:21 -07001291 return newCCDynamic(&module.ccDynamic, module, common.HostSupported, common.MultilibFirst)
Colin Cross3f40fa42015-01-30 17:27:36 -08001292}
1293
1294//
1295// Device libraries shipped with gcc
1296//
1297
1298type toolchainLibrary struct {
1299 ccLibrary
1300}
1301
1302func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1303 // toolchain libraries can't have any dependencies
1304 return nil
1305}
1306
1307func (*toolchainLibrary) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1308 // toolchain libraries can't have any dependencies
1309 return ccDeps{}, flags
1310}
1311
1312func NewToolchainLibrary() (blueprint.Module, []interface{}) {
1313 module := &toolchainLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001314
Colin Crossc472d572015-03-17 15:06:21 -07001315 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001316}
1317
1318func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
1319 flags ccFlags, deps ccDeps, objFiles []string) {
1320
1321 libName := ctx.ModuleName() + staticLibraryExtension
1322 outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
1323
1324 CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
1325
1326 c.out = outputFile
1327
1328 ctx.CheckbuildFile(outputFile)
1329}
1330
Dan Albertc403f7c2015-03-18 14:01:18 -07001331func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1332 // Toolchain libraries do not get installed.
1333}
1334
Colin Cross3f40fa42015-01-30 17:27:36 -08001335func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
1336 if c, ok := mctx.Module().(*ccLibrary); ok {
1337 var modules []blueprint.Module
1338 if c.libraryProperties.BuildStatic && c.libraryProperties.BuildShared {
1339 modules = mctx.CreateLocalVariations("static", "shared")
1340 modules[0].(*ccLibrary).libraryProperties.IsStatic = true
1341 modules[1].(*ccLibrary).libraryProperties.IsShared = true
1342 } else if c.libraryProperties.BuildStatic {
1343 modules = mctx.CreateLocalVariations("static")
1344 modules[0].(*ccLibrary).libraryProperties.IsStatic = true
1345 } else if c.libraryProperties.BuildShared {
1346 modules = mctx.CreateLocalVariations("shared")
1347 modules[0].(*ccLibrary).libraryProperties.IsShared = true
1348 } else {
1349 panic("ccLibrary not static or shared")
1350 }
1351 primary := modules[0].(*ccLibrary)
1352 for _, m := range modules {
1353 m.(*ccLibrary).primary = primary
1354 if m != primary {
1355 m.(*ccLibrary).properties.SkipCompileObjs = true
1356 }
1357 }
1358 } else if _, ok := mctx.Module().(*toolchainLibrary); ok {
1359 mctx.CreateLocalVariations("static")
1360 }
1361}