blob: 30319a87a37a42686d3b459724f1572531a65863 [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 (
Colin Cross3f40fa42015-01-30 17:27:36 -080022 "fmt"
23 "path/filepath"
24 "strings"
25
Colin Cross97ba0732015-03-23 17:50:24 -070026 "github.com/google/blueprint"
27 "github.com/google/blueprint/pathtools"
28
Colin Cross3f40fa42015-01-30 17:27:36 -080029 "android/soong/common"
Colin Cross5049f022015-03-18 13:28:46 -070030 "android/soong/genrule"
Colin Cross3f40fa42015-01-30 17:27:36 -080031)
32
33type Config interface {
34 SrcDir() string
35 PrebuiltOS() string
36}
37
38var (
39 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", Config.PrebuiltOS)
40 SrcDir = pctx.VariableConfigMethod("SrcDir", Config.SrcDir)
41
42 LibcRoot = pctx.StaticVariable("LibcRoot", "${SrcDir}/bionic/libc")
43 LibmRoot = pctx.StaticVariable("LibmRoot", "${SrcDir}/bionic/libm")
44)
45
46// Flags used by lots of devices. Putting them in package static variables will save bytes in
47// build.ninja so they aren't repeated for every file
48var (
49 commonGlobalCflags = []string{
50 "-DANDROID",
51 "-fmessage-length=0",
52 "-W",
53 "-Wall",
54 "-Wno-unused",
55 "-Winit-self",
56 "-Wpointer-arith",
57
58 // COMMON_RELEASE_CFLAGS
59 "-DNDEBUG",
60 "-UDEBUG",
61 }
62
63 deviceGlobalCflags = []string{
64 // TARGET_ERROR_FLAGS
65 "-Werror=return-type",
66 "-Werror=non-virtual-dtor",
67 "-Werror=address",
68 "-Werror=sequence-point",
69 }
70
71 hostGlobalCflags = []string{}
72
73 commonGlobalCppflags = []string{
74 "-Wsign-promo",
75 "-std=gnu++11",
76 }
77)
78
79func init() {
80 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
81 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
82 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
83
84 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
85
86 pctx.StaticVariable("commonClangGlobalCflags",
87 strings.Join(clangFilterUnknownCflags(commonGlobalCflags), " "))
88 pctx.StaticVariable("deviceClangGlobalCflags",
89 strings.Join(clangFilterUnknownCflags(deviceGlobalCflags), " "))
90 pctx.StaticVariable("hostClangGlobalCflags",
91 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Tim Kilbournf2948142015-03-11 12:03:03 -070092 pctx.StaticVariable("commonClangGlobalCppflags",
93 strings.Join(clangFilterUnknownCflags(commonGlobalCppflags), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -080094
95 // Everything in this list is a crime against abstraction and dependency tracking.
96 // Do not add anything to this list.
97 pctx.StaticVariable("commonGlobalIncludes", strings.Join([]string{
98 "-isystem ${SrcDir}/system/core/include",
99 "-isystem ${SrcDir}/hardware/libhardware/include",
100 "-isystem ${SrcDir}/hardware/libhardware_legacy/include",
101 "-isystem ${SrcDir}/hardware/ril/include",
102 "-isystem ${SrcDir}/libnativehelper/include",
103 "-isystem ${SrcDir}/frameworks/native/include",
104 "-isystem ${SrcDir}/frameworks/native/opengl/include",
105 "-isystem ${SrcDir}/frameworks/av/include",
106 "-isystem ${SrcDir}/frameworks/base/include",
107 }, " "))
108
109 pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/${HostPrebuiltTag}/host/3.6/bin/")
110}
111
Colin Cross97ba0732015-03-23 17:50:24 -0700112// ccProperties describes properties used to compile all C or C++ modules
Colin Cross3f40fa42015-01-30 17:27:36 -0800113type ccProperties struct {
114 // srcs: list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
115 Srcs []string `android:"arch_variant,arch_subtract"`
116
117 // cflags: list of module-specific flags that will be used for C and C++ compiles.
118 Cflags []string `android:"arch_variant"`
119
120 // cppflags: list of module-specific flags that will be used for C++ compiles
121 Cppflags []string `android:"arch_variant"`
122
123 // conlyflags: list of module-specific flags that will be used for C compiles
124 Conlyflags []string `android:"arch_variant"`
125
126 // asflags: list of module-specific flags that will be used for .S compiles
127 Asflags []string `android:"arch_variant"`
128
129 // ldflags: list of module-specific flags that will be used for all link steps
130 Ldflags []string `android:"arch_variant"`
131
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700132 // instruction_set: the instruction set architecture to use to compile the C/C++
133 // module.
134 Instruction_set string `android:"arch_variant"`
135
Colin Cross3f40fa42015-01-30 17:27:36 -0800136 // include_dirs: list of directories relative to the root of the source tree that will
137 // be added to the include path using -I.
138 // If possible, don't use this. If adding paths from the current directory use
139 // local_include_dirs, if adding paths from other modules use export_include_dirs in
140 // that module.
141 Include_dirs []string `android:"arch_variant"`
142
143 // local_include_dirs: list of directories relative to the Blueprints file that will
144 // be added to the include path using -I
145 Local_include_dirs []string `android:"arch_variant"`
146
147 // export_include_dirs: list of directories relative to the Blueprints file that will
148 // be added to the include path using -I for any module that links against this module
149 Export_include_dirs []string
150
151 // clang_cflags: list of module-specific flags that will be used for C and C++ compiles when
152 // compiling with clang
153 Clang_cflags []string `android:"arch_variant"`
154
155 // clang_asflags: list of module-specific flags that will be used for .S compiles when
156 // compiling with clang
157 Clang_asflags []string `android:"arch_variant"`
158
159 // system_shared_libs: list of system libraries that will be dynamically linked to
160 // shared library and executable modules. If unset, generally defaults to libc
161 // and libm. Set to [] to prevent linking against libc and libm.
162 System_shared_libs []string
163
164 // whole_static_libs: list of modules whose object files should be linked into this module
165 // in their entirety. For static library modules, all of the .o files from the intermediate
166 // directory of the dependency will be linked into this modules .a file. For a shared library,
167 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
168 Whole_static_libs []string `android:"arch_variant"`
169
170 // static_libs: list of modules that should be statically linked into this module.
171 Static_libs []string `android:"arch_variant"`
172
173 // shared_libs: list of modules that should be dynamically linked into this module.
174 Shared_libs []string `android:"arch_variant"`
175
176 // allow_undefined_symbols: allow the module to contain undefined symbols. By default,
177 // modules cannot contain undefined symbols that are not satisified by their immediate
178 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
179 // This flag should only be necessary for compiling low-level libraries like libc.
180 Allow_undefined_symbols bool
181
182 // nocrt: don't link in crt_begin and crt_end. This flag should only be necessary for
183 // compiling crt or libc.
184 Nocrt bool `android:"arch_variant"`
185
186 // no_default_compiler_flags: don't insert default compiler flags into asflags, cflags,
187 // cppflags, conlyflags, ldflags, or include_dirs
188 No_default_compiler_flags bool
189
190 // clang: compile module with clang instead of gcc
191 Clang bool `android:"arch_variant"`
192
193 // rtti: pass -frtti instead of -fno-rtti
194 Rtti bool
195
196 // host_ldlibs: -l arguments to pass to linker for host-provided shared libraries
197 Host_ldlibs []string `android:"arch_variant"`
198
199 // stl: select the STL library to use. Possible values are "libc++", "libc++_static",
200 // "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
201 // default
202 Stl string
203
204 // Set for combined shared/static libraries to prevent compiling object files a second time
205 SkipCompileObjs bool `blueprint:"mutated"`
Colin Crossaf19a292015-03-18 12:07:10 -0700206
207 Debug struct {
208 Cflags []string `android:"arch_variant"`
209 } `android:"arch_variant"`
210 Release struct {
211 Cflags []string `android:"arch_variant"`
212 } `android:"arch_variant"`
Colin Crossefd8e482015-03-18 17:17:35 -0700213
214 // Minimum sdk version supported when compiling against the ndk
215 Sdk_version string
Colin Cross3f40fa42015-01-30 17:27:36 -0800216}
217
218type unusedProperties struct {
219 Asan bool
220 Native_coverage bool
221 Strip string
222 Tags []string
223 Required []string
224}
225
226// Building C/C++ code is handled by objects that satisfy this interface via composition
Colin Cross97ba0732015-03-23 17:50:24 -0700227type CCModuleType interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800228 common.AndroidModule
229
Colin Cross97ba0732015-03-23 17:50:24 -0700230 // Modify the ccFlags that are specific to this _type_ of module
231 ModuleTypeFlags(common.AndroidModuleContext, CCFlags) CCFlags
Colin Cross3f40fa42015-01-30 17:27:36 -0800232
233 // Create a ccDeps struct that collects the module dependency info. Can also
234 // modify ccFlags in order to add dependency include directories, etc.
Colin Cross97ba0732015-03-23 17:50:24 -0700235 collectDeps(common.AndroidModuleContext, CCFlags) (CCDeps, CCFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800236
237 // Compile objects into final module
Colin Cross97ba0732015-03-23 17:50:24 -0700238 compileModule(common.AndroidModuleContext, CCFlags, CCDeps, []string)
Colin Cross3f40fa42015-01-30 17:27:36 -0800239
Dan Albertc403f7c2015-03-18 14:01:18 -0700240 // Install the built module.
Colin Cross97ba0732015-03-23 17:50:24 -0700241 installModule(common.AndroidModuleContext, CCFlags)
Dan Albertc403f7c2015-03-18 14:01:18 -0700242
Colin Cross3f40fa42015-01-30 17:27:36 -0800243 // Return the output file (.o, .a or .so) for use by other modules
244 outputFile() string
245}
246
Colin Cross97ba0732015-03-23 17:50:24 -0700247type CCDeps struct {
248 StaticLibs, SharedLibs, LateStaticLibs, WholeStaticLibs, ObjFiles, IncludeDirs []string
Colin Crossc472d572015-03-17 15:06:21 -0700249
Colin Cross97ba0732015-03-23 17:50:24 -0700250 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700251}
252
Colin Cross97ba0732015-03-23 17:50:24 -0700253type CCFlags struct {
254 GlobalFlags []string
255 AsFlags []string
256 CFlags []string
257 ConlyFlags []string
258 CppFlags []string
259 LdFlags []string
260 LdLibs []string
261 IncludeDirs []string
262 Nocrt bool
263 Toolchain Toolchain
264 Clang bool
Colin Crossc472d572015-03-17 15:06:21 -0700265
Colin Cross97ba0732015-03-23 17:50:24 -0700266 ExtraStaticLibs []string
267 ExtraSharedLibs []string
Colin Crossc472d572015-03-17 15:06:21 -0700268}
269
270// ccBase contains the properties and members used by all C/C++ module types, and implements
271// the blueprint.Module interface. It expects to be embedded into an outer specialization struct,
272// and uses a ccModuleType interface to that struct to create the build steps.
273type ccBase struct {
274 common.AndroidModuleBase
Colin Cross97ba0732015-03-23 17:50:24 -0700275 module CCModuleType
Colin Crossc472d572015-03-17 15:06:21 -0700276
277 properties ccProperties
278 unused unusedProperties
279
280 installPath string
281}
282
Colin Cross97ba0732015-03-23 17:50:24 -0700283func newCCBase(base *ccBase, module CCModuleType, hod common.HostOrDeviceSupported,
Colin Crossc472d572015-03-17 15:06:21 -0700284 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
285
286 base.module = module
287
288 props = append(props, &base.properties, &base.unused)
289
Colin Cross5049f022015-03-18 13:28:46 -0700290 return common.InitAndroidArchModule(module, hod, multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700291}
292
Colin Cross3f40fa42015-01-30 17:27:36 -0800293func (c *ccBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
294 toolchain := c.findToolchain(ctx)
295 if ctx.Failed() {
296 return
297 }
298
299 flags := c.flags(ctx, toolchain)
300 if ctx.Failed() {
301 return
302 }
303
304 flags = c.addStlFlags(ctx, flags)
305 if ctx.Failed() {
306 return
307 }
308
309 deps, flags := c.ccModuleType().collectDeps(ctx, flags)
310 if ctx.Failed() {
311 return
312 }
313
Colin Cross97ba0732015-03-23 17:50:24 -0700314 flags.IncludeDirs = append(flags.IncludeDirs, deps.IncludeDirs...)
Colin Crossed9f8682015-03-18 17:17:35 -0700315
Colin Cross3f40fa42015-01-30 17:27:36 -0800316 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
Colin Cross97ba0732015-03-23 17:50:24 -0700339func (c *ccBase) ccModuleType() CCModuleType {
Colin Cross3f40fa42015-01-30 17:27:36 -0800340 return c.module
341}
342
343var _ common.AndroidDynamicDepender = (*ccBase)(nil)
344
Colin Cross97ba0732015-03-23 17:50:24 -0700345func (c *ccBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
Colin Cross3f40fa42015-01-30 17:27:36 -0800346 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 Cross97ba0732015-03-23 17:50:24 -0700355func (c *ccBase) ModuleTypeFlags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
356 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -0800357}
358
359func (c *ccBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
360 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Whole_static_libs...)
361 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, c.properties.Static_libs...)
362 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.properties.Shared_libs...)
363
364 return nil
365}
366
367// Create a ccFlags struct that collects the compile flags from global values,
368// per-target values, module type values, and per-module Blueprints properties
Colin Cross97ba0732015-03-23 17:50:24 -0700369func (c *ccBase) flags(ctx common.AndroidModuleContext, toolchain Toolchain) CCFlags {
Colin Cross3f40fa42015-01-30 17:27:36 -0800370
371 arch := ctx.Arch()
372
Colin Cross97ba0732015-03-23 17:50:24 -0700373 flags := CCFlags{
374 CFlags: c.properties.Cflags,
375 CppFlags: c.properties.Cppflags,
376 ConlyFlags: c.properties.Conlyflags,
377 LdFlags: c.properties.Ldflags,
378 AsFlags: c.properties.Asflags,
379 Nocrt: c.properties.Nocrt,
380 Toolchain: toolchain,
381 Clang: c.properties.Clang,
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 }
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700383 instructionSet := c.properties.Instruction_set
384 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
385 if err != nil {
386 ctx.ModuleErrorf("%s", err)
387 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800388
Colin Crossaf19a292015-03-18 12:07:10 -0700389 // TODO: debug
Colin Cross97ba0732015-03-23 17:50:24 -0700390 flags.CFlags = append(flags.CFlags, c.properties.Release.Cflags...)
Colin Crossaf19a292015-03-18 12:07:10 -0700391
Colin Cross3f40fa42015-01-30 17:27:36 -0800392 if arch.HostOrDevice.Host() {
393 // TODO: allow per-module clang disable for host
Colin Cross97ba0732015-03-23 17:50:24 -0700394 flags.Clang = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800395 }
396
Colin Cross97ba0732015-03-23 17:50:24 -0700397 if flags.Clang {
398 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
399 flags.CFlags = append(flags.CFlags, c.properties.Clang_cflags...)
400 flags.AsFlags = append(flags.AsFlags, c.properties.Clang_asflags...)
401 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
402 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
403 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800404
Colin Cross97ba0732015-03-23 17:50:24 -0700405 flags.CFlags = append(flags.CFlags, "${clangExtraCflags}")
406 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Crossbdd7b1c2015-03-16 16:21:20 -0700407 if arch.HostOrDevice.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -0700408 flags.CFlags = append(flags.CFlags, "${clangExtraTargetCflags}")
Colin Crossbdd7b1c2015-03-16 16:21:20 -0700409 }
410
Colin Cross3f40fa42015-01-30 17:27:36 -0800411 target := "-target " + toolchain.ClangTriple()
412 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
413
Colin Cross97ba0732015-03-23 17:50:24 -0700414 flags.CFlags = append(flags.CFlags, target, gccPrefix)
415 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
416 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800417
418 if arch.HostOrDevice.Host() {
419 gccToolchain := "--gcc-toolchain=" + toolchain.GccRoot()
420 sysroot := "--sysroot=" + filepath.Join(toolchain.GccRoot(), "sysroot")
421
422 // TODO: also need more -B, -L flags to make host builds hermetic
Colin Cross97ba0732015-03-23 17:50:24 -0700423 flags.CFlags = append(flags.CFlags, gccToolchain, sysroot)
424 flags.AsFlags = append(flags.AsFlags, gccToolchain, sysroot)
425 flags.LdFlags = append(flags.LdFlags, gccToolchain, sysroot)
Colin Cross3f40fa42015-01-30 17:27:36 -0800426 }
427 }
428
Colin Cross97ba0732015-03-23 17:50:24 -0700429 flags.IncludeDirs = pathtools.PrefixPaths(c.properties.Include_dirs, ctx.Config().(Config).SrcDir())
Colin Cross3f40fa42015-01-30 17:27:36 -0800430 localIncludeDirs := pathtools.PrefixPaths(c.properties.Local_include_dirs, common.ModuleSrcDir(ctx))
Colin Cross97ba0732015-03-23 17:50:24 -0700431 flags.IncludeDirs = append(flags.IncludeDirs, localIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800432
433 if !c.properties.No_default_compiler_flags {
Colin Cross97ba0732015-03-23 17:50:24 -0700434 flags.IncludeDirs = append(flags.IncludeDirs, []string{
Colin Cross3f40fa42015-01-30 17:27:36 -0800435 common.ModuleSrcDir(ctx),
436 common.ModuleOutDir(ctx),
437 common.ModuleGenDir(ctx),
438 }...)
439
Colin Crossefd8e482015-03-18 17:17:35 -0700440 if c.properties.Sdk_version == "" {
Colin Cross97ba0732015-03-23 17:50:24 -0700441 flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/libnativehelper/include/nativehelper")
Colin Crossefd8e482015-03-18 17:17:35 -0700442 }
443
Colin Cross3f40fa42015-01-30 17:27:36 -0800444 if arch.HostOrDevice.Device() && !c.properties.Allow_undefined_symbols {
Colin Cross97ba0732015-03-23 17:50:24 -0700445 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
Colin Cross3f40fa42015-01-30 17:27:36 -0800446 }
447
Colin Cross97ba0732015-03-23 17:50:24 -0700448 if flags.Clang {
449 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
450 flags.GlobalFlags = []string{
Colin Cross3f40fa42015-01-30 17:27:36 -0800451 "${commonGlobalIncludes}",
452 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700453 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800454 toolchain.ClangCflags(),
455 "${commonClangGlobalCflags}",
456 fmt.Sprintf("${%sClangGlobalCflags}", arch.HostOrDevice),
457 }
458 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700459 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
460 flags.GlobalFlags = []string{
Colin Cross3f40fa42015-01-30 17:27:36 -0800461 "${commonGlobalIncludes}",
462 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700463 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800464 toolchain.Cflags(),
465 "${commonGlobalCflags}",
466 fmt.Sprintf("${%sGlobalCflags}", arch.HostOrDevice),
467 }
468 }
469
470 if arch.HostOrDevice.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -0700471 flags.LdFlags = append(flags.LdFlags, c.properties.Host_ldlibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800472 }
473
474 if arch.HostOrDevice.Device() {
475 if c.properties.Rtti {
Colin Cross97ba0732015-03-23 17:50:24 -0700476 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700478 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800479 }
480 }
481
Colin Cross97ba0732015-03-23 17:50:24 -0700482 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -0800483
Colin Cross97ba0732015-03-23 17:50:24 -0700484 if flags.Clang {
485 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
486 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
Colin Cross3f40fa42015-01-30 17:27:36 -0800487 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700488 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
489 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
Colin Cross3f40fa42015-01-30 17:27:36 -0800490 }
491 }
492
Colin Cross97ba0732015-03-23 17:50:24 -0700493 flags = c.ccModuleType().ModuleTypeFlags(ctx, flags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800494
495 // Optimization to reduce size of build.ninja
496 // Replace the long list of flags for each file with a module-local variable
Colin Cross97ba0732015-03-23 17:50:24 -0700497 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
498 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
499 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
500 flags.CFlags = []string{"$cflags"}
501 flags.CppFlags = []string{"$cppflags"}
502 flags.AsFlags = []string{"$asflags"}
Colin Cross3f40fa42015-01-30 17:27:36 -0800503
504 return flags
505}
506
507// Modify ccFlags structs with STL library info
Colin Cross97ba0732015-03-23 17:50:24 -0700508func (c *ccBase) addStlFlags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Cross3f40fa42015-01-30 17:27:36 -0800509 if !c.properties.No_default_compiler_flags {
510 arch := ctx.Arch()
511 stl := "libc++" // TODO: mingw needs libstdc++
512 if c.properties.Stl != "" {
513 stl = c.properties.Stl
514 }
515
516 stlStatic := false
517 if strings.HasSuffix(stl, "_static") {
518 stlStatic = true
519 }
520
521 switch stl {
522 case "libc++", "libc++_static":
Colin Cross97ba0732015-03-23 17:50:24 -0700523 flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
524 flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/external/libcxx/include")
Colin Cross3f40fa42015-01-30 17:27:36 -0800525 if arch.HostOrDevice.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -0700526 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
527 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
528 flags.LdLibs = append(flags.LdLibs, "-lc", "-lm", "-lpthread")
Colin Cross3f40fa42015-01-30 17:27:36 -0800529 }
530 if stlStatic {
Colin Cross97ba0732015-03-23 17:50:24 -0700531 flags.ExtraStaticLibs = append(flags.ExtraStaticLibs, "libc++_static")
Colin Cross3f40fa42015-01-30 17:27:36 -0800532 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700533 flags.ExtraSharedLibs = append(flags.ExtraSharedLibs, "libc++")
Colin Cross3f40fa42015-01-30 17:27:36 -0800534 }
535 case "stlport", "stlport_static":
536 if arch.HostOrDevice.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -0700537 flags.IncludeDirs = append(flags.IncludeDirs,
Colin Cross3f40fa42015-01-30 17:27:36 -0800538 "${SrcDir}/external/stlport/stlport",
539 "${SrcDir}/bionic/libstdc++/include",
540 "${SrcDir}/bionic")
541 if stlStatic {
Colin Cross97ba0732015-03-23 17:50:24 -0700542 flags.ExtraStaticLibs = append(flags.ExtraStaticLibs, "libstdc++", "libstlport_static")
Colin Cross3f40fa42015-01-30 17:27:36 -0800543 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700544 flags.ExtraSharedLibs = append(flags.ExtraSharedLibs, "libstdc++", "libstlport")
Colin Cross3f40fa42015-01-30 17:27:36 -0800545 }
546 }
547 case "ndk":
548 panic("TODO")
549 case "libstdc++":
550 // Using bionic's basic libstdc++. Not actually an STL. Only around until the
551 // tree is in good enough shape to not need it.
552 // Host builds will use GNU libstdc++.
553 if arch.HostOrDevice.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -0700554 flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/bionic/libstdc++/include")
555 flags.ExtraSharedLibs = append(flags.ExtraSharedLibs, "libstdc++")
Colin Cross3f40fa42015-01-30 17:27:36 -0800556 }
557 case "none":
558 if arch.HostOrDevice.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -0700559 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
560 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
561 flags.LdLibs = append(flags.LdLibs, "-lc", "-lm")
Colin Cross3f40fa42015-01-30 17:27:36 -0800562 }
563 default:
564 ctx.ModuleErrorf("stl: %q is not a supported STL", stl)
565 }
566
567 }
568 return flags
569}
570
571// Compile a list of source files into objects a specified subdirectory
Colin Cross97ba0732015-03-23 17:50:24 -0700572func (c *ccBase) customCompileObjs(ctx common.AndroidModuleContext, flags CCFlags,
573 deps CCDeps, subdir string, srcFiles []string) []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800574
575 srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
576 srcFiles = common.ExpandGlobs(ctx, srcFiles)
577
578 return TransformSourceToObj(ctx, subdir, srcFiles, ccFlagsToBuilderFlags(flags))
579}
580
581// Compile files listed in c.properties.Srcs into objects
Colin Cross97ba0732015-03-23 17:50:24 -0700582func (c *ccBase) compileObjs(ctx common.AndroidModuleContext, flags CCFlags,
583 deps CCDeps) []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800584
585 if c.properties.SkipCompileObjs {
586 return nil
587 }
588
589 return c.customCompileObjs(ctx, flags, deps, "", c.properties.Srcs)
590}
591
Colin Cross5049f022015-03-18 13:28:46 -0700592// Compile generated source files from dependencies
Colin Cross97ba0732015-03-23 17:50:24 -0700593func (c *ccBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags CCFlags,
594 deps CCDeps) []string {
Colin Cross5049f022015-03-18 13:28:46 -0700595 var srcs []string
596
597 if c.properties.SkipCompileObjs {
598 return nil
599 }
600
601 ctx.VisitDirectDeps(func(module blueprint.Module) {
602 if gen, ok := module.(genrule.SourceFileGenerator); ok {
603 srcs = append(srcs, gen.GeneratedSourceFiles()...)
604 }
605 })
606
607 if len(srcs) == 0 {
608 return nil
609 }
610
611 return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags))
612}
613
Colin Cross3f40fa42015-01-30 17:27:36 -0800614func (c *ccBase) outputFile() string {
615 return ""
616}
617
618func (c *ccBase) collectDepsFromList(ctx common.AndroidModuleContext,
619 names []string) (modules []common.AndroidModule,
620 outputFiles []string, exportedIncludeDirs []string) {
621
622 for _, n := range names {
623 found := false
624 ctx.VisitDirectDeps(func(m blueprint.Module) {
625 otherName := ctx.OtherModuleName(m)
626 if otherName != n {
627 return
628 }
629
Colin Cross97ba0732015-03-23 17:50:24 -0700630 if a, ok := m.(CCModuleType); ok {
Colin Cross3f40fa42015-01-30 17:27:36 -0800631 if a.Disabled() {
632 // If a cc_library host+device module depends on a library that exists as both
633 // cc_library_shared and cc_library_host_shared, it will end up with two
634 // dependencies with the same name, one of which is marked disabled for each
635 // of host and device. Ignore the disabled one.
636 return
637 }
638 if a.HostOrDevice() != ctx.Arch().HostOrDevice {
639 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
640 otherName)
641 return
642 }
643
644 if outputFile := a.outputFile(); outputFile != "" {
645 if found {
646 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
647 return
648 }
649 outputFiles = append(outputFiles, outputFile)
650 modules = append(modules, a)
651 if i, ok := a.(ccExportedIncludeDirsProducer); ok {
652 exportedIncludeDirs = append(exportedIncludeDirs, i.exportedIncludeDirs()...)
653 }
654 found = true
655 } else {
656 ctx.ModuleErrorf("module %q missing output file", otherName)
657 return
658 }
659 } else {
660 ctx.ModuleErrorf("module %q not an android module", otherName)
661 return
662 }
663 })
664 if !found {
665 ctx.ModuleErrorf("unsatisified dependency on %q", n)
666 }
667 }
668
669 return modules, outputFiles, exportedIncludeDirs
670}
671
Colin Cross97ba0732015-03-23 17:50:24 -0700672func (c *ccBase) collectDeps(ctx common.AndroidModuleContext, flags CCFlags) (CCDeps, CCFlags) {
673 var deps CCDeps
Colin Cross3f40fa42015-01-30 17:27:36 -0800674 var newIncludeDirs []string
675
676 wholeStaticLibNames := c.properties.Whole_static_libs
Colin Cross97ba0732015-03-23 17:50:24 -0700677 _, deps.WholeStaticLibs, newIncludeDirs = c.collectDepsFromList(ctx, wholeStaticLibNames)
Colin Cross3f40fa42015-01-30 17:27:36 -0800678
Colin Cross97ba0732015-03-23 17:50:24 -0700679 deps.IncludeDirs = append(deps.IncludeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800680
681 staticLibNames := c.properties.Static_libs
Colin Cross97ba0732015-03-23 17:50:24 -0700682 staticLibNames = append(staticLibNames, flags.ExtraStaticLibs...)
683 _, deps.StaticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
684 deps.IncludeDirs = append(deps.IncludeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800685
686 return deps, flags
687}
688
689// ccDynamic contains the properties and members used by shared libraries and dynamic executables
690type ccDynamic struct {
691 ccBase
692}
693
Colin Cross97ba0732015-03-23 17:50:24 -0700694func newCCDynamic(dynamic *ccDynamic, module CCModuleType, hod common.HostOrDeviceSupported,
Colin Crossc472d572015-03-17 15:06:21 -0700695 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
696
697 dynamic.properties.System_shared_libs = []string{defaultSystemSharedLibraries}
698
699 return newCCBase(&dynamic.ccBase, module, hod, multilib, props...)
700}
701
Colin Cross3f40fa42015-01-30 17:27:36 -0800702const defaultSystemSharedLibraries = "__default__"
703
704func (c *ccDynamic) systemSharedLibs() []string {
705
706 if len(c.properties.System_shared_libs) == 1 &&
707 c.properties.System_shared_libs[0] == defaultSystemSharedLibraries {
708
709 if c.HostOrDevice().Host() {
710 return []string{}
711 } else {
712 return []string{"libc", "libm"}
713 }
714 }
715 return c.properties.System_shared_libs
716}
717
718var (
719 stlSharedLibs = []string{"libc++", "libstlport", "libstdc++"}
720 stlSharedHostLibs = []string{"libc++"}
721 stlStaticLibs = []string{"libc++_static", "libstlport_static", "libstdc++"}
722 stlStaticHostLibs = []string{"libc++_static"}
723)
724
725func (c *ccDynamic) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
726 deps := c.ccBase.AndroidDynamicDependencies(ctx)
727
728 if c.HostOrDevice().Device() {
729 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.systemSharedLibs()...)
730 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}},
731 "libcompiler_rt-extras",
Colin Cross77b00fa2015-03-16 16:15:49 -0700732 "libgcov",
Colin Cross3f40fa42015-01-30 17:27:36 -0800733 "libatomic",
734 "libgcc")
735
736 if c.properties.Stl != "none" {
737 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedLibs...)
738 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticLibs...)
739 }
740 } else {
741 if c.properties.Stl != "none" {
742 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, stlSharedHostLibs...)
743 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, stlStaticHostLibs...)
744 }
745 }
746
747 return deps
748}
749
Colin Cross97ba0732015-03-23 17:50:24 -0700750func (c *ccDynamic) collectDeps(ctx common.AndroidModuleContext, flags CCFlags) (CCDeps, CCFlags) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800751 var newIncludeDirs []string
752
753 deps, flags := c.ccBase.collectDeps(ctx, flags)
754
755 systemSharedLibs := c.systemSharedLibs()
756 sharedLibNames := make([]string, 0, len(c.properties.Shared_libs)+len(systemSharedLibs)+
Colin Cross97ba0732015-03-23 17:50:24 -0700757 len(flags.ExtraSharedLibs))
Colin Cross3f40fa42015-01-30 17:27:36 -0800758 sharedLibNames = append(sharedLibNames, c.properties.Shared_libs...)
759 sharedLibNames = append(sharedLibNames, systemSharedLibs...)
Colin Cross97ba0732015-03-23 17:50:24 -0700760 sharedLibNames = append(sharedLibNames, flags.ExtraSharedLibs...)
761 _, deps.SharedLibs, newIncludeDirs = c.collectDepsFromList(ctx, sharedLibNames)
762 deps.IncludeDirs = append(deps.IncludeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800763
764 if ctx.Arch().HostOrDevice.Device() {
765 var staticLibs []string
Colin Cross77b00fa2015-03-16 16:15:49 -0700766 staticLibNames := []string{"libcompiler_rt-extras"}
Colin Cross3f40fa42015-01-30 17:27:36 -0800767 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
Colin Cross97ba0732015-03-23 17:50:24 -0700768 deps.StaticLibs = append(deps.StaticLibs, staticLibs...)
769 deps.IncludeDirs = append(deps.IncludeDirs, newIncludeDirs...)
Colin Cross77b00fa2015-03-16 16:15:49 -0700770
771 // libgcc and libatomic have to be last on the command line
772 staticLibNames = []string{"libgcov", "libatomic", "libgcc"}
773 _, staticLibs, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
Colin Cross97ba0732015-03-23 17:50:24 -0700774 deps.LateStaticLibs = append(deps.LateStaticLibs, staticLibs...)
775 deps.IncludeDirs = append(deps.IncludeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800776 }
777
778 ctx.VisitDirectDeps(func(m blueprint.Module) {
779 if obj, ok := m.(*ccObject); ok {
780 otherName := ctx.OtherModuleName(m)
781 if strings.HasPrefix(otherName, "crtbegin") {
782 if !c.properties.Nocrt {
Colin Cross97ba0732015-03-23 17:50:24 -0700783 deps.CrtBegin = obj.outputFile()
Colin Cross3f40fa42015-01-30 17:27:36 -0800784 }
785 } else if strings.HasPrefix(otherName, "crtend") {
786 if !c.properties.Nocrt {
Colin Cross97ba0732015-03-23 17:50:24 -0700787 deps.CrtEnd = obj.outputFile()
Colin Cross3f40fa42015-01-30 17:27:36 -0800788 }
789 } else {
790 ctx.ModuleErrorf("object module type only support for crtbegin and crtend, found %q",
791 ctx.OtherModuleName(m))
792 }
793 }
794 })
795
Colin Cross3f40fa42015-01-30 17:27:36 -0800796 return deps, flags
797}
798
799type ccExportedIncludeDirsProducer interface {
800 exportedIncludeDirs() []string
801}
802
803//
804// Combined static+shared libraries
805//
806
Colin Cross97ba0732015-03-23 17:50:24 -0700807type CCLibrary struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800808 ccDynamic
809
Colin Cross97ba0732015-03-23 17:50:24 -0700810 primary *CCLibrary
Colin Cross3f40fa42015-01-30 17:27:36 -0800811 primaryObjFiles []string
812 objFiles []string
813 exportIncludeDirs []string
814 out string
815
Colin Cross97ba0732015-03-23 17:50:24 -0700816 LibraryProperties struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800817 BuildStatic bool `blueprint:"mutated"`
818 BuildShared bool `blueprint:"mutated"`
819 IsShared bool `blueprint:"mutated"`
820 IsStatic bool `blueprint:"mutated"`
821
822 Static struct {
823 Srcs []string `android:"arch_variant"`
824 Cflags []string `android:"arch_variant"`
825 } `android:"arch_variant"`
826 Shared struct {
827 Srcs []string `android:"arch_variant"`
828 Cflags []string `android:"arch_variant"`
829 } `android:"arch_variant"`
830 }
831}
832
Colin Cross97ba0732015-03-23 17:50:24 -0700833type ccLibraryInterface interface {
834 ccLibrary() *CCLibrary
835 static() bool
836 shared() bool
837 allObjFiles() []string
Colin Crossc472d572015-03-17 15:06:21 -0700838}
839
Colin Cross97ba0732015-03-23 17:50:24 -0700840func (c *CCLibrary) ccLibrary() *CCLibrary {
841 return c
Colin Cross3f40fa42015-01-30 17:27:36 -0800842}
843
Colin Cross97ba0732015-03-23 17:50:24 -0700844func (c *CCLibrary) static() bool {
845 return c.LibraryProperties.IsStatic
846}
847
848func (c *CCLibrary) shared() bool {
849 return c.LibraryProperties.IsShared
850}
851
852func NewCCLibrary(library *CCLibrary, module CCModuleType,
853 hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
854
855 return newCCDynamic(&library.ccDynamic, module, hod, common.MultilibBoth,
856 &library.LibraryProperties)
857}
858
859func CCLibraryFactory() (blueprint.Module, []interface{}) {
860 module := &CCLibrary{}
861
862 module.LibraryProperties.BuildShared = true
863 module.LibraryProperties.BuildStatic = true
864
865 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
866}
867
868func (c *CCLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
869 if c.LibraryProperties.IsShared {
Colin Cross3f40fa42015-01-30 17:27:36 -0800870 deps := c.ccDynamic.AndroidDynamicDependencies(ctx)
871 if c.HostOrDevice().Device() {
872 deps = append(deps, "crtbegin_so", "crtend_so")
873 }
874 return deps
875 } else {
876 return c.ccBase.AndroidDynamicDependencies(ctx)
877 }
878}
879
Colin Cross97ba0732015-03-23 17:50:24 -0700880func (c *CCLibrary) collectDeps(ctx common.AndroidModuleContext, flags CCFlags) (CCDeps, CCFlags) {
881 if c.LibraryProperties.IsStatic {
Colin Cross3f40fa42015-01-30 17:27:36 -0800882 deps, flags := c.ccBase.collectDeps(ctx, flags)
883 wholeStaticLibNames := c.properties.Whole_static_libs
884 wholeStaticLibs, _, _ := c.collectDepsFromList(ctx, wholeStaticLibNames)
885
886 for _, m := range wholeStaticLibs {
Colin Cross97ba0732015-03-23 17:50:24 -0700887 if staticLib, ok := m.(ccLibraryInterface); ok && staticLib.static() {
888 deps.ObjFiles = append(deps.ObjFiles, staticLib.allObjFiles()...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800889 } else {
890 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
891 }
892 }
893
Colin Crossed9f8682015-03-18 17:17:35 -0700894 // Collect exported includes from shared lib dependencies
895 sharedLibNames := c.properties.Shared_libs
896 _, _, newIncludeDirs := c.collectDepsFromList(ctx, sharedLibNames)
Colin Cross97ba0732015-03-23 17:50:24 -0700897 deps.IncludeDirs = append(deps.IncludeDirs, newIncludeDirs...)
Colin Crossed9f8682015-03-18 17:17:35 -0700898
Colin Cross3f40fa42015-01-30 17:27:36 -0800899 return deps, flags
Colin Cross97ba0732015-03-23 17:50:24 -0700900 } else if c.LibraryProperties.IsShared {
Colin Cross3f40fa42015-01-30 17:27:36 -0800901 return c.ccDynamic.collectDeps(ctx, flags)
902 } else {
903 panic("Not shared or static")
904 }
905}
906
Colin Cross97ba0732015-03-23 17:50:24 -0700907func (c *CCLibrary) outputFile() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800908 return c.out
909}
910
Colin Cross97ba0732015-03-23 17:50:24 -0700911func (c *CCLibrary) allObjFiles() []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800912 return c.objFiles
913}
914
Colin Cross97ba0732015-03-23 17:50:24 -0700915func (c *CCLibrary) exportedIncludeDirs() []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800916 return c.exportIncludeDirs
917}
918
Colin Cross97ba0732015-03-23 17:50:24 -0700919func (c *CCLibrary) ModuleTypeFlags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
920 flags.CFlags = append(flags.CFlags, "-fPIC")
Colin Cross3f40fa42015-01-30 17:27:36 -0800921
Colin Cross97ba0732015-03-23 17:50:24 -0700922 if c.LibraryProperties.IsShared {
Colin Cross3f40fa42015-01-30 17:27:36 -0800923 libName := ctx.ModuleName()
924 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
925 sharedFlag := "-Wl,-shared"
926 if c.properties.Clang || ctx.Arch().HostOrDevice.Host() {
927 sharedFlag = "-shared"
928 }
929 if ctx.Arch().HostOrDevice.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -0700930 flags.LdFlags = append(flags.LdFlags, "-nostdlib")
Colin Cross3f40fa42015-01-30 17:27:36 -0800931 }
Colin Cross97ba0732015-03-23 17:50:24 -0700932
933 flags.LdFlags = append(flags.LdFlags,
934 "-Wl,--gc-sections",
935 sharedFlag,
936 "-Wl,-soname,"+libName+sharedLibraryExtension,
937 )
Colin Cross3f40fa42015-01-30 17:27:36 -0800938 }
Colin Cross97ba0732015-03-23 17:50:24 -0700939
940 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -0800941}
942
Colin Cross97ba0732015-03-23 17:50:24 -0700943func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
944 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800945
946 staticFlags := flags
Colin Cross97ba0732015-03-23 17:50:24 -0700947 staticFlags.CFlags = append(staticFlags.CFlags, c.LibraryProperties.Static.Cflags...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800948 objFilesStatic := c.customCompileObjs(ctx, staticFlags, deps, common.DeviceStaticLibrary,
Colin Cross97ba0732015-03-23 17:50:24 -0700949 c.LibraryProperties.Static.Srcs)
Colin Cross3f40fa42015-01-30 17:27:36 -0800950
951 objFiles = append(objFiles, objFilesStatic...)
952
953 var includeDirs []string
954
955 wholeStaticLibNames := c.properties.Whole_static_libs
956 wholeStaticLibs, _, newIncludeDirs := c.collectDepsFromList(ctx, wholeStaticLibNames)
957 includeDirs = append(includeDirs, newIncludeDirs...)
958
959 for _, m := range wholeStaticLibs {
Colin Cross97ba0732015-03-23 17:50:24 -0700960 if staticLib, ok := m.(ccLibraryInterface); ok && staticLib.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800961 objFiles = append(objFiles, staticLib.allObjFiles()...)
962 } else {
963 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
964 }
965 }
966
967 staticLibNames := c.properties.Static_libs
968 _, _, newIncludeDirs = c.collectDepsFromList(ctx, staticLibNames)
969 includeDirs = append(includeDirs, newIncludeDirs...)
970
971 ctx.VisitDirectDeps(func(m blueprint.Module) {
972 if obj, ok := m.(*ccObject); ok {
973 otherName := ctx.OtherModuleName(m)
974 if !strings.HasPrefix(otherName, "crtbegin") && !strings.HasPrefix(otherName, "crtend") {
975 objFiles = append(objFiles, obj.outputFile())
976 }
977 }
978 })
979
980 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
981
982 TransformObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
983
984 c.objFiles = objFiles
985 c.out = outputFile
986 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
987 common.ModuleSrcDir(ctx))
988
989 ctx.CheckbuildFile(outputFile)
990}
991
Colin Cross97ba0732015-03-23 17:50:24 -0700992func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
993 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800994
995 sharedFlags := flags
Colin Cross97ba0732015-03-23 17:50:24 -0700996 sharedFlags.CFlags = append(sharedFlags.CFlags, c.LibraryProperties.Shared.Cflags...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800997 objFilesShared := c.customCompileObjs(ctx, sharedFlags, deps, common.DeviceSharedLibrary,
Colin Cross97ba0732015-03-23 17:50:24 -0700998 c.LibraryProperties.Shared.Srcs)
Colin Cross3f40fa42015-01-30 17:27:36 -0800999
1000 objFiles = append(objFiles, objFilesShared...)
1001
1002 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
1003
Colin Cross97ba0732015-03-23 17:50:24 -07001004 TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
1005 deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd,
Colin Cross77b00fa2015-03-16 16:15:49 -07001006 ccFlagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001007
1008 c.out = outputFile
1009 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
1010 common.ModuleSrcDir(ctx))
Colin Cross3f40fa42015-01-30 17:27:36 -08001011}
1012
Colin Cross97ba0732015-03-23 17:50:24 -07001013func (c *CCLibrary) compileModule(ctx common.AndroidModuleContext,
1014 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001015
1016 // Reuse the object files from the matching static library if it exists
1017 if c.primary == c {
1018 c.primaryObjFiles = objFiles
1019 } else {
1020 objFiles = append([]string(nil), c.primary.primaryObjFiles...)
1021 }
1022
Colin Cross97ba0732015-03-23 17:50:24 -07001023 if c.LibraryProperties.IsStatic {
Colin Cross3f40fa42015-01-30 17:27:36 -08001024 c.compileStaticLibrary(ctx, flags, deps, objFiles)
1025 } else {
1026 c.compileSharedLibrary(ctx, flags, deps, objFiles)
1027 }
1028}
1029
Colin Cross97ba0732015-03-23 17:50:24 -07001030func (c *CCLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001031 // Static libraries do not get installed.
1032}
1033
Colin Cross97ba0732015-03-23 17:50:24 -07001034func (c *CCLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001035 installDir := "lib"
Colin Cross97ba0732015-03-23 17:50:24 -07001036 if flags.Toolchain.Is64Bit() {
Dan Albertc403f7c2015-03-18 14:01:18 -07001037 installDir = "lib64"
1038 }
1039
1040 ctx.InstallFile(installDir, c.out)
1041}
1042
Colin Cross97ba0732015-03-23 17:50:24 -07001043func (c *CCLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
1044 if c.LibraryProperties.IsStatic {
Dan Albertc403f7c2015-03-18 14:01:18 -07001045 c.installStaticLibrary(ctx, flags)
1046 } else {
1047 c.installSharedLibrary(ctx, flags)
1048 }
1049}
1050
Colin Cross3f40fa42015-01-30 17:27:36 -08001051//
1052// Objects (for crt*.o)
1053//
1054
1055type ccObject struct {
1056 ccBase
1057 out string
1058}
1059
Colin Cross97ba0732015-03-23 17:50:24 -07001060func CCObjectFactory() (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001061 module := &ccObject{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001062
Colin Crossc472d572015-03-17 15:06:21 -07001063 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001064}
1065
1066func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1067 // object files can't have any dynamic dependencies
1068 return nil
1069}
1070
Colin Cross97ba0732015-03-23 17:50:24 -07001071func (c *ccObject) collectDeps(ctx common.AndroidModuleContext, flags CCFlags) (CCDeps, CCFlags) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001072 deps, flags := c.ccBase.collectDeps(ctx, flags)
1073 ctx.VisitDirectDeps(func(m blueprint.Module) {
1074 if obj, ok := m.(*ccObject); ok {
Colin Cross97ba0732015-03-23 17:50:24 -07001075 deps.ObjFiles = append(deps.ObjFiles, obj.outputFile())
Colin Cross3f40fa42015-01-30 17:27:36 -08001076 } else {
1077 ctx.ModuleErrorf("Unknown module type for dependency %q", ctx.OtherModuleName(m))
1078 }
1079 })
1080
1081 return deps, flags
1082}
1083
1084func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
Colin Cross97ba0732015-03-23 17:50:24 -07001085 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001086
Colin Cross97ba0732015-03-23 17:50:24 -07001087 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001088
1089 var outputFile string
1090 if len(objFiles) == 1 {
1091 outputFile = objFiles[0]
1092 } else {
1093 outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+".o")
1094 TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1095 }
1096
1097 c.out = outputFile
1098
1099 ctx.CheckbuildFile(outputFile)
1100}
1101
Colin Cross97ba0732015-03-23 17:50:24 -07001102func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001103 // Object files do not get installed.
1104}
1105
Colin Cross3f40fa42015-01-30 17:27:36 -08001106func (c *ccObject) outputFile() string {
1107 return c.out
1108}
1109
1110//
1111// Executables
1112//
1113
Colin Cross97ba0732015-03-23 17:50:24 -07001114type CCBinary struct {
Colin Cross3f40fa42015-01-30 17:27:36 -08001115 ccDynamic
Dan Albertc403f7c2015-03-18 14:01:18 -07001116 out string
Colin Cross97ba0732015-03-23 17:50:24 -07001117 BinaryProperties struct {
1118 // static_executable: compile executable with -static
1119 Static_executable bool
1120
1121 // stem: set the name of the output
1122 Stem string `android:"arch_variant"`
1123
1124 // prefix_symbols: if set, add an extra objcopy --prefix-symbols= step
1125 Prefix_symbols string
1126 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001127}
1128
Colin Cross97ba0732015-03-23 17:50:24 -07001129func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
1130 if c.BinaryProperties.Stem != "" {
1131 return c.BinaryProperties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001132 }
1133 return ctx.ModuleName()
1134}
1135
Colin Cross97ba0732015-03-23 17:50:24 -07001136func (c *CCBinary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
Colin Cross3f40fa42015-01-30 17:27:36 -08001137 deps := c.ccDynamic.AndroidDynamicDependencies(ctx)
1138 if c.HostOrDevice().Device() {
Colin Cross97ba0732015-03-23 17:50:24 -07001139 if c.BinaryProperties.Static_executable {
Colin Cross3f40fa42015-01-30 17:27:36 -08001140 deps = append(deps, "crtbegin_static", "crtend_android")
1141 } else {
1142 deps = append(deps, "crtbegin_dynamic", "crtend_android")
1143 }
1144 }
1145 return deps
1146}
1147
Colin Cross97ba0732015-03-23 17:50:24 -07001148func NewCCBinary(binary *CCBinary, module CCModuleType,
1149 hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001150
Colin Cross97ba0732015-03-23 17:50:24 -07001151 return newCCDynamic(&binary.ccDynamic, module, hod, common.MultilibFirst,
1152 &binary.BinaryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001153}
1154
Colin Cross97ba0732015-03-23 17:50:24 -07001155func CCBinaryFactory() (blueprint.Module, []interface{}) {
1156 module := &CCBinary{}
1157
1158 return NewCCBinary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001159}
1160
Colin Cross97ba0732015-03-23 17:50:24 -07001161func (c *CCBinary) ModuleTypeFlags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
1162 flags.CFlags = append(flags.CFlags, "-fpie")
1163
Colin Cross3f40fa42015-01-30 17:27:36 -08001164 if ctx.Arch().HostOrDevice.Device() {
1165 linker := "/system/bin/linker"
Colin Cross97ba0732015-03-23 17:50:24 -07001166 if flags.Toolchain.Is64Bit() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001167 linker = "/system/bin/linker64"
1168 }
1169
Colin Cross97ba0732015-03-23 17:50:24 -07001170 flags.LdFlags = append(flags.LdFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001171 "-nostdlib",
1172 "-Bdynamic",
1173 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1174 "-Wl,--gc-sections",
1175 "-Wl,-z,nocopyreloc",
Colin Cross97ba0732015-03-23 17:50:24 -07001176 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001177 }
1178
Colin Cross97ba0732015-03-23 17:50:24 -07001179 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001180}
1181
Colin Cross97ba0732015-03-23 17:50:24 -07001182func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
1183 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001184
Colin Cross97ba0732015-03-23 17:50:24 -07001185 if !c.BinaryProperties.Static_executable && inList("libc", c.properties.Static_libs) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001186 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1187 "from static libs or set static_executable: true")
1188 }
1189
1190 outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
Dan Albertc403f7c2015-03-18 14:01:18 -07001191 c.out = outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001192
Colin Cross97ba0732015-03-23 17:50:24 -07001193 TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
1194 deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd,
Colin Cross77b00fa2015-03-16 16:15:49 -07001195 ccFlagsToBuilderFlags(flags), outputFile)
Dan Albertc403f7c2015-03-18 14:01:18 -07001196}
Colin Cross3f40fa42015-01-30 17:27:36 -08001197
Colin Cross97ba0732015-03-23 17:50:24 -07001198func (c *CCBinary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001199 ctx.InstallFile("bin", c.out)
1200}
1201
1202type ccTest struct {
Colin Cross97ba0732015-03-23 17:50:24 -07001203 CCBinary
Colin Cross6b290692015-03-19 14:05:33 -07001204
1205 testProperties struct {
1206 // test_per_src: Create a separate test for each source file. Useful when there is
1207 // global state that can not be torn down and reset between each test suite.
1208 Test_per_src bool
1209 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001210}
1211
1212var (
1213 gtestLibs = []string{"libgtest", "libgtest_main"}
1214)
1215
Colin Cross97ba0732015-03-23 17:50:24 -07001216func (c *ccTest) collectDeps(ctx common.AndroidModuleContext, flags CCFlags) (CCDeps, CCFlags) {
1217 deps, flags := c.CCBinary.collectDeps(ctx, flags)
Dan Albertc403f7c2015-03-18 14:01:18 -07001218
Colin Cross97ba0732015-03-23 17:50:24 -07001219 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Dan Albertc403f7c2015-03-18 14:01:18 -07001220 if c.HostOrDevice().Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001221 flags.CFlags = append(flags.CFlags, "-O0", "-g")
1222 flags.LdLibs = append(flags.LdLibs, "-lpthread")
Dan Albertc403f7c2015-03-18 14:01:18 -07001223 }
1224
1225 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross97ba0732015-03-23 17:50:24 -07001226 flags.IncludeDirs = append(flags.IncludeDirs,
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001227 filepath.Join(ctx.Config().(Config).SrcDir(), "external/gtest/include"))
Dan Albertc403f7c2015-03-18 14:01:18 -07001228
1229 _, staticLibs, _ := c.collectDepsFromList(ctx, gtestLibs)
Colin Cross97ba0732015-03-23 17:50:24 -07001230 deps.StaticLibs = append(deps.StaticLibs, staticLibs...)
Dan Albertc403f7c2015-03-18 14:01:18 -07001231
1232 return deps, flags
1233}
1234
1235func (c *ccTest) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1236 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, gtestLibs...)
Colin Cross97ba0732015-03-23 17:50:24 -07001237 deps := c.CCBinary.AndroidDynamicDependencies(ctx)
Dan Albertc403f7c2015-03-18 14:01:18 -07001238 return append(deps, gtestLibs...)
1239}
1240
Colin Cross97ba0732015-03-23 17:50:24 -07001241func (c *ccTest) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001242 if c.HostOrDevice().Device() {
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001243 ctx.InstallFile("../data/nativetest/"+ctx.ModuleName(), c.out)
Dan Albertc403f7c2015-03-18 14:01:18 -07001244 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001245 c.CCBinary.installModule(ctx, flags)
Dan Albertc403f7c2015-03-18 14:01:18 -07001246 }
1247}
1248
Colin Cross97ba0732015-03-23 17:50:24 -07001249func CCTestFactory() (blueprint.Module, []interface{}) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001250 module := &ccTest{}
1251 return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported,
Colin Cross97ba0732015-03-23 17:50:24 -07001252 common.MultilibFirst, &module.BinaryProperties, &module.testProperties)
Colin Cross6b290692015-03-19 14:05:33 -07001253}
1254
1255func TestPerSrcMutator(mctx blueprint.EarlyMutatorContext) {
1256 if test, ok := mctx.Module().(*ccTest); ok {
1257 if test.testProperties.Test_per_src {
1258 testNames := make([]string, len(test.properties.Srcs))
1259 for i, src := range test.properties.Srcs {
1260 testNames[i] = strings.TrimSuffix(src, filepath.Ext(src))
1261 }
1262 tests := mctx.CreateLocalVariations(testNames...)
1263 for i, src := range test.properties.Srcs {
1264 tests[i].(*ccTest).properties.Srcs = []string{src}
Colin Cross97ba0732015-03-23 17:50:24 -07001265 tests[i].(*ccTest).BinaryProperties.Stem = testNames[i]
Colin Cross6b290692015-03-19 14:05:33 -07001266 }
1267 }
1268 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001269}
1270
1271//
1272// Static library
1273//
1274
Colin Cross97ba0732015-03-23 17:50:24 -07001275func CCLibraryStaticFactory() (blueprint.Module, []interface{}) {
1276 module := &CCLibrary{}
1277 module.LibraryProperties.BuildStatic = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001278
Colin Cross97ba0732015-03-23 17:50:24 -07001279 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001280}
1281
1282//
1283// Shared libraries
1284//
1285
Colin Cross97ba0732015-03-23 17:50:24 -07001286func CCLibrarySharedFactory() (blueprint.Module, []interface{}) {
1287 module := &CCLibrary{}
1288 module.LibraryProperties.BuildShared = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001289
Colin Cross97ba0732015-03-23 17:50:24 -07001290 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001291}
1292
1293//
1294// Host static library
1295//
1296
Colin Cross97ba0732015-03-23 17:50:24 -07001297func CCLibraryHostStaticFactory() (blueprint.Module, []interface{}) {
1298 module := &CCLibrary{}
1299 module.LibraryProperties.BuildStatic = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001300
Colin Cross97ba0732015-03-23 17:50:24 -07001301 return NewCCLibrary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001302}
1303
1304//
1305// Host Shared libraries
1306//
1307
Colin Cross97ba0732015-03-23 17:50:24 -07001308func CCLibraryHostSharedFactory() (blueprint.Module, []interface{}) {
1309 module := &CCLibrary{}
1310 module.LibraryProperties.BuildShared = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001311
Colin Cross97ba0732015-03-23 17:50:24 -07001312 return NewCCLibrary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001313}
1314
1315//
1316// Host Binaries
1317//
1318
Colin Cross97ba0732015-03-23 17:50:24 -07001319func CCBinaryHostFactory() (blueprint.Module, []interface{}) {
1320 module := &CCBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001321
Colin Cross97ba0732015-03-23 17:50:24 -07001322 return NewCCBinary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001323}
1324
1325//
1326// Device libraries shipped with gcc
1327//
1328
1329type toolchainLibrary struct {
Colin Cross97ba0732015-03-23 17:50:24 -07001330 CCLibrary
Colin Cross3f40fa42015-01-30 17:27:36 -08001331}
1332
1333func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1334 // toolchain libraries can't have any dependencies
1335 return nil
1336}
1337
Colin Cross97ba0732015-03-23 17:50:24 -07001338func (*toolchainLibrary) collectDeps(ctx common.AndroidModuleContext, flags CCFlags) (CCDeps, CCFlags) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001339 // toolchain libraries can't have any dependencies
Colin Cross97ba0732015-03-23 17:50:24 -07001340 return CCDeps{}, flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001341}
1342
Colin Cross97ba0732015-03-23 17:50:24 -07001343func ToolchainLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001344 module := &toolchainLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001345
Colin Cross97ba0732015-03-23 17:50:24 -07001346 module.LibraryProperties.BuildStatic = true
1347
Colin Crossc472d572015-03-17 15:06:21 -07001348 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001349}
1350
1351func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
Colin Cross97ba0732015-03-23 17:50:24 -07001352 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001353
1354 libName := ctx.ModuleName() + staticLibraryExtension
1355 outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
1356
1357 CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
1358
1359 c.out = outputFile
1360
1361 ctx.CheckbuildFile(outputFile)
1362}
1363
Colin Cross97ba0732015-03-23 17:50:24 -07001364func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001365 // Toolchain libraries do not get installed.
1366}
1367
Colin Cross3f40fa42015-01-30 17:27:36 -08001368func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
Colin Cross97ba0732015-03-23 17:50:24 -07001369 if c, ok := mctx.Module().(ccLibraryInterface); ok {
Colin Cross3f40fa42015-01-30 17:27:36 -08001370 var modules []blueprint.Module
Colin Cross97ba0732015-03-23 17:50:24 -07001371 if c.ccLibrary().LibraryProperties.BuildStatic && c.ccLibrary().LibraryProperties.BuildShared {
Colin Cross3f40fa42015-01-30 17:27:36 -08001372 modules = mctx.CreateLocalVariations("static", "shared")
Colin Cross97ba0732015-03-23 17:50:24 -07001373 modules[0].(ccLibraryInterface).ccLibrary().LibraryProperties.IsStatic = true
1374 modules[1].(ccLibraryInterface).ccLibrary().LibraryProperties.IsShared = true
1375 } else if c.ccLibrary().LibraryProperties.BuildStatic {
Colin Cross3f40fa42015-01-30 17:27:36 -08001376 modules = mctx.CreateLocalVariations("static")
Colin Cross97ba0732015-03-23 17:50:24 -07001377 modules[0].(ccLibraryInterface).ccLibrary().LibraryProperties.IsStatic = true
1378 } else if c.ccLibrary().LibraryProperties.BuildShared {
Colin Cross3f40fa42015-01-30 17:27:36 -08001379 modules = mctx.CreateLocalVariations("shared")
Colin Cross97ba0732015-03-23 17:50:24 -07001380 modules[0].(ccLibraryInterface).ccLibrary().LibraryProperties.IsShared = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001381 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001382 panic(fmt.Errorf("ccLibrary %q not static or shared", mctx.ModuleName()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001383 }
Colin Cross97ba0732015-03-23 17:50:24 -07001384 primary := modules[0].(ccLibraryInterface).ccLibrary()
Colin Cross3f40fa42015-01-30 17:27:36 -08001385 for _, m := range modules {
Colin Cross97ba0732015-03-23 17:50:24 -07001386 m.(ccLibraryInterface).ccLibrary().primary = primary
1387 if m.(ccLibraryInterface).ccLibrary() != primary {
1388 m.(ccLibraryInterface).ccLibrary().properties.SkipCompileObjs = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001389 }
1390 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001391 }
1392}