blob: f76706b876dbd763874c2482a0ab122caa513a79 [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
316 objFiles := c.compileObjs(ctx, flags, deps)
317 if ctx.Failed() {
318 return
319 }
320
Colin Cross5049f022015-03-18 13:28:46 -0700321 generatedObjFiles := c.compileGeneratedObjs(ctx, flags, deps)
322 if ctx.Failed() {
323 return
324 }
325
326 objFiles = append(objFiles, generatedObjFiles...)
327
Colin Cross3f40fa42015-01-30 17:27:36 -0800328 c.ccModuleType().compileModule(ctx, flags, deps, objFiles)
329 if ctx.Failed() {
330 return
331 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700332
333 c.ccModuleType().installModule(ctx, flags)
334 if ctx.Failed() {
335 return
336 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800337}
338
339func (c *ccBase) ccModuleType() ccModuleType {
340 return c.module
341}
342
343var _ common.AndroidDynamicDepender = (*ccBase)(nil)
344
345func (c *ccBase) findToolchain(ctx common.AndroidModuleContext) toolchain {
346 arch := ctx.Arch()
347 factory := toolchainFactories[arch.HostOrDevice][arch.ArchType]
348 if factory == nil {
349 panic(fmt.Sprintf("Toolchain not found for %s arch %q",
350 arch.HostOrDevice.String(), arch.String()))
351 }
352 return factory(arch.ArchVariant, arch.CpuVariant)
353}
354
Colin Cross3f40fa42015-01-30 17:27:36 -0800355func (c *ccBase) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
356 return nil
357}
358
359func (c *ccBase) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
360 return nil
361}
362
363func (c *ccBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
364 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Whole_static_libs...)
365 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Static_libs...)
366 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.properties.Shared_libs...)
367
368 return nil
369}
370
371// Create a ccFlags struct that collects the compile flags from global values,
372// per-target values, module type values, and per-module Blueprints properties
373func (c *ccBase) flags(ctx common.AndroidModuleContext, toolchain toolchain) ccFlags {
374
375 arch := ctx.Arch()
376
377 flags := ccFlags{
378 cFlags: c.properties.Cflags,
379 cppFlags: c.properties.Cppflags,
380 conlyFlags: c.properties.Conlyflags,
381 ldFlags: c.properties.Ldflags,
382 asFlags: c.properties.Asflags,
383 nocrt: c.properties.Nocrt,
384 toolchain: toolchain,
385 clang: c.properties.Clang,
386 }
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700387 instructionSet := c.properties.Instruction_set
388 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
389 if err != nil {
390 ctx.ModuleErrorf("%s", err)
391 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800392
Colin Crossaf19a292015-03-18 12:07:10 -0700393 // TODO: debug
394 flags.cFlags = append(flags.cFlags, c.properties.Release.Cflags...)
395
Colin Cross3f40fa42015-01-30 17:27:36 -0800396 if arch.HostOrDevice.Host() {
397 // TODO: allow per-module clang disable for host
398 flags.clang = true
399 }
400
401 if flags.clang {
402 flags.cFlags = clangFilterUnknownCflags(flags.cFlags)
403 flags.cFlags = append(flags.cFlags, c.properties.Clang_cflags...)
404 flags.asFlags = append(flags.asFlags, c.properties.Clang_asflags...)
405 flags.cppFlags = clangFilterUnknownCflags(flags.cppFlags)
406 flags.conlyFlags = clangFilterUnknownCflags(flags.conlyFlags)
407 flags.ldFlags = clangFilterUnknownCflags(flags.ldFlags)
408
Colin Crossbdd7b1c2015-03-16 16:21:20 -0700409 flags.cFlags = append(flags.cFlags, "${clangExtraCflags}")
410 flags.conlyFlags = append(flags.conlyFlags, "${clangExtraConlyflags}")
411 if arch.HostOrDevice.Device() {
412 flags.cFlags = append(flags.cFlags, "${clangExtraTargetCflags}")
413 }
414
Colin Cross3f40fa42015-01-30 17:27:36 -0800415 target := "-target " + toolchain.ClangTriple()
416 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
417
418 flags.cFlags = append(flags.cFlags, target, gccPrefix)
419 flags.asFlags = append(flags.asFlags, target, gccPrefix)
420 flags.ldFlags = append(flags.ldFlags, target, gccPrefix)
421
422 if arch.HostOrDevice.Host() {
423 gccToolchain := "--gcc-toolchain=" + toolchain.GccRoot()
424 sysroot := "--sysroot=" + filepath.Join(toolchain.GccRoot(), "sysroot")
425
426 // TODO: also need more -B, -L flags to make host builds hermetic
427 flags.cFlags = append(flags.cFlags, gccToolchain, sysroot)
428 flags.asFlags = append(flags.asFlags, gccToolchain, sysroot)
429 flags.ldFlags = append(flags.ldFlags, gccToolchain, sysroot)
430 }
431 }
432
433 flags.includeDirs = pathtools.PrefixPaths(c.properties.Include_dirs, ctx.Config().(Config).SrcDir())
434 localIncludeDirs := pathtools.PrefixPaths(c.properties.Local_include_dirs, common.ModuleSrcDir(ctx))
435 flags.includeDirs = append(flags.includeDirs, localIncludeDirs...)
436
437 if !c.properties.No_default_compiler_flags {
438 flags.includeDirs = append(flags.includeDirs, []string{
439 common.ModuleSrcDir(ctx),
440 common.ModuleOutDir(ctx),
441 common.ModuleGenDir(ctx),
442 }...)
443
Colin Crossefd8e482015-03-18 17:17:35 -0700444 if c.properties.Sdk_version == "" {
445 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/libnativehelper/include/nativehelper")
446 }
447
Colin Cross3f40fa42015-01-30 17:27:36 -0800448 if arch.HostOrDevice.Device() && !c.properties.Allow_undefined_symbols {
449 flags.ldFlags = append(flags.ldFlags, "-Wl,--no-undefined")
450 }
451
452 if flags.clang {
Tim Kilbournf2948142015-03-11 12:03:03 -0700453 flags.cppFlags = append(flags.cppFlags, "${commonClangGlobalCppflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800454 flags.globalFlags = []string{
455 "${commonGlobalIncludes}",
456 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700457 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800458 toolchain.ClangCflags(),
459 "${commonClangGlobalCflags}",
460 fmt.Sprintf("${%sClangGlobalCflags}", arch.HostOrDevice),
461 }
462 } else {
Tim Kilbournf2948142015-03-11 12:03:03 -0700463 flags.cppFlags = append(flags.cppFlags, "${commonGlobalCppflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800464 flags.globalFlags = []string{
465 "${commonGlobalIncludes}",
466 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700467 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800468 toolchain.Cflags(),
469 "${commonGlobalCflags}",
470 fmt.Sprintf("${%sGlobalCflags}", arch.HostOrDevice),
471 }
472 }
473
474 if arch.HostOrDevice.Host() {
475 flags.ldFlags = append(flags.ldFlags, c.properties.Host_ldlibs...)
476 }
477
478 if arch.HostOrDevice.Device() {
479 if c.properties.Rtti {
480 flags.cppFlags = append(flags.cppFlags, "-frtti")
481 } else {
482 flags.cppFlags = append(flags.cppFlags, "-fno-rtti")
483 }
484 }
485
486 flags.asFlags = append(flags.asFlags, "-D__ASSEMBLY__")
487
488 if flags.clang {
489 flags.cppFlags = append(flags.cppFlags, toolchain.ClangCppflags())
490 flags.ldFlags = append(flags.ldFlags, toolchain.ClangLdflags())
491 } else {
492 flags.cppFlags = append(flags.cppFlags, toolchain.Cppflags())
493 flags.ldFlags = append(flags.ldFlags, toolchain.Ldflags())
494 }
495 }
496
497 flags.cFlags = append(flags.cFlags, c.ccModuleType().moduleTypeCflags(ctx, toolchain)...)
498 flags.ldFlags = append(flags.ldFlags, c.ccModuleType().moduleTypeLdflags(ctx, toolchain)...)
499
500 // Optimization to reduce size of build.ninja
501 // Replace the long list of flags for each file with a module-local variable
502 ctx.Variable(pctx, "cflags", strings.Join(flags.cFlags, " "))
503 ctx.Variable(pctx, "cppflags", strings.Join(flags.cppFlags, " "))
504 ctx.Variable(pctx, "asflags", strings.Join(flags.asFlags, " "))
505 flags.cFlags = []string{"$cflags"}
506 flags.cppFlags = []string{"$cppflags"}
507 flags.asFlags = []string{"$asflags"}
508
509 return flags
510}
511
512// Modify ccFlags structs with STL library info
513func (c *ccBase) addStlFlags(ctx common.AndroidModuleContext, flags ccFlags) ccFlags {
514 if !c.properties.No_default_compiler_flags {
515 arch := ctx.Arch()
516 stl := "libc++" // TODO: mingw needs libstdc++
517 if c.properties.Stl != "" {
518 stl = c.properties.Stl
519 }
520
521 stlStatic := false
522 if strings.HasSuffix(stl, "_static") {
523 stlStatic = true
524 }
525
526 switch stl {
527 case "libc++", "libc++_static":
528 flags.cFlags = append(flags.cFlags, "-D_USING_LIBCXX")
529 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/external/libcxx/include")
530 if arch.HostOrDevice.Host() {
531 flags.cppFlags = append(flags.cppFlags, "-nostdinc++")
532 flags.ldFlags = append(flags.ldFlags, "-nodefaultlibs")
533 flags.ldLibs = append(flags.ldLibs, "-lc", "-lm", "-lpthread")
534 }
535 if stlStatic {
536 flags.extraStaticLibs = append(flags.extraStaticLibs, "libc++_static")
537 } else {
538 flags.extraSharedLibs = append(flags.extraSharedLibs, "libc++")
539 }
540 case "stlport", "stlport_static":
541 if arch.HostOrDevice.Device() {
542 flags.includeDirs = append(flags.includeDirs,
543 "${SrcDir}/external/stlport/stlport",
544 "${SrcDir}/bionic/libstdc++/include",
545 "${SrcDir}/bionic")
546 if stlStatic {
547 flags.extraStaticLibs = append(flags.extraStaticLibs, "libstdc++", "libstlport_static")
548 } else {
549 flags.extraSharedLibs = append(flags.extraSharedLibs, "libstdc++", "libstlport")
550 }
551 }
552 case "ndk":
553 panic("TODO")
554 case "libstdc++":
555 // Using bionic's basic libstdc++. Not actually an STL. Only around until the
556 // tree is in good enough shape to not need it.
557 // Host builds will use GNU libstdc++.
558 if arch.HostOrDevice.Device() {
559 flags.includeDirs = append(flags.includeDirs, "${SrcDir}/bionic/libstdc++/include")
560 flags.extraSharedLibs = append(flags.extraSharedLibs, "libstdc++")
561 }
562 case "none":
563 if arch.HostOrDevice.Host() {
564 flags.cppFlags = append(flags.cppFlags, "-nostdinc++")
565 flags.ldFlags = append(flags.ldFlags, "-nodefaultlibs")
566 flags.ldLibs = append(flags.ldLibs, "-lc", "-lm")
567 }
568 default:
569 ctx.ModuleErrorf("stl: %q is not a supported STL", stl)
570 }
571
572 }
573 return flags
574}
575
576// Compile a list of source files into objects a specified subdirectory
577func (c *ccBase) customCompileObjs(ctx common.AndroidModuleContext, flags ccFlags,
578 deps ccDeps, subdir string, srcFiles []string) []string {
579
580 srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
581 srcFiles = common.ExpandGlobs(ctx, srcFiles)
582
583 return TransformSourceToObj(ctx, subdir, srcFiles, ccFlagsToBuilderFlags(flags))
584}
585
586// Compile files listed in c.properties.Srcs into objects
587func (c *ccBase) compileObjs(ctx common.AndroidModuleContext, flags ccFlags,
588 deps ccDeps) []string {
589
590 if c.properties.SkipCompileObjs {
591 return nil
592 }
593
594 return c.customCompileObjs(ctx, flags, deps, "", c.properties.Srcs)
595}
596
Colin Cross5049f022015-03-18 13:28:46 -0700597// Compile generated source files from dependencies
598func (c *ccBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags ccFlags,
599 deps ccDeps) []string {
600 var srcs []string
601
602 if c.properties.SkipCompileObjs {
603 return nil
604 }
605
606 ctx.VisitDirectDeps(func(module blueprint.Module) {
607 if gen, ok := module.(genrule.SourceFileGenerator); ok {
608 srcs = append(srcs, gen.GeneratedSourceFiles()...)
609 }
610 })
611
612 if len(srcs) == 0 {
613 return nil
614 }
615
616 return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags))
617}
618
Colin Cross3f40fa42015-01-30 17:27:36 -0800619func (c *ccBase) outputFile() string {
620 return ""
621}
622
623func (c *ccBase) collectDepsFromList(ctx common.AndroidModuleContext,
624 names []string) (modules []common.AndroidModule,
625 outputFiles []string, exportedIncludeDirs []string) {
626
627 for _, n := range names {
628 found := false
629 ctx.VisitDirectDeps(func(m blueprint.Module) {
630 otherName := ctx.OtherModuleName(m)
631 if otherName != n {
632 return
633 }
634
635 if a, ok := m.(ccModuleType); ok {
636 if a.Disabled() {
637 // If a cc_library host+device module depends on a library that exists as both
638 // cc_library_shared and cc_library_host_shared, it will end up with two
639 // dependencies with the same name, one of which is marked disabled for each
640 // of host and device. Ignore the disabled one.
641 return
642 }
643 if a.HostOrDevice() != ctx.Arch().HostOrDevice {
644 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
645 otherName)
646 return
647 }
648
649 if outputFile := a.outputFile(); outputFile != "" {
650 if found {
651 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
652 return
653 }
654 outputFiles = append(outputFiles, outputFile)
655 modules = append(modules, a)
656 if i, ok := a.(ccExportedIncludeDirsProducer); ok {
657 exportedIncludeDirs = append(exportedIncludeDirs, i.exportedIncludeDirs()...)
658 }
659 found = true
660 } else {
661 ctx.ModuleErrorf("module %q missing output file", otherName)
662 return
663 }
664 } else {
665 ctx.ModuleErrorf("module %q not an android module", otherName)
666 return
667 }
668 })
669 if !found {
670 ctx.ModuleErrorf("unsatisified dependency on %q", n)
671 }
672 }
673
674 return modules, outputFiles, exportedIncludeDirs
675}
676
677func (c *ccBase) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
678 var deps ccDeps
679 var newIncludeDirs []string
680
681 wholeStaticLibNames := c.properties.Whole_static_libs
682 _, deps.wholeStaticLibs, newIncludeDirs = c.collectDepsFromList(ctx, wholeStaticLibNames)
683
684 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
685
686 staticLibNames := c.properties.Static_libs
687 staticLibNames = append(staticLibNames, flags.extraStaticLibs...)
688 _, deps.staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
689 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
690
691 return deps, flags
692}
693
694// ccDynamic contains the properties and members used by shared libraries and dynamic executables
695type ccDynamic struct {
696 ccBase
697}
698
Colin Crossc472d572015-03-17 15:06:21 -0700699func newCCDynamic(dynamic *ccDynamic, module ccModuleType, hod common.HostOrDeviceSupported,
700 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
701
702 dynamic.properties.System_shared_libs = []string{defaultSystemSharedLibraries}
703
704 return newCCBase(&dynamic.ccBase, module, hod, multilib, props...)
705}
706
Colin Cross3f40fa42015-01-30 17:27:36 -0800707const defaultSystemSharedLibraries = "__default__"
708
709func (c *ccDynamic) systemSharedLibs() []string {
710
711 if len(c.properties.System_shared_libs) == 1 &&
712 c.properties.System_shared_libs[0] == defaultSystemSharedLibraries {
713
714 if c.HostOrDevice().Host() {
715 return []string{}
716 } else {
717 return []string{"libc", "libm"}
718 }
719 }
720 return c.properties.System_shared_libs
721}
722
723var (
724 stlSharedLibs = []string{"libc++", "libstlport", "libstdc++"}
725 stlSharedHostLibs = []string{"libc++"}
726 stlStaticLibs = []string{"libc++_static", "libstlport_static", "libstdc++"}
727 stlStaticHostLibs = []string{"libc++_static"}
728)
729
730func (c *ccDynamic) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
731 deps := c.ccBase.AndroidDynamicDependencies(ctx)
732
733 if c.HostOrDevice().Device() {
734 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.systemSharedLibs()...)
735 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}},
736 "libcompiler_rt-extras",
Colin Cross77b00fa2015-03-16 16:15:49 -0700737 "libgcov",
Colin Cross3f40fa42015-01-30 17:27:36 -0800738 "libatomic",
739 "libgcc")
740
741 if c.properties.Stl != "none" {
742 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedLibs...)
743 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticLibs...)
744 }
745 } else {
746 if c.properties.Stl != "none" {
747 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedHostLibs...)
748 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticHostLibs...)
749 }
750 }
751
752 return deps
753}
754
Colin Cross3f40fa42015-01-30 17:27:36 -0800755func (c *ccDynamic) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
756 var newIncludeDirs []string
757
758 deps, flags := c.ccBase.collectDeps(ctx, flags)
759
760 systemSharedLibs := c.systemSharedLibs()
761 sharedLibNames := make([]string, 0, len(c.properties.Shared_libs)+len(systemSharedLibs)+
762 len(flags.extraSharedLibs))
763 sharedLibNames = append(sharedLibNames, c.properties.Shared_libs...)
764 sharedLibNames = append(sharedLibNames, systemSharedLibs...)
765 sharedLibNames = append(sharedLibNames, flags.extraSharedLibs...)
766 _, deps.sharedLibs, newIncludeDirs = c.collectDepsFromList(ctx, sharedLibNames)
767 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
768
769 if ctx.Arch().HostOrDevice.Device() {
770 var staticLibs []string
Colin Cross77b00fa2015-03-16 16:15:49 -0700771 staticLibNames := []string{"libcompiler_rt-extras"}
Colin Cross3f40fa42015-01-30 17:27:36 -0800772 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
773 deps.staticLibs = append(deps.staticLibs, staticLibs...)
774 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
Colin Cross77b00fa2015-03-16 16:15:49 -0700775
776 // libgcc and libatomic have to be last on the command line
777 staticLibNames = []string{"libgcov", "libatomic", "libgcc"}
778 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
779 deps.lateStaticLibs = append(deps.lateStaticLibs, staticLibs...)
780 deps.includeDirs = append(deps.includeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800781 }
782
783 ctx.VisitDirectDeps(func(m blueprint.Module) {
784 if obj, ok := m.(*ccObject); ok {
785 otherName := ctx.OtherModuleName(m)
786 if strings.HasPrefix(otherName, "crtbegin") {
787 if !c.properties.Nocrt {
788 deps.crtBegin = obj.outputFile()
789 }
790 } else if strings.HasPrefix(otherName, "crtend") {
791 if !c.properties.Nocrt {
792 deps.crtEnd = obj.outputFile()
793 }
794 } else {
795 ctx.ModuleErrorf("object module type only support for crtbegin and crtend, found %q",
796 ctx.OtherModuleName(m))
797 }
798 }
799 })
800
801 flags.includeDirs = append(flags.includeDirs, deps.includeDirs...)
802
803 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
880 return deps, flags
881 } else if c.libraryProperties.IsShared {
882 return c.ccDynamic.collectDeps(ctx, flags)
883 } else {
884 panic("Not shared or static")
885 }
886}
887
888func (c *ccLibrary) outputFile() string {
889 return c.out
890}
891
892func (c *ccLibrary) allObjFiles() []string {
893 return c.objFiles
894}
895
896func (c *ccLibrary) exportedIncludeDirs() []string {
897 return c.exportIncludeDirs
898}
899
900func (c *ccLibrary) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
901 return []string{"-fPIC"}
902}
903
904func (c *ccLibrary) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
905 if c.libraryProperties.IsShared {
906 libName := ctx.ModuleName()
907 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
908 sharedFlag := "-Wl,-shared"
909 if c.properties.Clang || ctx.Arch().HostOrDevice.Host() {
910 sharedFlag = "-shared"
911 }
912 if ctx.Arch().HostOrDevice.Device() {
913 return []string{
914 "-nostdlib",
915 "-Wl,--gc-sections",
916 sharedFlag,
Colin Cross6072ad42015-03-16 16:22:04 -0700917 "-Wl,-soname," + libName + sharedLibraryExtension,
Colin Cross3f40fa42015-01-30 17:27:36 -0800918 }
919 } else {
920 return []string{
921 "-Wl,--gc-sections",
922 sharedFlag,
Colin Cross6072ad42015-03-16 16:22:04 -0700923 "-Wl,-soname," + libName + sharedLibraryExtension,
Colin Cross3f40fa42015-01-30 17:27:36 -0800924 }
925 }
926 } else {
927 return nil
928 }
929}
930
931func (c *ccLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
932 flags ccFlags, deps ccDeps, objFiles []string) {
933
934 staticFlags := flags
935 staticFlags.cFlags = append(staticFlags.cFlags, c.libraryProperties.Static.Cflags...)
936 objFilesStatic := c.customCompileObjs(ctx, staticFlags, deps, common.DeviceStaticLibrary,
937 c.libraryProperties.Static.Srcs)
938
939 objFiles = append(objFiles, objFilesStatic...)
940
941 var includeDirs []string
942
943 wholeStaticLibNames := c.properties.Whole_static_libs
944 wholeStaticLibs, _, newIncludeDirs := c.collectDepsFromList(ctx, wholeStaticLibNames)
945 includeDirs = append(includeDirs, newIncludeDirs...)
946
947 for _, m := range wholeStaticLibs {
948 if staticLib, ok := m.(*ccLibrary); ok && staticLib.libraryProperties.IsStatic {
949 objFiles = append(objFiles, staticLib.allObjFiles()...)
950 } else {
951 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
952 }
953 }
954
955 staticLibNames := c.properties.Static_libs
956 _, _, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
957 includeDirs = append(includeDirs, newIncludeDirs...)
958
959 ctx.VisitDirectDeps(func(m blueprint.Module) {
960 if obj, ok := m.(*ccObject); ok {
961 otherName := ctx.OtherModuleName(m)
962 if !strings.HasPrefix(otherName, "crtbegin") && !strings.HasPrefix(otherName, "crtend") {
963 objFiles = append(objFiles, obj.outputFile())
964 }
965 }
966 })
967
968 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
969
970 TransformObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
971
972 c.objFiles = objFiles
973 c.out = outputFile
974 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
975 common.ModuleSrcDir(ctx))
976
977 ctx.CheckbuildFile(outputFile)
978}
979
980func (c *ccLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
981 flags ccFlags, deps ccDeps, objFiles []string) {
982
983 sharedFlags := flags
984 sharedFlags.cFlags = append(sharedFlags.cFlags, c.libraryProperties.Shared.Cflags...)
985 objFilesShared := c.customCompileObjs(ctx, sharedFlags, deps, common.DeviceSharedLibrary,
986 c.libraryProperties.Shared.Srcs)
987
988 objFiles = append(objFiles, objFilesShared...)
989
990 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
991
Colin Cross77b00fa2015-03-16 16:15:49 -0700992 TransformObjToDynamicBinary(ctx, objFiles, deps.sharedLibs, deps.staticLibs,
993 deps.lateStaticLibs, deps.wholeStaticLibs, deps.crtBegin, deps.crtEnd,
994 ccFlagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -0800995
996 c.out = outputFile
997 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
998 common.ModuleSrcDir(ctx))
Colin Cross3f40fa42015-01-30 17:27:36 -0800999}
1000
1001func (c *ccLibrary) compileModule(ctx common.AndroidModuleContext,
1002 flags ccFlags, deps ccDeps, objFiles []string) {
1003
1004 // Reuse the object files from the matching static library if it exists
1005 if c.primary == c {
1006 c.primaryObjFiles = objFiles
1007 } else {
1008 objFiles = append([]string(nil), c.primary.primaryObjFiles...)
1009 }
1010
1011 if c.libraryProperties.IsStatic {
1012 c.compileStaticLibrary(ctx, flags, deps, objFiles)
1013 } else {
1014 c.compileSharedLibrary(ctx, flags, deps, objFiles)
1015 }
1016}
1017
Dan Albertc403f7c2015-03-18 14:01:18 -07001018func (c *ccLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
1019 // Static libraries do not get installed.
1020}
1021
1022func (c *ccLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
1023 installDir := "lib"
1024 if flags.toolchain.Is64Bit() {
1025 installDir = "lib64"
1026 }
1027
1028 ctx.InstallFile(installDir, c.out)
1029}
1030
1031func (c *ccLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1032 if c.libraryProperties.IsStatic {
1033 c.installStaticLibrary(ctx, flags)
1034 } else {
1035 c.installSharedLibrary(ctx, flags)
1036 }
1037}
1038
Colin Cross3f40fa42015-01-30 17:27:36 -08001039//
1040// Objects (for crt*.o)
1041//
1042
1043type ccObject struct {
1044 ccBase
1045 out string
1046}
1047
1048func NewCCObject() (blueprint.Module, []interface{}) {
1049 module := &ccObject{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001050
Colin Crossc472d572015-03-17 15:06:21 -07001051 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001052}
1053
1054func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1055 // object files can't have any dynamic dependencies
1056 return nil
1057}
1058
1059func (c *ccObject) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1060 deps, flags := c.ccBase.collectDeps(ctx, flags)
1061 ctx.VisitDirectDeps(func(m blueprint.Module) {
1062 if obj, ok := m.(*ccObject); ok {
1063 deps.objFiles = append(deps.objFiles, obj.outputFile())
1064 } else {
1065 ctx.ModuleErrorf("Unknown module type for dependency %q", ctx.OtherModuleName(m))
1066 }
1067 })
1068
1069 return deps, flags
1070}
1071
1072func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
1073 flags ccFlags, deps ccDeps, objFiles []string) {
1074
1075 objFiles = append(objFiles, deps.objFiles...)
1076
1077 var outputFile string
1078 if len(objFiles) == 1 {
1079 outputFile = objFiles[0]
1080 } else {
1081 outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+".o")
1082 TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1083 }
1084
1085 c.out = outputFile
1086
1087 ctx.CheckbuildFile(outputFile)
1088}
1089
Dan Albertc403f7c2015-03-18 14:01:18 -07001090func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1091 // Object files do not get installed.
1092}
1093
Colin Cross3f40fa42015-01-30 17:27:36 -08001094func (c *ccObject) outputFile() string {
1095 return c.out
1096}
1097
1098//
1099// Executables
1100//
1101
1102type ccBinary struct {
1103 ccDynamic
Dan Albertc403f7c2015-03-18 14:01:18 -07001104 out string
Colin Cross3f40fa42015-01-30 17:27:36 -08001105 binaryProperties binaryProperties
1106}
1107
1108type binaryProperties struct {
1109 // static_executable: compile executable with -static
1110 Static_executable bool
1111
1112 // stem: set the name of the output
1113 Stem string `android:"arch_variant"`
1114
1115 // prefix_symbols: if set, add an extra objcopy --prefix-symbols= step
1116 Prefix_symbols string
1117}
1118
1119func (c *ccBinary) getStem(ctx common.AndroidModuleContext) string {
1120 if c.binaryProperties.Stem != "" {
1121 return c.binaryProperties.Stem
1122 }
1123 return ctx.ModuleName()
1124}
1125
1126func (c *ccBinary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1127 deps := c.ccDynamic.AndroidDynamicDependencies(ctx)
1128 if c.HostOrDevice().Device() {
1129 if c.binaryProperties.Static_executable {
1130 deps = append(deps, "crtbegin_static", "crtend_android")
1131 } else {
1132 deps = append(deps, "crtbegin_dynamic", "crtend_android")
1133 }
1134 }
1135 return deps
1136}
1137
1138func NewCCBinary() (blueprint.Module, []interface{}) {
1139 module := &ccBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001140
Colin Crossc472d572015-03-17 15:06:21 -07001141 return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported, common.MultilibFirst,
1142 &module.binaryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001143}
1144
1145func (c *ccBinary) moduleTypeCflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
1146 return []string{"-fpie"}
1147}
1148
1149func (c *ccBinary) moduleTypeLdflags(ctx common.AndroidModuleContext, toolchain toolchain) []string {
1150 if ctx.Arch().HostOrDevice.Device() {
1151 linker := "/system/bin/linker"
1152 if toolchain.Is64Bit() {
1153 linker = "/system/bin/linker64"
1154 }
1155
1156 return []string{
1157 "-nostdlib",
1158 "-Bdynamic",
1159 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1160 "-Wl,--gc-sections",
1161 "-Wl,-z,nocopyreloc",
1162 }
1163 }
1164
1165 return nil
1166}
1167
1168func (c *ccBinary) compileModule(ctx common.AndroidModuleContext,
1169 flags ccFlags, deps ccDeps, objFiles []string) {
1170
1171 if !c.binaryProperties.Static_executable && inList("libc", c.properties.Static_libs) {
1172 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1173 "from static libs or set static_executable: true")
1174 }
1175
1176 outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
Dan Albertc403f7c2015-03-18 14:01:18 -07001177 c.out = outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001178
Colin Cross77b00fa2015-03-16 16:15:49 -07001179 TransformObjToDynamicBinary(ctx, objFiles, deps.sharedLibs, deps.staticLibs,
1180 deps.lateStaticLibs, deps.wholeStaticLibs, deps.crtBegin, deps.crtEnd,
1181 ccFlagsToBuilderFlags(flags), outputFile)
Dan Albertc403f7c2015-03-18 14:01:18 -07001182}
Colin Cross3f40fa42015-01-30 17:27:36 -08001183
Dan Albertc403f7c2015-03-18 14:01:18 -07001184func (c *ccBinary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1185 ctx.InstallFile("bin", c.out)
1186}
1187
1188type ccTest struct {
1189 ccBinary
1190}
1191
1192var (
1193 gtestLibs = []string{"libgtest", "libgtest_main"}
1194)
1195
1196func (c *ccTest) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1197 deps, flags := c.ccBinary.collectDeps(ctx, flags)
1198
1199 flags.cFlags = append(flags.cFlags, "-DGTEST_HAS_STD_STRING")
1200 if c.HostOrDevice().Host() {
1201 flags.cFlags = append(flags.cFlags, "-O0", "-g")
1202 flags.ldLibs = append(flags.ldLibs, "-lpthread")
1203 }
1204
1205 // TODO(danalbert): Make gtest export its dependencies.
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001206 flags.includeDirs = append(flags.includeDirs,
1207 filepath.Join(ctx.Config().(Config).SrcDir(), "external/gtest/include"))
Dan Albertc403f7c2015-03-18 14:01:18 -07001208
1209 _, staticLibs, _ := c.collectDepsFromList(ctx, gtestLibs)
1210 deps.staticLibs = append(deps.staticLibs, staticLibs...)
1211
1212 return deps, flags
1213}
1214
1215func (c *ccTest) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1216 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, gtestLibs...)
1217 deps := c.ccBinary.AndroidDynamicDependencies(ctx)
1218 return append(deps, gtestLibs...)
1219}
1220
1221func (c *ccTest) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1222 if c.HostOrDevice().Device() {
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001223 ctx.InstallFile("../data/nativetest/"+ctx.ModuleName(), c.out)
Dan Albertc403f7c2015-03-18 14:01:18 -07001224 } else {
1225 c.ccBinary.installModule(ctx, flags)
1226 }
1227}
1228
1229func NewCCTest() (blueprint.Module, []interface{}) {
1230 module := &ccTest{}
1231 return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported,
1232 common.MultilibFirst, &module.binaryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001233}
1234
1235//
1236// Static library
1237//
1238
1239func NewCCLibraryStatic() (blueprint.Module, []interface{}) {
1240 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001241 module.libraryProperties.BuildStatic = true
1242
Colin Crossc472d572015-03-17 15:06:21 -07001243 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001244}
1245
1246//
1247// Shared libraries
1248//
1249
1250func NewCCLibraryShared() (blueprint.Module, []interface{}) {
1251 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001252 module.libraryProperties.BuildShared = true
1253
Colin Crossc472d572015-03-17 15:06:21 -07001254 return newCCLibrary(module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001255}
1256
1257//
1258// Host static library
1259//
1260
1261func NewCCLibraryHostStatic() (blueprint.Module, []interface{}) {
1262 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001263 module.libraryProperties.BuildStatic = true
1264
Colin Crossc472d572015-03-17 15:06:21 -07001265 return newCCLibrary(module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001266}
1267
1268//
1269// Host Shared libraries
1270//
1271
1272func NewCCLibraryHostShared() (blueprint.Module, []interface{}) {
1273 module := &ccLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001274 module.libraryProperties.BuildShared = true
1275
Colin Crossc472d572015-03-17 15:06:21 -07001276 return newCCLibrary(module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001277}
1278
1279//
1280// Host Binaries
1281//
1282
1283func NewCCBinaryHost() (blueprint.Module, []interface{}) {
1284 module := &ccBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001285
Colin Crossc472d572015-03-17 15:06:21 -07001286 return newCCDynamic(&module.ccDynamic, module, common.HostSupported, common.MultilibFirst)
Colin Cross3f40fa42015-01-30 17:27:36 -08001287}
1288
1289//
1290// Device libraries shipped with gcc
1291//
1292
1293type toolchainLibrary struct {
1294 ccLibrary
1295}
1296
1297func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1298 // toolchain libraries can't have any dependencies
1299 return nil
1300}
1301
1302func (*toolchainLibrary) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
1303 // toolchain libraries can't have any dependencies
1304 return ccDeps{}, flags
1305}
1306
1307func NewToolchainLibrary() (blueprint.Module, []interface{}) {
1308 module := &toolchainLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001309
Colin Crossc472d572015-03-17 15:06:21 -07001310 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001311}
1312
1313func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
1314 flags ccFlags, deps ccDeps, objFiles []string) {
1315
1316 libName := ctx.ModuleName() + staticLibraryExtension
1317 outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
1318
1319 CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
1320
1321 c.out = outputFile
1322
1323 ctx.CheckbuildFile(outputFile)
1324}
1325
Dan Albertc403f7c2015-03-18 14:01:18 -07001326func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
1327 // Toolchain libraries do not get installed.
1328}
1329
Colin Cross3f40fa42015-01-30 17:27:36 -08001330func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
1331 if c, ok := mctx.Module().(*ccLibrary); ok {
1332 var modules []blueprint.Module
1333 if c.libraryProperties.BuildStatic && c.libraryProperties.BuildShared {
1334 modules = mctx.CreateLocalVariations("static", "shared")
1335 modules[0].(*ccLibrary).libraryProperties.IsStatic = true
1336 modules[1].(*ccLibrary).libraryProperties.IsShared = true
1337 } else if c.libraryProperties.BuildStatic {
1338 modules = mctx.CreateLocalVariations("static")
1339 modules[0].(*ccLibrary).libraryProperties.IsStatic = true
1340 } else if c.libraryProperties.BuildShared {
1341 modules = mctx.CreateLocalVariations("shared")
1342 modules[0].(*ccLibrary).libraryProperties.IsShared = true
1343 } else {
1344 panic("ccLibrary not static or shared")
1345 }
1346 primary := modules[0].(*ccLibrary)
1347 for _, m := range modules {
1348 m.(*ccLibrary).primary = primary
1349 if m != primary {
1350 m.(*ccLibrary).properties.SkipCompileObjs = true
1351 }
1352 }
1353 } else if _, ok := mctx.Module().(*toolchainLibrary); ok {
1354 mctx.CreateLocalVariations("static")
1355 }
1356}