blob: e209faa051bab566c36c3e8227079a75bc2c8437 [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
Dan Albertbe961682015-03-18 23:38:50 -0700149 Export_include_dirs []string `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800150
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 Cross21b9a242015-03-24 14:15:58 -0700230 // Modify the ccFlags
231 Flags(common.AndroidModuleContext, CCFlags) CCFlags
Colin Cross3f40fa42015-01-30 17:27:36 -0800232
Colin Cross21b9a242015-03-24 14:15:58 -0700233 // Return list of dependency names for use in AndroidDynamicDependencies and in depsToPaths
234 DepNames(common.AndroidBaseContext, CCDeps) CCDeps
Colin Cross3f40fa42015-01-30 17:27:36 -0800235
236 // Compile objects into final module
Colin Cross97ba0732015-03-23 17:50:24 -0700237 compileModule(common.AndroidModuleContext, CCFlags, CCDeps, []string)
Colin Cross3f40fa42015-01-30 17:27:36 -0800238
Dan Albertc403f7c2015-03-18 14:01:18 -0700239 // Install the built module.
Colin Cross97ba0732015-03-23 17:50:24 -0700240 installModule(common.AndroidModuleContext, CCFlags)
Dan Albertc403f7c2015-03-18 14:01:18 -0700241
Colin Cross3f40fa42015-01-30 17:27:36 -0800242 // Return the output file (.o, .a or .so) for use by other modules
243 outputFile() string
244}
245
Colin Cross97ba0732015-03-23 17:50:24 -0700246type CCDeps struct {
247 StaticLibs, SharedLibs, LateStaticLibs, WholeStaticLibs, ObjFiles, IncludeDirs []string
Colin Crossc472d572015-03-17 15:06:21 -0700248
Colin Cross21b9a242015-03-24 14:15:58 -0700249 WholeStaticLibObjFiles []string
250
Colin Cross97ba0732015-03-23 17:50:24 -0700251 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700252}
253
Colin Cross97ba0732015-03-23 17:50:24 -0700254type CCFlags struct {
255 GlobalFlags []string
256 AsFlags []string
257 CFlags []string
258 ConlyFlags []string
259 CppFlags []string
260 LdFlags []string
261 LdLibs []string
262 IncludeDirs []string
263 Nocrt bool
264 Toolchain Toolchain
265 Clang bool
Colin Crossc472d572015-03-17 15:06:21 -0700266}
267
268// ccBase contains the properties and members used by all C/C++ module types, and implements
269// the blueprint.Module interface. It expects to be embedded into an outer specialization struct,
270// and uses a ccModuleType interface to that struct to create the build steps.
271type ccBase struct {
272 common.AndroidModuleBase
Colin Cross97ba0732015-03-23 17:50:24 -0700273 module CCModuleType
Colin Crossc472d572015-03-17 15:06:21 -0700274
275 properties ccProperties
276 unused unusedProperties
277
278 installPath string
279}
280
Colin Cross97ba0732015-03-23 17:50:24 -0700281func newCCBase(base *ccBase, module CCModuleType, hod common.HostOrDeviceSupported,
Colin Crossc472d572015-03-17 15:06:21 -0700282 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
283
284 base.module = module
285
286 props = append(props, &base.properties, &base.unused)
287
Colin Cross5049f022015-03-18 13:28:46 -0700288 return common.InitAndroidArchModule(module, hod, multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700289}
290
Colin Cross3f40fa42015-01-30 17:27:36 -0800291func (c *ccBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
292 toolchain := c.findToolchain(ctx)
293 if ctx.Failed() {
294 return
295 }
296
Colin Cross21b9a242015-03-24 14:15:58 -0700297 flags := c.collectFlags(ctx, toolchain)
Colin Cross3f40fa42015-01-30 17:27:36 -0800298 if ctx.Failed() {
299 return
300 }
301
Colin Cross21b9a242015-03-24 14:15:58 -0700302 depNames := c.module.DepNames(ctx, CCDeps{})
Colin Cross3f40fa42015-01-30 17:27:36 -0800303 if ctx.Failed() {
304 return
305 }
306
Colin Cross21b9a242015-03-24 14:15:58 -0700307 deps := c.depsToPaths(ctx, depNames)
Colin Cross3f40fa42015-01-30 17:27:36 -0800308 if ctx.Failed() {
309 return
310 }
311
Colin Cross97ba0732015-03-23 17:50:24 -0700312 flags.IncludeDirs = append(flags.IncludeDirs, deps.IncludeDirs...)
Colin Crossed9f8682015-03-18 17:17:35 -0700313
Colin Cross3f40fa42015-01-30 17:27:36 -0800314 objFiles := c.compileObjs(ctx, flags, deps)
315 if ctx.Failed() {
316 return
317 }
318
Colin Cross5049f022015-03-18 13:28:46 -0700319 generatedObjFiles := c.compileGeneratedObjs(ctx, flags, deps)
320 if ctx.Failed() {
321 return
322 }
323
324 objFiles = append(objFiles, generatedObjFiles...)
325
Colin Cross3f40fa42015-01-30 17:27:36 -0800326 c.ccModuleType().compileModule(ctx, flags, deps, objFiles)
327 if ctx.Failed() {
328 return
329 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700330
331 c.ccModuleType().installModule(ctx, flags)
332 if ctx.Failed() {
333 return
334 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800335}
336
Colin Cross97ba0732015-03-23 17:50:24 -0700337func (c *ccBase) ccModuleType() CCModuleType {
Colin Cross3f40fa42015-01-30 17:27:36 -0800338 return c.module
339}
340
341var _ common.AndroidDynamicDepender = (*ccBase)(nil)
342
Colin Cross97ba0732015-03-23 17:50:24 -0700343func (c *ccBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
Colin Cross3f40fa42015-01-30 17:27:36 -0800344 arch := ctx.Arch()
345 factory := toolchainFactories[arch.HostOrDevice][arch.ArchType]
346 if factory == nil {
347 panic(fmt.Sprintf("Toolchain not found for %s arch %q",
348 arch.HostOrDevice.String(), arch.String()))
349 }
350 return factory(arch.ArchVariant, arch.CpuVariant)
351}
352
Colin Cross21b9a242015-03-24 14:15:58 -0700353func (c *ccBase) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
354 depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.properties.Whole_static_libs...)
355 depNames.StaticLibs = append(depNames.StaticLibs, c.properties.Static_libs...)
356 depNames.SharedLibs = append(depNames.SharedLibs, c.properties.Shared_libs...)
357
Colin Cross21b9a242015-03-24 14:15:58 -0700358 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -0800359}
360
361func (c *ccBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
Colin Cross21b9a242015-03-24 14:15:58 -0700362 depNames := CCDeps{}
363 depNames = c.module.DepNames(ctx, depNames)
364 staticLibs := depNames.WholeStaticLibs
365 staticLibs = append(staticLibs, depNames.StaticLibs...)
366 staticLibs = append(staticLibs, depNames.LateStaticLibs...)
367 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800368
Colin Cross21b9a242015-03-24 14:15:58 -0700369 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, depNames.SharedLibs...)
370
371 ret := append([]string(nil), depNames.ObjFiles...)
372 if depNames.CrtBegin != "" {
373 ret = append(ret, depNames.CrtBegin)
374 }
375 if depNames.CrtEnd != "" {
376 ret = append(ret, depNames.CrtEnd)
377 }
378
379 return ret
Colin Cross3f40fa42015-01-30 17:27:36 -0800380}
381
382// Create a ccFlags struct that collects the compile flags from global values,
383// per-target values, module type values, and per-module Blueprints properties
Colin Cross21b9a242015-03-24 14:15:58 -0700384func (c *ccBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolchain) CCFlags {
Colin Cross97ba0732015-03-23 17:50:24 -0700385 flags := CCFlags{
386 CFlags: c.properties.Cflags,
387 CppFlags: c.properties.Cppflags,
388 ConlyFlags: c.properties.Conlyflags,
389 LdFlags: c.properties.Ldflags,
390 AsFlags: c.properties.Asflags,
391 Nocrt: c.properties.Nocrt,
392 Toolchain: toolchain,
393 Clang: c.properties.Clang,
Colin Cross3f40fa42015-01-30 17:27:36 -0800394 }
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700395 instructionSet := c.properties.Instruction_set
396 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
397 if err != nil {
398 ctx.ModuleErrorf("%s", err)
399 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800400
Colin Crossaf19a292015-03-18 12:07:10 -0700401 // TODO: debug
Colin Cross97ba0732015-03-23 17:50:24 -0700402 flags.CFlags = append(flags.CFlags, c.properties.Release.Cflags...)
Colin Crossaf19a292015-03-18 12:07:10 -0700403
Colin Crossf6566ed2015-03-24 11:13:38 -0700404 if ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 // TODO: allow per-module clang disable for host
Colin Cross97ba0732015-03-23 17:50:24 -0700406 flags.Clang = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800407 }
408
Colin Cross97ba0732015-03-23 17:50:24 -0700409 if flags.Clang {
410 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
411 flags.CFlags = append(flags.CFlags, c.properties.Clang_cflags...)
412 flags.AsFlags = append(flags.AsFlags, c.properties.Clang_asflags...)
413 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
414 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
415 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800416
Colin Cross97ba0732015-03-23 17:50:24 -0700417 flags.CFlags = append(flags.CFlags, "${clangExtraCflags}")
418 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Crossf6566ed2015-03-24 11:13:38 -0700419 if ctx.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -0700420 flags.CFlags = append(flags.CFlags, "${clangExtraTargetCflags}")
Colin Crossbdd7b1c2015-03-16 16:21:20 -0700421 }
422
Colin Cross3f40fa42015-01-30 17:27:36 -0800423 target := "-target " + toolchain.ClangTriple()
424 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
425
Colin Cross97ba0732015-03-23 17:50:24 -0700426 flags.CFlags = append(flags.CFlags, target, gccPrefix)
427 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
428 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800429
Colin Crossf6566ed2015-03-24 11:13:38 -0700430 if ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800431 gccToolchain := "--gcc-toolchain=" + toolchain.GccRoot()
432 sysroot := "--sysroot=" + filepath.Join(toolchain.GccRoot(), "sysroot")
433
434 // TODO: also need more -B, -L flags to make host builds hermetic
Colin Cross97ba0732015-03-23 17:50:24 -0700435 flags.CFlags = append(flags.CFlags, gccToolchain, sysroot)
436 flags.AsFlags = append(flags.AsFlags, gccToolchain, sysroot)
437 flags.LdFlags = append(flags.LdFlags, gccToolchain, sysroot)
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 }
439 }
440
Colin Cross97ba0732015-03-23 17:50:24 -0700441 flags.IncludeDirs = pathtools.PrefixPaths(c.properties.Include_dirs, ctx.Config().(Config).SrcDir())
Colin Cross3f40fa42015-01-30 17:27:36 -0800442 localIncludeDirs := pathtools.PrefixPaths(c.properties.Local_include_dirs, common.ModuleSrcDir(ctx))
Colin Cross97ba0732015-03-23 17:50:24 -0700443 flags.IncludeDirs = append(flags.IncludeDirs, localIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800444
445 if !c.properties.No_default_compiler_flags {
Colin Cross97ba0732015-03-23 17:50:24 -0700446 flags.IncludeDirs = append(flags.IncludeDirs, []string{
Colin Cross3f40fa42015-01-30 17:27:36 -0800447 common.ModuleSrcDir(ctx),
448 common.ModuleOutDir(ctx),
449 common.ModuleGenDir(ctx),
450 }...)
451
Colin Crossefd8e482015-03-18 17:17:35 -0700452 if c.properties.Sdk_version == "" {
Colin Cross97ba0732015-03-23 17:50:24 -0700453 flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/libnativehelper/include/nativehelper")
Colin Crossefd8e482015-03-18 17:17:35 -0700454 }
455
Colin Crossf6566ed2015-03-24 11:13:38 -0700456 if ctx.Device() && !c.properties.Allow_undefined_symbols {
Colin Cross97ba0732015-03-23 17:50:24 -0700457 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
Colin Cross3f40fa42015-01-30 17:27:36 -0800458 }
459
Colin Cross97ba0732015-03-23 17:50:24 -0700460 if flags.Clang {
461 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
462 flags.GlobalFlags = []string{
Colin Cross3f40fa42015-01-30 17:27:36 -0800463 "${commonGlobalIncludes}",
464 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700465 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800466 toolchain.ClangCflags(),
467 "${commonClangGlobalCflags}",
Colin Crossf6566ed2015-03-24 11:13:38 -0700468 fmt.Sprintf("${%sClangGlobalCflags}", ctx.Arch().HostOrDevice),
Colin Cross3f40fa42015-01-30 17:27:36 -0800469 }
470 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700471 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
472 flags.GlobalFlags = []string{
Colin Cross3f40fa42015-01-30 17:27:36 -0800473 "${commonGlobalIncludes}",
474 toolchain.IncludeFlags(),
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700475 instructionSetFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800476 toolchain.Cflags(),
477 "${commonGlobalCflags}",
Colin Crossf6566ed2015-03-24 11:13:38 -0700478 fmt.Sprintf("${%sGlobalCflags}", ctx.Arch().HostOrDevice),
Colin Cross3f40fa42015-01-30 17:27:36 -0800479 }
480 }
481
Colin Crossf6566ed2015-03-24 11:13:38 -0700482 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -0700483 flags.LdFlags = append(flags.LdFlags, c.properties.Host_ldlibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800484 }
485
Colin Crossf6566ed2015-03-24 11:13:38 -0700486 if ctx.Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800487 if c.properties.Rtti {
Colin Cross97ba0732015-03-23 17:50:24 -0700488 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800489 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700490 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800491 }
492 }
493
Colin Cross97ba0732015-03-23 17:50:24 -0700494 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -0800495
Colin Cross97ba0732015-03-23 17:50:24 -0700496 if flags.Clang {
497 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
498 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
Colin Cross3f40fa42015-01-30 17:27:36 -0800499 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700500 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
501 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
Colin Cross3f40fa42015-01-30 17:27:36 -0800502 }
503 }
504
Colin Cross21b9a242015-03-24 14:15:58 -0700505 flags = c.ccModuleType().Flags(ctx, flags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800506
507 // Optimization to reduce size of build.ninja
508 // Replace the long list of flags for each file with a module-local variable
Colin Cross97ba0732015-03-23 17:50:24 -0700509 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
510 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
511 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
512 flags.CFlags = []string{"$cflags"}
513 flags.CppFlags = []string{"$cppflags"}
514 flags.AsFlags = []string{"$asflags"}
Colin Cross3f40fa42015-01-30 17:27:36 -0800515
516 return flags
517}
518
Colin Cross21b9a242015-03-24 14:15:58 -0700519func (c *ccBase) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Cross3f40fa42015-01-30 17:27:36 -0800520 return flags
521}
522
523// Compile a list of source files into objects a specified subdirectory
Colin Cross97ba0732015-03-23 17:50:24 -0700524func (c *ccBase) customCompileObjs(ctx common.AndroidModuleContext, flags CCFlags,
525 deps CCDeps, subdir string, srcFiles []string) []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800526
527 srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
528 srcFiles = common.ExpandGlobs(ctx, srcFiles)
529
530 return TransformSourceToObj(ctx, subdir, srcFiles, ccFlagsToBuilderFlags(flags))
531}
532
533// Compile files listed in c.properties.Srcs into objects
Colin Cross97ba0732015-03-23 17:50:24 -0700534func (c *ccBase) compileObjs(ctx common.AndroidModuleContext, flags CCFlags,
535 deps CCDeps) []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800536
537 if c.properties.SkipCompileObjs {
538 return nil
539 }
540
541 return c.customCompileObjs(ctx, flags, deps, "", c.properties.Srcs)
542}
543
Colin Cross5049f022015-03-18 13:28:46 -0700544// Compile generated source files from dependencies
Colin Cross97ba0732015-03-23 17:50:24 -0700545func (c *ccBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags CCFlags,
546 deps CCDeps) []string {
Colin Cross5049f022015-03-18 13:28:46 -0700547 var srcs []string
548
549 if c.properties.SkipCompileObjs {
550 return nil
551 }
552
553 ctx.VisitDirectDeps(func(module blueprint.Module) {
554 if gen, ok := module.(genrule.SourceFileGenerator); ok {
555 srcs = append(srcs, gen.GeneratedSourceFiles()...)
556 }
557 })
558
559 if len(srcs) == 0 {
560 return nil
561 }
562
563 return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags))
564}
565
Colin Cross3f40fa42015-01-30 17:27:36 -0800566func (c *ccBase) outputFile() string {
567 return ""
568}
569
Colin Cross21b9a242015-03-24 14:15:58 -0700570func (c *ccBase) depsToPathsFromList(ctx common.AndroidModuleContext,
Colin Cross3f40fa42015-01-30 17:27:36 -0800571 names []string) (modules []common.AndroidModule,
572 outputFiles []string, exportedIncludeDirs []string) {
573
574 for _, n := range names {
575 found := false
576 ctx.VisitDirectDeps(func(m blueprint.Module) {
577 otherName := ctx.OtherModuleName(m)
578 if otherName != n {
579 return
580 }
581
Colin Cross97ba0732015-03-23 17:50:24 -0700582 if a, ok := m.(CCModuleType); ok {
Colin Cross3f40fa42015-01-30 17:27:36 -0800583 if a.Disabled() {
584 // If a cc_library host+device module depends on a library that exists as both
585 // cc_library_shared and cc_library_host_shared, it will end up with two
586 // dependencies with the same name, one of which is marked disabled for each
587 // of host and device. Ignore the disabled one.
588 return
589 }
590 if a.HostOrDevice() != ctx.Arch().HostOrDevice {
591 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
592 otherName)
593 return
594 }
595
596 if outputFile := a.outputFile(); outputFile != "" {
597 if found {
598 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
599 return
600 }
601 outputFiles = append(outputFiles, outputFile)
602 modules = append(modules, a)
603 if i, ok := a.(ccExportedIncludeDirsProducer); ok {
604 exportedIncludeDirs = append(exportedIncludeDirs, i.exportedIncludeDirs()...)
605 }
606 found = true
607 } else {
608 ctx.ModuleErrorf("module %q missing output file", otherName)
609 return
610 }
611 } else {
612 ctx.ModuleErrorf("module %q not an android module", otherName)
613 return
614 }
615 })
616 if !found {
617 ctx.ModuleErrorf("unsatisified dependency on %q", n)
618 }
619 }
620
621 return modules, outputFiles, exportedIncludeDirs
622}
623
Colin Cross21b9a242015-03-24 14:15:58 -0700624// Convert depenedency names to paths. Takes a CCDeps containing names and returns a CCDeps
625// containing paths
626func (c *ccBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) CCDeps {
627 var depPaths CCDeps
Colin Cross3f40fa42015-01-30 17:27:36 -0800628 var newIncludeDirs []string
629
Colin Cross21b9a242015-03-24 14:15:58 -0700630 var wholeStaticLibModules []common.AndroidModule
Colin Cross3f40fa42015-01-30 17:27:36 -0800631
Colin Cross21b9a242015-03-24 14:15:58 -0700632 wholeStaticLibModules, depPaths.WholeStaticLibs, newIncludeDirs =
633 c.depsToPathsFromList(ctx, depNames.WholeStaticLibs)
634 depPaths.IncludeDirs = append(depPaths.IncludeDirs, newIncludeDirs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800635
Colin Cross21b9a242015-03-24 14:15:58 -0700636 for _, m := range wholeStaticLibModules {
637 if staticLib, ok := m.(ccLibraryInterface); ok && staticLib.static() {
638 depPaths.WholeStaticLibObjFiles =
639 append(depPaths.WholeStaticLibObjFiles, staticLib.allObjFiles()...)
640 } else {
641 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
642 }
643 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800644
Colin Cross21b9a242015-03-24 14:15:58 -0700645 _, depPaths.StaticLibs, newIncludeDirs = c.depsToPathsFromList(ctx, depNames.StaticLibs)
646 depPaths.IncludeDirs = append(depPaths.IncludeDirs, newIncludeDirs...)
647
648 _, depPaths.LateStaticLibs, newIncludeDirs = c.depsToPathsFromList(ctx, depNames.LateStaticLibs)
649 depPaths.IncludeDirs = append(depPaths.IncludeDirs, newIncludeDirs...)
650
651 _, depPaths.SharedLibs, newIncludeDirs = c.depsToPathsFromList(ctx, depNames.SharedLibs)
652 depPaths.IncludeDirs = append(depPaths.IncludeDirs, newIncludeDirs...)
653
654 ctx.VisitDirectDeps(func(m blueprint.Module) {
655 if obj, ok := m.(*ccObject); ok {
656 otherName := ctx.OtherModuleName(m)
657 if otherName == depNames.CrtBegin {
658 if !c.properties.Nocrt {
659 depPaths.CrtBegin = obj.outputFile()
660 }
661 } else if otherName == depNames.CrtEnd {
662 if !c.properties.Nocrt {
663 depPaths.CrtEnd = obj.outputFile()
664 }
665 } else {
666 depPaths.ObjFiles = append(depPaths.ObjFiles, obj.outputFile())
667 }
668 }
669 })
670
671 return depPaths
Colin Cross3f40fa42015-01-30 17:27:36 -0800672}
673
Colin Crossed4cf0b2015-03-26 14:43:45 -0700674// ccLinked contains the properties and members used by libraries and executables
675type ccLinked struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800676 ccBase
Colin Crossed4cf0b2015-03-26 14:43:45 -0700677
678 dynamicProperties struct {
679 VariantIsShared bool `blueprint:"mutated"`
680 VariantIsStatic bool `blueprint:"mutated"`
681 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800682}
683
Colin Crossed4cf0b2015-03-26 14:43:45 -0700684func newCCDynamic(dynamic *ccLinked, module CCModuleType, hod common.HostOrDeviceSupported,
Colin Crossc472d572015-03-17 15:06:21 -0700685 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
686
687 dynamic.properties.System_shared_libs = []string{defaultSystemSharedLibraries}
688
Colin Crossed4cf0b2015-03-26 14:43:45 -0700689 props = append(props, &dynamic.dynamicProperties)
690
Colin Crossc472d572015-03-17 15:06:21 -0700691 return newCCBase(&dynamic.ccBase, module, hod, multilib, props...)
692}
693
Colin Cross3f40fa42015-01-30 17:27:36 -0800694const defaultSystemSharedLibraries = "__default__"
695
Colin Crossed4cf0b2015-03-26 14:43:45 -0700696func (c *ccLinked) systemSharedLibs(ctx common.AndroidBaseContext) []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800697 if len(c.properties.System_shared_libs) == 1 &&
698 c.properties.System_shared_libs[0] == defaultSystemSharedLibraries {
699
Colin Crossf6566ed2015-03-24 11:13:38 -0700700 if ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800701 return []string{}
Dan Albertbe961682015-03-18 23:38:50 -0700702 } else if c.properties.Sdk_version != "" {
703 version := c.properties.Sdk_version
704 libs := []string{
705 "ndk_libc." + version,
706 "ndk_libm." + version,
707 }
708
709 if c.properties.Sdk_version != "" && c.stl(ctx) == "ndk_system" {
710 libs = append([]string{"libstdc++"}, libs...)
711 }
712 return libs
Colin Cross3f40fa42015-01-30 17:27:36 -0800713 } else {
714 return []string{"libc", "libm"}
715 }
716 }
717 return c.properties.System_shared_libs
718}
719
Colin Crossed4cf0b2015-03-26 14:43:45 -0700720func (c *ccLinked) stl(ctx common.AndroidBaseContext) string {
721 if c.properties.Sdk_version != "" {
722 switch c.properties.Stl {
723 case "":
724 return "ndk_system"
725 case "c++_shared", "c++_static",
726 "stlport_shared", "stlport_static",
727 "gnustl_static":
728 return "ndk_lib" + c.properties.Stl
729 default:
730 ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", c.properties.Stl)
731 return ""
732 }
733 }
734
735 switch c.properties.Stl {
736 case "libc++", "libc++_static",
737 "stlport", "stlport_static",
738 "libstdc++":
739 return c.properties.Stl
740 case "none":
741 return ""
742 case "":
743 if c.shared() {
744 return "libc++" // TODO: mingw needs libstdc++
745 } else {
746 return "libc++_static"
747 }
748 default:
749 ctx.ModuleErrorf("stl: %q is not a supported STL", c.properties.Stl)
750 return ""
751 }
752}
753
754func (c *ccLinked) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
755 stl := c.stl(ctx)
756 if ctx.Failed() {
757 return flags
758 }
759
760 switch stl {
761 case "libc++", "libc++_static":
762 flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
763 flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/external/libcxx/include")
764 if ctx.Host() {
765 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
766 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
767 flags.LdLibs = append(flags.LdLibs, "-lc", "-lm", "-lpthread")
768 }
769 case "stlport", "stlport_static":
770 if ctx.Device() {
771 flags.IncludeDirs = append(flags.IncludeDirs,
772 "${SrcDir}/external/stlport/stlport",
773 "${SrcDir}/bionic/libstdc++/include",
774 "${SrcDir}/bionic")
775 }
776 case "libstdc++":
777 // Using bionic's basic libstdc++. Not actually an STL. Only around until the
778 // tree is in good enough shape to not need it.
779 // Host builds will use GNU libstdc++.
780 if ctx.Device() {
781 flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/bionic/libstdc++/include")
782 }
783 case "ndk_system":
784 ndkSrcRoot := ctx.Config().(Config).SrcDir() + "/prebuilts/ndk/current/sources/"
785 flags.IncludeDirs = append(flags.IncludeDirs, ndkSrcRoot+"cxx-stl/system/include")
786 case "ndk_libc++_shared", "ndk_libc++_static":
787 // TODO(danalbert): This really shouldn't be here...
788 flags.CppFlags = append(flags.CppFlags, "-std=c++11")
789 case "ndk_libstlport_shared", "ndk_libstlport_static", "ndk_libgnustl_static":
790 // Nothing
791 case "":
792 // None or error.
793 if ctx.Host() {
794 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
795 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
796 flags.LdLibs = append(flags.LdLibs, "-lc", "-lm")
797 }
798 default:
799 panic(fmt.Errorf("Unknown stl in ccLinked.Flags: %q", stl))
800 }
801
802 return flags
803}
804
805func (c *ccLinked) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Cross21b9a242015-03-24 14:15:58 -0700806 depNames = c.ccBase.DepNames(ctx, depNames)
Colin Cross3f40fa42015-01-30 17:27:36 -0800807
Colin Crossed4cf0b2015-03-26 14:43:45 -0700808 stl := c.stl(ctx)
809 if ctx.Failed() {
810 return depNames
811 }
812
813 switch stl {
814 case "libc++":
815 depNames.SharedLibs = append(depNames.SharedLibs, stl)
816 case "libstdc++":
817 if ctx.Device() {
818 depNames.SharedLibs = append(depNames.SharedLibs, stl)
819 }
820 case "libc++_static":
821 depNames.StaticLibs = append(depNames.StaticLibs, stl)
822 case "stlport":
823 depNames.SharedLibs = append(depNames.SharedLibs, "libstdc++", "libstlport")
824 case "stlport_static":
825 depNames.StaticLibs = append(depNames.StaticLibs, "libstdc++", "libstlport_static")
826 case "":
827 // None or error.
828 case "ndk_system":
829 // TODO: Make a system STL prebuilt for the NDK.
830 // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
831 // its own includes. The includes are handled in ccBase.Flags().
832 case "ndk_libc++_shared", "ndk_libstlport_shared":
833 depNames.SharedLibs = append(depNames.SharedLibs, stl)
834 case "ndk_libc++_static", "ndk_libstlport_static", "ndk_libgnustl_static":
835 depNames.StaticLibs = append(depNames.StaticLibs, stl)
836 default:
837 panic(fmt.Errorf("Unknown stl in ccLinked.DepNames: %q", stl))
838 }
839
Colin Crossf6566ed2015-03-24 11:13:38 -0700840 if ctx.Device() {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700841 if ctx.ModuleName() != "libcompiler_rt-extras" {
842 depNames.StaticLibs = append(depNames.StaticLibs, "libcompiler_rt-extras")
843 }
Colin Cross77b00fa2015-03-16 16:15:49 -0700844 // libgcc and libatomic have to be last on the command line
Colin Cross21b9a242015-03-24 14:15:58 -0700845 depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic", "libgcc")
Colin Crossed4cf0b2015-03-26 14:43:45 -0700846
847 if c.shared() {
848 depNames.SharedLibs = append(depNames.SharedLibs, c.systemSharedLibs(ctx)...)
849 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800850 }
851
Colin Cross21b9a242015-03-24 14:15:58 -0700852 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -0800853}
854
Colin Crossed4cf0b2015-03-26 14:43:45 -0700855// ccLinkedInterface interface is used on ccLinked to deal with static or shared variants
856type ccLinkedInterface interface {
857 // Returns true if the build options for the module have selected a static or shared build
858 buildStatic() bool
859 buildShared() bool
860
861 // Sets whether a specific variant is static or shared
862 setStatic()
863 setShared()
864
865 // Returns whether a specific variant is static or shared
866 static() bool
867 shared() bool
868}
869
870var _ ccLinkedInterface = (*CCLibrary)(nil)
871var _ ccLinkedInterface = (*CCBinary)(nil)
872
873func (c *ccLinked) static() bool {
874 return c.dynamicProperties.VariantIsStatic
875}
876
877func (c *ccLinked) shared() bool {
878 return c.dynamicProperties.VariantIsShared
879}
880
881func (c *ccLinked) setStatic() {
882 c.dynamicProperties.VariantIsStatic = true
883}
884
885func (c *ccLinked) setShared() {
886 c.dynamicProperties.VariantIsShared = true
887}
888
Colin Cross3f40fa42015-01-30 17:27:36 -0800889type ccExportedIncludeDirsProducer interface {
890 exportedIncludeDirs() []string
891}
892
893//
894// Combined static+shared libraries
895//
896
Colin Cross97ba0732015-03-23 17:50:24 -0700897type CCLibrary struct {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700898 ccLinked
Colin Cross3f40fa42015-01-30 17:27:36 -0800899
Colin Crossed4cf0b2015-03-26 14:43:45 -0700900 reuseFrom ccLibraryInterface
901 reuseObjFiles []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800902 objFiles []string
903 exportIncludeDirs []string
904 out string
905
Colin Cross97ba0732015-03-23 17:50:24 -0700906 LibraryProperties struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800907 BuildStatic bool `blueprint:"mutated"`
908 BuildShared bool `blueprint:"mutated"`
Colin Crossed4cf0b2015-03-26 14:43:45 -0700909 Static struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800910 Srcs []string `android:"arch_variant"`
911 Cflags []string `android:"arch_variant"`
912 } `android:"arch_variant"`
913 Shared struct {
914 Srcs []string `android:"arch_variant"`
915 Cflags []string `android:"arch_variant"`
916 } `android:"arch_variant"`
917 }
918}
919
Colin Crossed4cf0b2015-03-26 14:43:45 -0700920func (c *CCLibrary) buildStatic() bool {
921 return c.LibraryProperties.BuildStatic
922}
923
924func (c *CCLibrary) buildShared() bool {
925 return c.LibraryProperties.BuildShared
926}
927
Colin Cross97ba0732015-03-23 17:50:24 -0700928type ccLibraryInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700929 ccLinkedInterface
Colin Cross97ba0732015-03-23 17:50:24 -0700930 ccLibrary() *CCLibrary
Colin Crossed4cf0b2015-03-26 14:43:45 -0700931 setReuseFrom(ccLibraryInterface)
932 getReuseFrom() ccLibraryInterface
933 getReuseObjFiles() []string
Colin Cross97ba0732015-03-23 17:50:24 -0700934 allObjFiles() []string
Colin Crossc472d572015-03-17 15:06:21 -0700935}
936
Colin Crossed4cf0b2015-03-26 14:43:45 -0700937var _ ccLibraryInterface = (*CCLibrary)(nil)
938
Colin Cross97ba0732015-03-23 17:50:24 -0700939func (c *CCLibrary) ccLibrary() *CCLibrary {
940 return c
Colin Cross3f40fa42015-01-30 17:27:36 -0800941}
942
Colin Cross97ba0732015-03-23 17:50:24 -0700943func NewCCLibrary(library *CCLibrary, module CCModuleType,
944 hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
945
Colin Crossed4cf0b2015-03-26 14:43:45 -0700946 return newCCDynamic(&library.ccLinked, module, hod, common.MultilibBoth,
Colin Cross97ba0732015-03-23 17:50:24 -0700947 &library.LibraryProperties)
948}
949
950func CCLibraryFactory() (blueprint.Module, []interface{}) {
951 module := &CCLibrary{}
952
953 module.LibraryProperties.BuildShared = true
954 module.LibraryProperties.BuildStatic = true
955
956 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
957}
958
Colin Cross21b9a242015-03-24 14:15:58 -0700959func (c *CCLibrary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700960 depNames = c.ccLinked.DepNames(ctx, depNames)
Colin Cross21b9a242015-03-24 14:15:58 -0700961 if c.shared() {
Colin Crossf6566ed2015-03-24 11:13:38 -0700962 if ctx.Device() {
Colin Cross21b9a242015-03-24 14:15:58 -0700963 depNames.CrtBegin = "crtbegin_so"
964 depNames.CrtEnd = "crtend_so"
Colin Cross3f40fa42015-01-30 17:27:36 -0800965 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800966 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800967
Colin Cross21b9a242015-03-24 14:15:58 -0700968 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -0800969}
970
Colin Cross97ba0732015-03-23 17:50:24 -0700971func (c *CCLibrary) outputFile() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800972 return c.out
973}
974
Colin Crossed4cf0b2015-03-26 14:43:45 -0700975func (c *CCLibrary) getReuseObjFiles() []string {
976 return c.reuseObjFiles
977}
978
979func (c *CCLibrary) setReuseFrom(reuseFrom ccLibraryInterface) {
980 c.reuseFrom = reuseFrom
981}
982
983func (c *CCLibrary) getReuseFrom() ccLibraryInterface {
984 return c.reuseFrom
985}
986
Colin Cross97ba0732015-03-23 17:50:24 -0700987func (c *CCLibrary) allObjFiles() []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800988 return c.objFiles
989}
990
Colin Cross97ba0732015-03-23 17:50:24 -0700991func (c *CCLibrary) exportedIncludeDirs() []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800992 return c.exportIncludeDirs
993}
994
Colin Cross21b9a242015-03-24 14:15:58 -0700995func (c *CCLibrary) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700996 flags = c.ccLinked.Flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -0700997
Colin Cross97ba0732015-03-23 17:50:24 -0700998 flags.CFlags = append(flags.CFlags, "-fPIC")
Colin Cross3f40fa42015-01-30 17:27:36 -0800999
Colin Crossed4cf0b2015-03-26 14:43:45 -07001000 if c.shared() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001001 libName := ctx.ModuleName()
1002 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1003 sharedFlag := "-Wl,-shared"
Colin Crossf6566ed2015-03-24 11:13:38 -07001004 if c.properties.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001005 sharedFlag = "-shared"
1006 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001007 if ctx.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -07001008 flags.LdFlags = append(flags.LdFlags, "-nostdlib")
Colin Cross3f40fa42015-01-30 17:27:36 -08001009 }
Colin Cross97ba0732015-03-23 17:50:24 -07001010
1011 flags.LdFlags = append(flags.LdFlags,
1012 "-Wl,--gc-sections",
1013 sharedFlag,
1014 "-Wl,-soname,"+libName+sharedLibraryExtension,
1015 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001016 }
Colin Cross97ba0732015-03-23 17:50:24 -07001017
1018 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001019}
1020
Colin Cross97ba0732015-03-23 17:50:24 -07001021func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
1022 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001023
1024 staticFlags := flags
Colin Cross97ba0732015-03-23 17:50:24 -07001025 staticFlags.CFlags = append(staticFlags.CFlags, c.LibraryProperties.Static.Cflags...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001026 objFilesStatic := c.customCompileObjs(ctx, staticFlags, deps, common.DeviceStaticLibrary,
Colin Cross97ba0732015-03-23 17:50:24 -07001027 c.LibraryProperties.Static.Srcs)
Colin Cross3f40fa42015-01-30 17:27:36 -08001028
1029 objFiles = append(objFiles, objFilesStatic...)
Colin Cross21b9a242015-03-24 14:15:58 -07001030 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001031
1032 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
1033
1034 TransformObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1035
1036 c.objFiles = objFiles
1037 c.out = outputFile
1038 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
1039 common.ModuleSrcDir(ctx))
1040
1041 ctx.CheckbuildFile(outputFile)
1042}
1043
Colin Cross97ba0732015-03-23 17:50:24 -07001044func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
1045 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001046
1047 sharedFlags := flags
Colin Cross97ba0732015-03-23 17:50:24 -07001048 sharedFlags.CFlags = append(sharedFlags.CFlags, c.LibraryProperties.Shared.Cflags...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001049 objFilesShared := c.customCompileObjs(ctx, sharedFlags, deps, common.DeviceSharedLibrary,
Colin Cross97ba0732015-03-23 17:50:24 -07001050 c.LibraryProperties.Shared.Srcs)
Colin Cross3f40fa42015-01-30 17:27:36 -08001051
1052 objFiles = append(objFiles, objFilesShared...)
1053
1054 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
1055
Colin Cross97ba0732015-03-23 17:50:24 -07001056 TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001057 deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd, false,
Colin Cross77b00fa2015-03-16 16:15:49 -07001058 ccFlagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001059
1060 c.out = outputFile
1061 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
1062 common.ModuleSrcDir(ctx))
Colin Cross3f40fa42015-01-30 17:27:36 -08001063}
1064
Colin Cross97ba0732015-03-23 17:50:24 -07001065func (c *CCLibrary) compileModule(ctx common.AndroidModuleContext,
1066 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001067
1068 // Reuse the object files from the matching static library if it exists
Colin Crossed4cf0b2015-03-26 14:43:45 -07001069 if c.getReuseFrom().ccLibrary() == c {
1070 c.reuseObjFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001071 } else {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001072 objFiles = append([]string(nil), c.getReuseFrom().getReuseObjFiles()...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001073 }
1074
Colin Crossed4cf0b2015-03-26 14:43:45 -07001075 if c.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001076 c.compileStaticLibrary(ctx, flags, deps, objFiles)
1077 } else {
1078 c.compileSharedLibrary(ctx, flags, deps, objFiles)
1079 }
1080}
1081
Colin Cross97ba0732015-03-23 17:50:24 -07001082func (c *CCLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001083 // Static libraries do not get installed.
1084}
1085
Colin Cross97ba0732015-03-23 17:50:24 -07001086func (c *CCLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001087 installDir := "lib"
Colin Cross97ba0732015-03-23 17:50:24 -07001088 if flags.Toolchain.Is64Bit() {
Dan Albertc403f7c2015-03-18 14:01:18 -07001089 installDir = "lib64"
1090 }
1091
1092 ctx.InstallFile(installDir, c.out)
1093}
1094
Colin Cross97ba0732015-03-23 17:50:24 -07001095func (c *CCLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001096 if c.static() {
Dan Albertc403f7c2015-03-18 14:01:18 -07001097 c.installStaticLibrary(ctx, flags)
1098 } else {
1099 c.installSharedLibrary(ctx, flags)
1100 }
1101}
1102
Colin Cross3f40fa42015-01-30 17:27:36 -08001103//
1104// Objects (for crt*.o)
1105//
1106
1107type ccObject struct {
1108 ccBase
1109 out string
1110}
1111
Colin Cross97ba0732015-03-23 17:50:24 -07001112func CCObjectFactory() (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001113 module := &ccObject{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001114
Colin Crossc472d572015-03-17 15:06:21 -07001115 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001116}
1117
1118func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1119 // object files can't have any dynamic dependencies
1120 return nil
1121}
1122
Colin Cross21b9a242015-03-24 14:15:58 -07001123func (*ccObject) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
1124 // object files can't have any dynamic dependencies
1125 return CCDeps{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001126}
1127
1128func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
Colin Cross97ba0732015-03-23 17:50:24 -07001129 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001130
Colin Cross97ba0732015-03-23 17:50:24 -07001131 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001132
1133 var outputFile string
1134 if len(objFiles) == 1 {
1135 outputFile = objFiles[0]
1136 } else {
1137 outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+".o")
1138 TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1139 }
1140
1141 c.out = outputFile
1142
1143 ctx.CheckbuildFile(outputFile)
1144}
1145
Colin Cross97ba0732015-03-23 17:50:24 -07001146func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001147 // Object files do not get installed.
1148}
1149
Colin Cross3f40fa42015-01-30 17:27:36 -08001150func (c *ccObject) outputFile() string {
1151 return c.out
1152}
1153
1154//
1155// Executables
1156//
1157
Colin Cross97ba0732015-03-23 17:50:24 -07001158type CCBinary struct {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001159 ccLinked
Dan Albertc403f7c2015-03-18 14:01:18 -07001160 out string
Colin Cross97ba0732015-03-23 17:50:24 -07001161 BinaryProperties struct {
1162 // static_executable: compile executable with -static
1163 Static_executable bool
1164
1165 // stem: set the name of the output
1166 Stem string `android:"arch_variant"`
1167
Colin Cross4ae185c2015-03-26 15:12:10 -07001168 // suffix: append to the name of the output
1169 Suffix string `android:"arch_variant"`
1170
Colin Cross97ba0732015-03-23 17:50:24 -07001171 // prefix_symbols: if set, add an extra objcopy --prefix-symbols= step
1172 Prefix_symbols string
1173 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001174}
1175
Colin Crossed4cf0b2015-03-26 14:43:45 -07001176func (c *CCBinary) buildStatic() bool {
1177 return c.BinaryProperties.Static_executable
1178}
1179
1180func (c *CCBinary) buildShared() bool {
1181 return !c.BinaryProperties.Static_executable
1182}
1183
Colin Cross97ba0732015-03-23 17:50:24 -07001184func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001185 stem := ctx.ModuleName()
Colin Cross97ba0732015-03-23 17:50:24 -07001186 if c.BinaryProperties.Stem != "" {
Colin Cross4ae185c2015-03-26 15:12:10 -07001187 stem = c.BinaryProperties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001188 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001189
1190 return stem + c.BinaryProperties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001191}
1192
Colin Cross21b9a242015-03-24 14:15:58 -07001193func (c *CCBinary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001194 depNames = c.ccLinked.DepNames(ctx, depNames)
Colin Crossf6566ed2015-03-24 11:13:38 -07001195 if ctx.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -07001196 if c.BinaryProperties.Static_executable {
Colin Cross21b9a242015-03-24 14:15:58 -07001197 depNames.CrtBegin = "crtbegin_static"
Colin Cross3f40fa42015-01-30 17:27:36 -08001198 } else {
Colin Cross21b9a242015-03-24 14:15:58 -07001199 depNames.CrtBegin = "crtbegin_dynamic"
Colin Cross3f40fa42015-01-30 17:27:36 -08001200 }
Colin Cross21b9a242015-03-24 14:15:58 -07001201 depNames.CrtEnd = "crtend_android"
Colin Crossed4cf0b2015-03-26 14:43:45 -07001202
1203 if c.BinaryProperties.Static_executable {
1204 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1205 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1206 // move them to the beginning of deps.LateStaticLibs
1207 var groupLibs []string
1208 depNames.StaticLibs, groupLibs = filterList(depNames.StaticLibs,
1209 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
1210 depNames.LateStaticLibs = append(groupLibs, depNames.LateStaticLibs...)
1211 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001212 }
Colin Cross21b9a242015-03-24 14:15:58 -07001213 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -08001214}
1215
Colin Cross97ba0732015-03-23 17:50:24 -07001216func NewCCBinary(binary *CCBinary, module CCModuleType,
Colin Cross1f8f2342015-03-26 16:09:47 -07001217 hod common.HostOrDeviceSupported, props ...interface{}) (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001218
Colin Cross1f8f2342015-03-26 16:09:47 -07001219 props = append(props, &binary.BinaryProperties)
1220
1221 return newCCDynamic(&binary.ccLinked, module, hod, common.MultilibFirst, props...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001222}
1223
Colin Cross97ba0732015-03-23 17:50:24 -07001224func CCBinaryFactory() (blueprint.Module, []interface{}) {
1225 module := &CCBinary{}
1226
1227 return NewCCBinary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001228}
1229
Colin Cross21b9a242015-03-24 14:15:58 -07001230func (c *CCBinary) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001231 flags = c.ccLinked.Flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001232
Colin Cross97ba0732015-03-23 17:50:24 -07001233 flags.CFlags = append(flags.CFlags, "-fpie")
1234
Colin Crossf6566ed2015-03-24 11:13:38 -07001235 if ctx.Device() {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001236 if c.BinaryProperties.Static_executable {
1237 // Clang driver needs -static to create static executable.
1238 // However, bionic/linker uses -shared to overwrite.
1239 // Linker for x86 targets does not allow coexistance of -static and -shared,
1240 // so we add -static only if -shared is not used.
1241 if !inList("-shared", flags.LdFlags) {
1242 flags.LdFlags = append(flags.LdFlags, "-static")
1243 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001244
Colin Crossed4cf0b2015-03-26 14:43:45 -07001245 flags.LdFlags = append(flags.LdFlags,
1246 "-nostdlib",
1247 "-Bstatic",
1248 "-Wl,--gc-sections",
1249 )
1250
1251 } else {
1252 linker := "/system/bin/linker"
1253 if flags.Toolchain.Is64Bit() {
1254 linker = "/system/bin/linker64"
1255 }
1256
1257 flags.LdFlags = append(flags.LdFlags,
1258 "-nostdlib",
1259 "-Bdynamic",
1260 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1261 "-Wl,--gc-sections",
1262 "-Wl,-z,nocopyreloc",
1263 )
1264 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001265 }
1266
Colin Cross97ba0732015-03-23 17:50:24 -07001267 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001268}
1269
Colin Cross97ba0732015-03-23 17:50:24 -07001270func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
1271 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001272
Colin Cross97ba0732015-03-23 17:50:24 -07001273 if !c.BinaryProperties.Static_executable && inList("libc", c.properties.Static_libs) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001274 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1275 "from static libs or set static_executable: true")
1276 }
1277
1278 outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
Dan Albertc403f7c2015-03-18 14:01:18 -07001279 c.out = outputFile
Colin Crossbfae8852015-03-26 14:44:11 -07001280 if c.BinaryProperties.Prefix_symbols != "" {
1281 afterPrefixSymbols := outputFile
1282 outputFile = outputFile + ".intermediate"
1283 TransformBinaryPrefixSymbols(ctx, c.BinaryProperties.Prefix_symbols, outputFile,
1284 ccFlagsToBuilderFlags(flags), afterPrefixSymbols)
1285 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001286
Colin Cross97ba0732015-03-23 17:50:24 -07001287 TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001288 deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd, true,
Colin Cross77b00fa2015-03-16 16:15:49 -07001289 ccFlagsToBuilderFlags(flags), outputFile)
Dan Albertc403f7c2015-03-18 14:01:18 -07001290}
Colin Cross3f40fa42015-01-30 17:27:36 -08001291
Colin Cross97ba0732015-03-23 17:50:24 -07001292func (c *CCBinary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001293 ctx.InstallFile("bin", c.out)
1294}
1295
1296type ccTest struct {
Colin Cross97ba0732015-03-23 17:50:24 -07001297 CCBinary
Colin Cross6b290692015-03-19 14:05:33 -07001298
1299 testProperties struct {
1300 // test_per_src: Create a separate test for each source file. Useful when there is
1301 // global state that can not be torn down and reset between each test suite.
1302 Test_per_src bool
1303 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001304}
1305
Colin Cross21b9a242015-03-24 14:15:58 -07001306func (c *ccTest) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
1307 flags = c.CCBinary.Flags(ctx, flags)
Dan Albertc403f7c2015-03-18 14:01:18 -07001308
Colin Cross97ba0732015-03-23 17:50:24 -07001309 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001310 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001311 flags.CFlags = append(flags.CFlags, "-O0", "-g")
1312 flags.LdLibs = append(flags.LdLibs, "-lpthread")
Dan Albertc403f7c2015-03-18 14:01:18 -07001313 }
1314
1315 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross97ba0732015-03-23 17:50:24 -07001316 flags.IncludeDirs = append(flags.IncludeDirs,
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001317 filepath.Join(ctx.Config().(Config).SrcDir(), "external/gtest/include"))
Dan Albertc403f7c2015-03-18 14:01:18 -07001318
Colin Cross21b9a242015-03-24 14:15:58 -07001319 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07001320}
1321
Colin Cross21b9a242015-03-24 14:15:58 -07001322func (c *ccTest) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
1323 depNames = c.CCBinary.DepNames(ctx, depNames)
1324 depNames.StaticLibs = append(depNames.StaticLibs, "libgtest", "libgtest_main")
1325 return depNames
Dan Albertc403f7c2015-03-18 14:01:18 -07001326}
1327
Colin Cross97ba0732015-03-23 17:50:24 -07001328func (c *ccTest) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Colin Crossf6566ed2015-03-24 11:13:38 -07001329 if ctx.Device() {
Tim Kilbourn5ccc7302015-03-19 10:02:21 -07001330 ctx.InstallFile("../data/nativetest/"+ctx.ModuleName(), c.out)
Dan Albertc403f7c2015-03-18 14:01:18 -07001331 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001332 c.CCBinary.installModule(ctx, flags)
Dan Albertc403f7c2015-03-18 14:01:18 -07001333 }
1334}
1335
Colin Cross97ba0732015-03-23 17:50:24 -07001336func CCTestFactory() (blueprint.Module, []interface{}) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001337 module := &ccTest{}
Colin Cross1f8f2342015-03-26 16:09:47 -07001338 return NewCCBinary(&module.CCBinary, module, common.HostAndDeviceSupported,
1339 &module.testProperties)
Colin Cross6b290692015-03-19 14:05:33 -07001340}
1341
1342func TestPerSrcMutator(mctx blueprint.EarlyMutatorContext) {
1343 if test, ok := mctx.Module().(*ccTest); ok {
1344 if test.testProperties.Test_per_src {
1345 testNames := make([]string, len(test.properties.Srcs))
1346 for i, src := range test.properties.Srcs {
1347 testNames[i] = strings.TrimSuffix(src, filepath.Ext(src))
1348 }
1349 tests := mctx.CreateLocalVariations(testNames...)
1350 for i, src := range test.properties.Srcs {
1351 tests[i].(*ccTest).properties.Srcs = []string{src}
Colin Cross97ba0732015-03-23 17:50:24 -07001352 tests[i].(*ccTest).BinaryProperties.Stem = testNames[i]
Colin Cross6b290692015-03-19 14:05:33 -07001353 }
1354 }
1355 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001356}
1357
1358//
1359// Static library
1360//
1361
Colin Cross97ba0732015-03-23 17:50:24 -07001362func CCLibraryStaticFactory() (blueprint.Module, []interface{}) {
1363 module := &CCLibrary{}
1364 module.LibraryProperties.BuildStatic = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001365
Colin Cross97ba0732015-03-23 17:50:24 -07001366 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001367}
1368
1369//
1370// Shared libraries
1371//
1372
Colin Cross97ba0732015-03-23 17:50:24 -07001373func CCLibrarySharedFactory() (blueprint.Module, []interface{}) {
1374 module := &CCLibrary{}
1375 module.LibraryProperties.BuildShared = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001376
Colin Cross97ba0732015-03-23 17:50:24 -07001377 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001378}
1379
1380//
1381// Host static library
1382//
1383
Colin Cross97ba0732015-03-23 17:50:24 -07001384func CCLibraryHostStaticFactory() (blueprint.Module, []interface{}) {
1385 module := &CCLibrary{}
1386 module.LibraryProperties.BuildStatic = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001387
Colin Cross97ba0732015-03-23 17:50:24 -07001388 return NewCCLibrary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001389}
1390
1391//
1392// Host Shared libraries
1393//
1394
Colin Cross97ba0732015-03-23 17:50:24 -07001395func CCLibraryHostSharedFactory() (blueprint.Module, []interface{}) {
1396 module := &CCLibrary{}
1397 module.LibraryProperties.BuildShared = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001398
Colin Cross97ba0732015-03-23 17:50:24 -07001399 return NewCCLibrary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001400}
1401
1402//
1403// Host Binaries
1404//
1405
Colin Cross97ba0732015-03-23 17:50:24 -07001406func CCBinaryHostFactory() (blueprint.Module, []interface{}) {
1407 module := &CCBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001408
Colin Cross97ba0732015-03-23 17:50:24 -07001409 return NewCCBinary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001410}
1411
1412//
Colin Cross1f8f2342015-03-26 16:09:47 -07001413// Host Tests
1414//
1415
1416func CCTestHostFactory() (blueprint.Module, []interface{}) {
1417 module := &ccTest{}
1418 return NewCCBinary(&module.CCBinary, module, common.HostSupported,
1419 &module.testProperties)
1420}
1421
1422//
Colin Cross3f40fa42015-01-30 17:27:36 -08001423// Device libraries shipped with gcc
1424//
1425
1426type toolchainLibrary struct {
Colin Cross97ba0732015-03-23 17:50:24 -07001427 CCLibrary
Colin Cross3f40fa42015-01-30 17:27:36 -08001428}
1429
1430func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1431 // toolchain libraries can't have any dependencies
1432 return nil
1433}
1434
Colin Cross21b9a242015-03-24 14:15:58 -07001435func (*toolchainLibrary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Cross3f40fa42015-01-30 17:27:36 -08001436 // toolchain libraries can't have any dependencies
Colin Cross21b9a242015-03-24 14:15:58 -07001437 return CCDeps{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001438}
1439
Colin Cross97ba0732015-03-23 17:50:24 -07001440func ToolchainLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001441 module := &toolchainLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001442
Colin Cross97ba0732015-03-23 17:50:24 -07001443 module.LibraryProperties.BuildStatic = true
1444
Colin Cross21b9a242015-03-24 14:15:58 -07001445 return newCCBase(&module.ccBase, module, common.DeviceSupported, common.MultilibBoth,
1446 &module.LibraryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001447}
1448
1449func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
Colin Cross97ba0732015-03-23 17:50:24 -07001450 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001451
1452 libName := ctx.ModuleName() + staticLibraryExtension
1453 outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
1454
1455 CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
1456
1457 c.out = outputFile
1458
1459 ctx.CheckbuildFile(outputFile)
1460}
1461
Colin Cross97ba0732015-03-23 17:50:24 -07001462func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001463 // Toolchain libraries do not get installed.
1464}
1465
Dan Albertbe961682015-03-18 23:38:50 -07001466// NDK prebuilt libraries.
1467//
1468// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
1469// either (with the exception of the shared STLs, which are installed to the app's directory rather
1470// than to the system image).
1471
1472func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) string {
1473 return fmt.Sprintf("%s/prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
1474 ctx.Config().(Config).SrcDir(), version, toolchain.Name())
1475}
1476
1477type ndkPrebuiltLibrary struct {
1478 CCLibrary
1479}
1480
1481func (*ndkPrebuiltLibrary) AndroidDynamicDependencies(
1482 ctx common.AndroidDynamicDependerModuleContext) []string {
1483
1484 // NDK libraries can't have any dependencies
1485 return nil
1486}
1487
1488func (*ndkPrebuiltLibrary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
1489 // NDK libraries can't have any dependencies
1490 return CCDeps{}
1491}
1492
1493func NdkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
1494 module := &ndkPrebuiltLibrary{}
1495 module.LibraryProperties.BuildShared = true
1496 return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
1497}
1498
1499func (c *ndkPrebuiltLibrary) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
1500 deps CCDeps, objFiles []string) {
1501 // A null build step, but it sets up the output path.
1502 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
1503 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
1504 }
1505
1506 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
1507 common.ModuleSrcDir(ctx))
1508
1509 // NDK prebuilt libraries are named like: ndk_LIBNAME.SDK_VERSION.
1510 // We want to translate to just LIBNAME.
1511 libName := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
1512 libDir := getNdkLibDir(ctx, flags.Toolchain, c.properties.Sdk_version)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001513 c.out = filepath.Join(libDir, libName+sharedLibraryExtension)
Dan Albertbe961682015-03-18 23:38:50 -07001514}
1515
1516func (c *ndkPrebuiltLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
1517 // Toolchain libraries do not get installed.
1518}
1519
1520// The NDK STLs are slightly different from the prebuilt system libraries:
1521// * Are not specific to each platform version.
1522// * The libraries are not in a predictable location for each STL.
1523
1524type ndkPrebuiltStl struct {
1525 ndkPrebuiltLibrary
1526}
1527
1528type ndkPrebuiltStaticStl struct {
1529 ndkPrebuiltStl
1530}
1531
1532type ndkPrebuiltSharedStl struct {
1533 ndkPrebuiltStl
1534}
1535
1536func NdkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
1537 module := &ndkPrebuiltSharedStl{}
1538 module.LibraryProperties.BuildShared = true
1539 return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
1540}
1541
1542func NdkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
1543 module := &ndkPrebuiltStaticStl{}
1544 module.LibraryProperties.BuildStatic = true
1545 return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
1546}
1547
1548func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) string {
1549 gccVersion := toolchain.GccVersion()
1550 var libDir string
1551 switch stl {
1552 case "libstlport":
1553 libDir = "cxx-stl/stlport/libs"
1554 case "libc++":
1555 libDir = "cxx-stl/llvm-libc++/libs"
1556 case "libgnustl":
1557 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
1558 }
1559
1560 if libDir != "" {
1561 ndkSrcRoot := ctx.Config().(Config).SrcDir() + "/prebuilts/ndk/current/sources"
1562 return fmt.Sprintf("%s/%s/%s", ndkSrcRoot, libDir, ctx.Arch().Abi)
1563 }
1564
1565 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
1566 return ""
1567}
1568
1569func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
1570 deps CCDeps, objFiles []string) {
1571 // A null build step, but it sets up the output path.
1572 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
1573 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
1574 }
1575
1576 c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
1577 common.ModuleSrcDir(ctx))
1578
1579 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
1580 libExt := sharedLibraryExtension
1581 if c.LibraryProperties.BuildStatic {
1582 libExt = staticLibraryExtension
1583 }
1584
1585 stlName := strings.TrimSuffix(libName, "_shared")
1586 stlName = strings.TrimSuffix(stlName, "_static")
1587 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
1588 c.out = libDir + "/" + libName + libExt
1589}
1590
Colin Cross3f40fa42015-01-30 17:27:36 -08001591func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001592 if c, ok := mctx.Module().(ccLinkedInterface); ok {
Colin Cross3f40fa42015-01-30 17:27:36 -08001593 var modules []blueprint.Module
Colin Crossed4cf0b2015-03-26 14:43:45 -07001594 if c.buildStatic() && c.buildShared() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001595 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossed4cf0b2015-03-26 14:43:45 -07001596 modules[0].(ccLinkedInterface).setStatic()
1597 modules[1].(ccLinkedInterface).setShared()
1598 } else if c.buildStatic() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001599 modules = mctx.CreateLocalVariations("static")
Colin Crossed4cf0b2015-03-26 14:43:45 -07001600 modules[0].(ccLinkedInterface).setStatic()
1601 } else if c.buildShared() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001602 modules = mctx.CreateLocalVariations("shared")
Colin Crossed4cf0b2015-03-26 14:43:45 -07001603 modules[0].(ccLinkedInterface).setShared()
Colin Cross3f40fa42015-01-30 17:27:36 -08001604 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001605 panic(fmt.Errorf("ccLibrary %q not static or shared", mctx.ModuleName()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001606 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001607
1608 if _, ok := c.(ccLibraryInterface); ok {
1609 reuseFrom := modules[0].(ccLibraryInterface)
1610 for _, m := range modules {
1611 m.(ccLibraryInterface).setReuseFrom(reuseFrom)
Colin Cross3f40fa42015-01-30 17:27:36 -08001612 }
1613 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001614 }
1615}