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