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