blob: 2ade59cc1d2c6f55d907857365590c25f554e1ed [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"
Colin Cross0af4b842015-04-30 16:36:18 -070024 "runtime"
Colin Cross3f40fa42015-01-30 17:27:36 -080025 "strings"
26
Colin Cross97ba0732015-03-23 17:50:24 -070027 "github.com/google/blueprint"
28 "github.com/google/blueprint/pathtools"
29
Colin Cross463a90e2015-06-17 14:20:06 -070030 "android/soong"
Colin Cross3f40fa42015-01-30 17:27:36 -080031 "android/soong/common"
Colin Cross5049f022015-03-18 13:28:46 -070032 "android/soong/genrule"
Colin Cross3f40fa42015-01-30 17:27:36 -080033)
34
Colin Cross463a90e2015-06-17 14:20:06 -070035func init() {
36 soong.RegisterModuleType("cc_library_static", CCLibraryStaticFactory)
37 soong.RegisterModuleType("cc_library_shared", CCLibrarySharedFactory)
38 soong.RegisterModuleType("cc_library", CCLibraryFactory)
39 soong.RegisterModuleType("cc_object", CCObjectFactory)
40 soong.RegisterModuleType("cc_binary", CCBinaryFactory)
41 soong.RegisterModuleType("cc_test", CCTestFactory)
42 soong.RegisterModuleType("cc_benchmark", CCBenchmarkFactory)
43
44 soong.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
45 soong.RegisterModuleType("ndk_prebuilt_library", NdkPrebuiltLibraryFactory)
46 soong.RegisterModuleType("ndk_prebuilt_object", NdkPrebuiltObjectFactory)
47 soong.RegisterModuleType("ndk_prebuilt_static_stl", NdkPrebuiltStaticStlFactory)
48 soong.RegisterModuleType("ndk_prebuilt_shared_stl", NdkPrebuiltSharedStlFactory)
49
50 soong.RegisterModuleType("cc_library_host_static", CCLibraryHostStaticFactory)
51 soong.RegisterModuleType("cc_library_host_shared", CCLibraryHostSharedFactory)
52 soong.RegisterModuleType("cc_binary_host", CCBinaryHostFactory)
53 soong.RegisterModuleType("cc_test_host", CCTestHostFactory)
54 soong.RegisterModuleType("cc_benchmark_host", CCBenchmarkHostFactory)
55
56 // LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
57 // the Go initialization order because this package depends on common, so common's init
58 // functions will run first.
59 soong.RegisterEarlyMutator("link", LinkageMutator)
60 soong.RegisterEarlyMutator("test_per_src", TestPerSrcMutator)
61}
62
Colin Cross3f40fa42015-01-30 17:27:36 -080063var (
Colin Cross1332b002015-04-07 17:11:30 -070064 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
65 SrcDir = pctx.VariableConfigMethod("SrcDir", common.Config.SrcDir)
Colin Cross3f40fa42015-01-30 17:27:36 -080066
67 LibcRoot = pctx.StaticVariable("LibcRoot", "${SrcDir}/bionic/libc")
68 LibmRoot = pctx.StaticVariable("LibmRoot", "${SrcDir}/bionic/libm")
69)
70
71// Flags used by lots of devices. Putting them in package static variables will save bytes in
72// build.ninja so they aren't repeated for every file
73var (
74 commonGlobalCflags = []string{
75 "-DANDROID",
76 "-fmessage-length=0",
77 "-W",
78 "-Wall",
79 "-Wno-unused",
80 "-Winit-self",
81 "-Wpointer-arith",
82
83 // COMMON_RELEASE_CFLAGS
84 "-DNDEBUG",
85 "-UDEBUG",
86 }
87
88 deviceGlobalCflags = []string{
89 // TARGET_ERROR_FLAGS
90 "-Werror=return-type",
91 "-Werror=non-virtual-dtor",
92 "-Werror=address",
93 "-Werror=sequence-point",
94 }
95
96 hostGlobalCflags = []string{}
97
98 commonGlobalCppflags = []string{
99 "-Wsign-promo",
100 "-std=gnu++11",
101 }
102)
103
104func init() {
105 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
106 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
107 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
108
109 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
110
111 pctx.StaticVariable("commonClangGlobalCflags",
112 strings.Join(clangFilterUnknownCflags(commonGlobalCflags), " "))
113 pctx.StaticVariable("deviceClangGlobalCflags",
114 strings.Join(clangFilterUnknownCflags(deviceGlobalCflags), " "))
115 pctx.StaticVariable("hostClangGlobalCflags",
116 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Tim Kilbournf2948142015-03-11 12:03:03 -0700117 pctx.StaticVariable("commonClangGlobalCppflags",
118 strings.Join(clangFilterUnknownCflags(commonGlobalCppflags), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800119
120 // Everything in this list is a crime against abstraction and dependency tracking.
121 // Do not add anything to this list.
122 pctx.StaticVariable("commonGlobalIncludes", strings.Join([]string{
123 "-isystem ${SrcDir}/system/core/include",
124 "-isystem ${SrcDir}/hardware/libhardware/include",
125 "-isystem ${SrcDir}/hardware/libhardware_legacy/include",
126 "-isystem ${SrcDir}/hardware/ril/include",
127 "-isystem ${SrcDir}/libnativehelper/include",
128 "-isystem ${SrcDir}/frameworks/native/include",
129 "-isystem ${SrcDir}/frameworks/native/opengl/include",
130 "-isystem ${SrcDir}/frameworks/av/include",
131 "-isystem ${SrcDir}/frameworks/base/include",
132 }, " "))
133
134 pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/${HostPrebuiltTag}/host/3.6/bin/")
135}
136
Colin Cross3f40fa42015-01-30 17:27:36 -0800137// Building C/C++ code is handled by objects that satisfy this interface via composition
Colin Cross97ba0732015-03-23 17:50:24 -0700138type CCModuleType interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800139 common.AndroidModule
140
Colin Crossfa138792015-04-24 17:31:52 -0700141 // Modify property values after parsing Blueprints file but before starting dependency
142 // resolution or build rule generation
143 ModifyProperties(common.AndroidBaseContext)
144
Colin Cross21b9a242015-03-24 14:15:58 -0700145 // Modify the ccFlags
Colin Cross0676e2d2015-04-24 17:39:18 -0700146 flags(common.AndroidModuleContext, CCFlags) CCFlags
Colin Cross3f40fa42015-01-30 17:27:36 -0800147
Colin Cross21b9a242015-03-24 14:15:58 -0700148 // Return list of dependency names for use in AndroidDynamicDependencies and in depsToPaths
Colin Cross0676e2d2015-04-24 17:39:18 -0700149 depNames(common.AndroidBaseContext, CCDeps) CCDeps
Colin Cross3f40fa42015-01-30 17:27:36 -0800150
151 // Compile objects into final module
Colin Cross97ba0732015-03-23 17:50:24 -0700152 compileModule(common.AndroidModuleContext, CCFlags, CCDeps, []string)
Colin Cross3f40fa42015-01-30 17:27:36 -0800153
Dan Albertc403f7c2015-03-18 14:01:18 -0700154 // Install the built module.
Colin Cross97ba0732015-03-23 17:50:24 -0700155 installModule(common.AndroidModuleContext, CCFlags)
Dan Albertc403f7c2015-03-18 14:01:18 -0700156
Colin Cross3f40fa42015-01-30 17:27:36 -0800157 // Return the output file (.o, .a or .so) for use by other modules
158 outputFile() string
159}
160
Colin Cross97ba0732015-03-23 17:50:24 -0700161type CCDeps struct {
Colin Cross28344522015-04-22 13:07:53 -0700162 StaticLibs, SharedLibs, LateStaticLibs, WholeStaticLibs, ObjFiles, Cflags []string
Colin Crossc472d572015-03-17 15:06:21 -0700163
Colin Cross21b9a242015-03-24 14:15:58 -0700164 WholeStaticLibObjFiles []string
165
Colin Cross97ba0732015-03-23 17:50:24 -0700166 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700167}
168
Colin Cross97ba0732015-03-23 17:50:24 -0700169type CCFlags struct {
Colin Cross28344522015-04-22 13:07:53 -0700170 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
171 AsFlags []string // Flags that apply to assembly source files
172 CFlags []string // Flags that apply to C and C++ source files
173 ConlyFlags []string // Flags that apply to C source files
174 CppFlags []string // Flags that apply to C++ source files
175 YaccFlags []string // Flags that apply to Yacc source files
176 LdFlags []string // Flags that apply to linker command lines
177
178 Nocrt bool
179 Toolchain Toolchain
180 Clang bool
Colin Crossc472d572015-03-17 15:06:21 -0700181}
182
Colin Cross7d5136f2015-05-11 13:39:40 -0700183// Properties used to compile all C or C++ modules
184type CCBaseProperties struct {
185 // list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700186 Srcs []string `android:"arch_variant"`
187
188 // list of source files that should not be used to build the C/C++ module.
189 // This is most useful in the arch/multilib variants to remove non-common files
190 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700191
192 // list of module-specific flags that will be used for C and C++ compiles.
193 Cflags []string `android:"arch_variant"`
194
195 // list of module-specific flags that will be used for C++ compiles
196 Cppflags []string `android:"arch_variant"`
197
198 // list of module-specific flags that will be used for C compiles
199 Conlyflags []string `android:"arch_variant"`
200
201 // list of module-specific flags that will be used for .S compiles
202 Asflags []string `android:"arch_variant"`
203
204 // list of module-specific flags that will be used for .y and .yy compiles
205 Yaccflags []string
206
207 // list of module-specific flags that will be used for all link steps
208 Ldflags []string `android:"arch_variant"`
209
210 // the instruction set architecture to use to compile the C/C++
211 // module.
212 Instruction_set string `android:"arch_variant"`
213
214 // list of directories relative to the root of the source tree that will
215 // be added to the include path using -I.
216 // If possible, don't use this. If adding paths from the current directory use
217 // local_include_dirs, if adding paths from other modules use export_include_dirs in
218 // that module.
219 Include_dirs []string `android:"arch_variant"`
220
Colin Cross39d97f22015-09-14 12:30:50 -0700221 // list of files relative to the root of the source tree that will be included
222 // using -include.
223 // If possible, don't use this.
224 Include_files []string `android:"arch_variant"`
225
Colin Cross7d5136f2015-05-11 13:39:40 -0700226 // list of directories relative to the Blueprints file that will
227 // be added to the include path using -I
228 Local_include_dirs []string `android:"arch_variant"`
229
Colin Cross39d97f22015-09-14 12:30:50 -0700230 // list of files relative to the Blueprints file that will be included
231 // using -include.
232 // If possible, don't use this.
233 Local_include_files []string `android:"arch_variant"`
234
Colin Cross7d5136f2015-05-11 13:39:40 -0700235 // list of directories relative to the Blueprints file that will
236 // be added to the include path using -I for any module that links against this module
237 Export_include_dirs []string `android:"arch_variant"`
238
239 // list of module-specific flags that will be used for C and C++ compiles when
240 // compiling with clang
241 Clang_cflags []string `android:"arch_variant"`
242
243 // list of module-specific flags that will be used for .S compiles when
244 // compiling with clang
245 Clang_asflags []string `android:"arch_variant"`
246
247 // list of system libraries that will be dynamically linked to
248 // shared library and executable modules. If unset, generally defaults to libc
249 // and libm. Set to [] to prevent linking against libc and libm.
250 System_shared_libs []string
251
252 // list of modules whose object files should be linked into this module
253 // in their entirety. For static library modules, all of the .o files from the intermediate
254 // directory of the dependency will be linked into this modules .a file. For a shared library,
255 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
256 Whole_static_libs []string `android:"arch_variant"`
257
258 // list of modules that should be statically linked into this module.
259 Static_libs []string `android:"arch_variant"`
260
261 // list of modules that should be dynamically linked into this module.
262 Shared_libs []string `android:"arch_variant"`
263
264 // allow the module to contain undefined symbols. By default,
265 // modules cannot contain undefined symbols that are not satisified by their immediate
266 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
267 // This flag should only be necessary for compiling low-level libraries like libc.
268 Allow_undefined_symbols bool
269
270 // don't link in crt_begin and crt_end. This flag should only be necessary for
271 // compiling crt or libc.
272 Nocrt bool `android:"arch_variant"`
273
274 // don't insert default compiler flags into asflags, cflags,
275 // cppflags, conlyflags, ldflags, or include_dirs
276 No_default_compiler_flags bool
277
278 // compile module with clang instead of gcc
279 Clang bool `android:"arch_variant"`
280
281 // pass -frtti instead of -fno-rtti
282 Rtti bool
283
284 // -l arguments to pass to linker for host-provided shared libraries
285 Host_ldlibs []string `android:"arch_variant"`
286
287 // select the STL library to use. Possible values are "libc++", "libc++_static",
288 // "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
289 // default
290 Stl string
291
292 // Set for combined shared/static libraries to prevent compiling object files a second time
293 SkipCompileObjs bool `blueprint:"mutated"`
294
295 Debug, Release struct {
296 // list of module-specific flags that will be used for C and C++ compiles in debug or
297 // release builds
298 Cflags []string `android:"arch_variant"`
299 } `android:"arch_variant"`
300
301 // Minimum sdk version supported when compiling against the ndk
302 Sdk_version string
303
304 // install to a subdirectory of the default install path for the module
305 Relative_install_path string
306}
307
Colin Crossfa138792015-04-24 17:31:52 -0700308// CCBase contains the properties and members used by all C/C++ module types, and implements
Colin Crossc472d572015-03-17 15:06:21 -0700309// the blueprint.Module interface. It expects to be embedded into an outer specialization struct,
310// and uses a ccModuleType interface to that struct to create the build steps.
Colin Crossfa138792015-04-24 17:31:52 -0700311type CCBase struct {
Colin Crossc472d572015-03-17 15:06:21 -0700312 common.AndroidModuleBase
Colin Cross97ba0732015-03-23 17:50:24 -0700313 module CCModuleType
Colin Crossc472d572015-03-17 15:06:21 -0700314
Colin Cross7d5136f2015-05-11 13:39:40 -0700315 Properties CCBaseProperties
Colin Crossfa138792015-04-24 17:31:52 -0700316
317 unused struct {
318 Asan bool
319 Native_coverage bool
320 Strip string
321 Tags []string
322 Required []string
323 }
Colin Crossc472d572015-03-17 15:06:21 -0700324
325 installPath string
Colin Cross74d1ec02015-04-28 13:30:13 -0700326
327 savedDepNames CCDeps
Colin Crossc472d572015-03-17 15:06:21 -0700328}
329
Colin Crossfa138792015-04-24 17:31:52 -0700330func newCCBase(base *CCBase, module CCModuleType, hod common.HostOrDeviceSupported,
Colin Crossc472d572015-03-17 15:06:21 -0700331 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
332
333 base.module = module
334
Colin Crossfa138792015-04-24 17:31:52 -0700335 props = append(props, &base.Properties, &base.unused)
Colin Crossc472d572015-03-17 15:06:21 -0700336
Colin Cross5049f022015-03-18 13:28:46 -0700337 return common.InitAndroidArchModule(module, hod, multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700338}
339
Colin Crossfa138792015-04-24 17:31:52 -0700340func (c *CCBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800341 toolchain := c.findToolchain(ctx)
342 if ctx.Failed() {
343 return
344 }
345
Colin Cross21b9a242015-03-24 14:15:58 -0700346 flags := c.collectFlags(ctx, toolchain)
Colin Cross3f40fa42015-01-30 17:27:36 -0800347 if ctx.Failed() {
348 return
349 }
350
Colin Cross74d1ec02015-04-28 13:30:13 -0700351 deps := c.depsToPaths(ctx, c.savedDepNames)
Colin Cross3f40fa42015-01-30 17:27:36 -0800352 if ctx.Failed() {
353 return
354 }
355
Colin Cross28344522015-04-22 13:07:53 -0700356 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700357
Colin Cross581c1892015-04-07 16:50:10 -0700358 objFiles := c.compileObjs(ctx, flags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800359 if ctx.Failed() {
360 return
361 }
362
Colin Cross581c1892015-04-07 16:50:10 -0700363 generatedObjFiles := c.compileGeneratedObjs(ctx, flags)
Colin Cross5049f022015-03-18 13:28:46 -0700364 if ctx.Failed() {
365 return
366 }
367
368 objFiles = append(objFiles, generatedObjFiles...)
369
Colin Cross3f40fa42015-01-30 17:27:36 -0800370 c.ccModuleType().compileModule(ctx, flags, deps, objFiles)
371 if ctx.Failed() {
372 return
373 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700374
375 c.ccModuleType().installModule(ctx, flags)
376 if ctx.Failed() {
377 return
378 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800379}
380
Colin Crossfa138792015-04-24 17:31:52 -0700381func (c *CCBase) ccModuleType() CCModuleType {
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 return c.module
383}
384
Colin Crossfa138792015-04-24 17:31:52 -0700385var _ common.AndroidDynamicDepender = (*CCBase)(nil)
Colin Cross3f40fa42015-01-30 17:27:36 -0800386
Colin Crossfa138792015-04-24 17:31:52 -0700387func (c *CCBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
Colin Cross3f40fa42015-01-30 17:27:36 -0800388 arch := ctx.Arch()
Colin Crossd3ba0392015-05-07 14:11:29 -0700389 hod := ctx.HostOrDevice()
390 factory := toolchainFactories[hod][arch.ArchType]
Colin Cross3f40fa42015-01-30 17:27:36 -0800391 if factory == nil {
392 panic(fmt.Sprintf("Toolchain not found for %s arch %q",
Colin Crossd3ba0392015-05-07 14:11:29 -0700393 hod.String(), arch.String()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800394 }
395 return factory(arch.ArchVariant, arch.CpuVariant)
396}
397
Colin Crossfa138792015-04-24 17:31:52 -0700398func (c *CCBase) ModifyProperties(ctx common.AndroidBaseContext) {
399}
400
Colin Crosse11befc2015-04-27 17:49:17 -0700401func (c *CCBase) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Crossfa138792015-04-24 17:31:52 -0700402 depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.Properties.Whole_static_libs...)
403 depNames.StaticLibs = append(depNames.StaticLibs, c.Properties.Static_libs...)
404 depNames.SharedLibs = append(depNames.SharedLibs, c.Properties.Shared_libs...)
Colin Cross21b9a242015-03-24 14:15:58 -0700405
Colin Cross21b9a242015-03-24 14:15:58 -0700406 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -0800407}
408
Colin Crossfa138792015-04-24 17:31:52 -0700409func (c *CCBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
410 c.module.ModifyProperties(ctx)
411
Colin Cross74d1ec02015-04-28 13:30:13 -0700412 c.savedDepNames = c.module.depNames(ctx, CCDeps{})
413 c.savedDepNames.WholeStaticLibs = lastUniqueElements(c.savedDepNames.WholeStaticLibs)
414 c.savedDepNames.StaticLibs = lastUniqueElements(c.savedDepNames.StaticLibs)
415 c.savedDepNames.SharedLibs = lastUniqueElements(c.savedDepNames.SharedLibs)
416
417 staticLibs := c.savedDepNames.WholeStaticLibs
418 staticLibs = append(staticLibs, c.savedDepNames.StaticLibs...)
419 staticLibs = append(staticLibs, c.savedDepNames.LateStaticLibs...)
Colin Cross21b9a242015-03-24 14:15:58 -0700420 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800421
Colin Cross74d1ec02015-04-28 13:30:13 -0700422 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.savedDepNames.SharedLibs...)
Colin Cross21b9a242015-03-24 14:15:58 -0700423
Colin Cross74d1ec02015-04-28 13:30:13 -0700424 ret := append([]string(nil), c.savedDepNames.ObjFiles...)
425 if c.savedDepNames.CrtBegin != "" {
426 ret = append(ret, c.savedDepNames.CrtBegin)
Colin Cross21b9a242015-03-24 14:15:58 -0700427 }
Colin Cross74d1ec02015-04-28 13:30:13 -0700428 if c.savedDepNames.CrtEnd != "" {
429 ret = append(ret, c.savedDepNames.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700430 }
431
432 return ret
Colin Cross3f40fa42015-01-30 17:27:36 -0800433}
434
435// Create a ccFlags struct that collects the compile flags from global values,
436// per-target values, module type values, and per-module Blueprints properties
Colin Crossfa138792015-04-24 17:31:52 -0700437func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolchain) CCFlags {
Colin Cross97ba0732015-03-23 17:50:24 -0700438 flags := CCFlags{
Colin Crossfa138792015-04-24 17:31:52 -0700439 CFlags: c.Properties.Cflags,
440 CppFlags: c.Properties.Cppflags,
441 ConlyFlags: c.Properties.Conlyflags,
442 LdFlags: c.Properties.Ldflags,
443 AsFlags: c.Properties.Asflags,
444 YaccFlags: c.Properties.Yaccflags,
445 Nocrt: c.Properties.Nocrt,
Colin Cross97ba0732015-03-23 17:50:24 -0700446 Toolchain: toolchain,
Colin Crossfa138792015-04-24 17:31:52 -0700447 Clang: c.Properties.Clang,
Colin Cross3f40fa42015-01-30 17:27:36 -0800448 }
Colin Cross28344522015-04-22 13:07:53 -0700449
450 // Include dir cflags
Colin Crossf2298272015-05-12 11:36:53 -0700451 common.CheckSrcDirsExist(ctx, c.Properties.Include_dirs, "include_dirs")
452 common.CheckModuleSrcDirsExist(ctx, c.Properties.Local_include_dirs, "local_include_dirs")
453
Colin Crossfa138792015-04-24 17:31:52 -0700454 rootIncludeDirs := pathtools.PrefixPaths(c.Properties.Include_dirs, ctx.AConfig().SrcDir())
455 localIncludeDirs := pathtools.PrefixPaths(c.Properties.Local_include_dirs, common.ModuleSrcDir(ctx))
Colin Cross28344522015-04-22 13:07:53 -0700456 flags.GlobalFlags = append(flags.GlobalFlags,
457 includeDirsToFlags(rootIncludeDirs),
458 includeDirsToFlags(localIncludeDirs))
459
Colin Cross39d97f22015-09-14 12:30:50 -0700460 rootIncludeFiles := pathtools.PrefixPaths(c.Properties.Include_files, ctx.AConfig().SrcDir())
461 localIncludeFiles := pathtools.PrefixPaths(c.Properties.Local_include_files, common.ModuleSrcDir(ctx))
462
463 flags.GlobalFlags = append(flags.GlobalFlags,
464 includeFilesToFlags(rootIncludeFiles),
465 includeFilesToFlags(localIncludeFiles))
466
Colin Crossfa138792015-04-24 17:31:52 -0700467 if !c.Properties.No_default_compiler_flags {
468 if c.Properties.Sdk_version == "" || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -0700469 flags.GlobalFlags = append(flags.GlobalFlags,
470 "${commonGlobalIncludes}",
471 toolchain.IncludeFlags(),
472 "-I${SrcDir}/libnativehelper/include/nativehelper")
473 }
474
475 flags.GlobalFlags = append(flags.GlobalFlags, []string{
476 "-I" + common.ModuleSrcDir(ctx),
477 "-I" + common.ModuleOutDir(ctx),
478 "-I" + common.ModuleGenDir(ctx),
479 }...)
480 }
481
Colin Crossfa138792015-04-24 17:31:52 -0700482 instructionSet := c.Properties.Instruction_set
Tim Kilbourn1a9bf262015-03-18 12:28:32 -0700483 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
484 if err != nil {
485 ctx.ModuleErrorf("%s", err)
486 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800487
Colin Crossaf19a292015-03-18 12:07:10 -0700488 // TODO: debug
Colin Crossfa138792015-04-24 17:31:52 -0700489 flags.CFlags = append(flags.CFlags, c.Properties.Release.Cflags...)
Colin Crossaf19a292015-03-18 12:07:10 -0700490
Colin Cross28d76592015-03-26 16:14:04 -0700491 if ctx.Host() && !ctx.ContainsProperty("clang") {
Colin Cross97ba0732015-03-23 17:50:24 -0700492 flags.Clang = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800493 }
494
Colin Cross97ba0732015-03-23 17:50:24 -0700495 if flags.Clang {
496 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossfa138792015-04-24 17:31:52 -0700497 flags.CFlags = append(flags.CFlags, c.Properties.Clang_cflags...)
498 flags.AsFlags = append(flags.AsFlags, c.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -0700499 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
500 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
501 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800502
Colin Cross97ba0732015-03-23 17:50:24 -0700503 flags.CFlags = append(flags.CFlags, "${clangExtraCflags}")
504 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Crossf6566ed2015-03-24 11:13:38 -0700505 if ctx.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -0700506 flags.CFlags = append(flags.CFlags, "${clangExtraTargetCflags}")
Colin Crossbdd7b1c2015-03-16 16:21:20 -0700507 }
508
Colin Cross3f40fa42015-01-30 17:27:36 -0800509 target := "-target " + toolchain.ClangTriple()
510 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
511
Colin Cross97ba0732015-03-23 17:50:24 -0700512 flags.CFlags = append(flags.CFlags, target, gccPrefix)
513 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
514 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800515 }
516
Colin Crossfa138792015-04-24 17:31:52 -0700517 if !c.Properties.No_default_compiler_flags {
518 if ctx.Device() && !c.Properties.Allow_undefined_symbols {
Colin Cross97ba0732015-03-23 17:50:24 -0700519 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
Colin Cross3f40fa42015-01-30 17:27:36 -0800520 }
521
Colin Cross56b4d452015-04-21 17:38:44 -0700522 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
523
Colin Cross97ba0732015-03-23 17:50:24 -0700524 if flags.Clang {
525 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -0700526 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800527 toolchain.ClangCflags(),
528 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -0700529 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800530 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700531 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -0700532 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800533 toolchain.Cflags(),
534 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -0700535 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800536 }
537
Colin Crossf6566ed2015-03-24 11:13:38 -0700538 if ctx.Device() {
Colin Crossfa138792015-04-24 17:31:52 -0700539 if c.Properties.Rtti {
Colin Cross97ba0732015-03-23 17:50:24 -0700540 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800541 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700542 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800543 }
544 }
545
Colin Cross97ba0732015-03-23 17:50:24 -0700546 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -0800547
Colin Cross97ba0732015-03-23 17:50:24 -0700548 if flags.Clang {
549 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
550 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
Colin Cross3f40fa42015-01-30 17:27:36 -0800551 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700552 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
553 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
Colin Cross3f40fa42015-01-30 17:27:36 -0800554 }
Colin Cross28344522015-04-22 13:07:53 -0700555
556 if ctx.Host() {
Colin Crossfa138792015-04-24 17:31:52 -0700557 flags.LdFlags = append(flags.LdFlags, c.Properties.Host_ldlibs...)
Colin Cross28344522015-04-22 13:07:53 -0700558 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800559 }
560
Colin Cross0676e2d2015-04-24 17:39:18 -0700561 flags = c.ccModuleType().flags(ctx, flags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800562
563 // Optimization to reduce size of build.ninja
564 // Replace the long list of flags for each file with a module-local variable
Colin Cross97ba0732015-03-23 17:50:24 -0700565 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
566 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
567 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
568 flags.CFlags = []string{"$cflags"}
569 flags.CppFlags = []string{"$cppflags"}
570 flags.AsFlags = []string{"$asflags"}
Colin Cross3f40fa42015-01-30 17:27:36 -0800571
572 return flags
573}
574
Colin Cross0676e2d2015-04-24 17:39:18 -0700575func (c *CCBase) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Cross3f40fa42015-01-30 17:27:36 -0800576 return flags
577}
578
579// Compile a list of source files into objects a specified subdirectory
Colin Crossfa138792015-04-24 17:31:52 -0700580func (c *CCBase) customCompileObjs(ctx common.AndroidModuleContext, flags CCFlags,
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700581 subdir string, srcFiles, excludes []string) []string {
Colin Cross581c1892015-04-07 16:50:10 -0700582
583 buildFlags := ccFlagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800584
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700585 srcFiles = ctx.ExpandSources(srcFiles, excludes)
Colin Cross581c1892015-04-07 16:50:10 -0700586 srcFiles, deps := genSources(ctx, srcFiles, buildFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800587
Colin Cross581c1892015-04-07 16:50:10 -0700588 return TransformSourceToObj(ctx, subdir, srcFiles, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -0800589}
590
Colin Crossfa138792015-04-24 17:31:52 -0700591// Compile files listed in c.Properties.Srcs into objects
592func (c *CCBase) compileObjs(ctx common.AndroidModuleContext, flags CCFlags) []string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800593
Colin Crossfa138792015-04-24 17:31:52 -0700594 if c.Properties.SkipCompileObjs {
Colin Cross3f40fa42015-01-30 17:27:36 -0800595 return nil
596 }
597
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700598 return c.customCompileObjs(ctx, flags, "", c.Properties.Srcs, c.Properties.Exclude_srcs)
Colin Cross3f40fa42015-01-30 17:27:36 -0800599}
600
Colin Cross5049f022015-03-18 13:28:46 -0700601// Compile generated source files from dependencies
Colin Crossfa138792015-04-24 17:31:52 -0700602func (c *CCBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags CCFlags) []string {
Colin Cross5049f022015-03-18 13:28:46 -0700603 var srcs []string
604
Colin Crossfa138792015-04-24 17:31:52 -0700605 if c.Properties.SkipCompileObjs {
Colin Cross5049f022015-03-18 13:28:46 -0700606 return nil
607 }
608
609 ctx.VisitDirectDeps(func(module blueprint.Module) {
610 if gen, ok := module.(genrule.SourceFileGenerator); ok {
611 srcs = append(srcs, gen.GeneratedSourceFiles()...)
612 }
613 })
614
615 if len(srcs) == 0 {
616 return nil
617 }
618
Colin Cross581c1892015-04-07 16:50:10 -0700619 return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags), nil)
Colin Cross5049f022015-03-18 13:28:46 -0700620}
621
Colin Crossfa138792015-04-24 17:31:52 -0700622func (c *CCBase) outputFile() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800623 return ""
624}
625
Colin Crossfa138792015-04-24 17:31:52 -0700626func (c *CCBase) depsToPathsFromList(ctx common.AndroidModuleContext,
Colin Cross3f40fa42015-01-30 17:27:36 -0800627 names []string) (modules []common.AndroidModule,
Colin Cross28344522015-04-22 13:07:53 -0700628 outputFiles []string, exportedFlags []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800629
630 for _, n := range names {
631 found := false
632 ctx.VisitDirectDeps(func(m blueprint.Module) {
633 otherName := ctx.OtherModuleName(m)
634 if otherName != n {
635 return
636 }
637
Colin Cross97ba0732015-03-23 17:50:24 -0700638 if a, ok := m.(CCModuleType); ok {
Colin Cross3f40fa42015-01-30 17:27:36 -0800639 if a.Disabled() {
640 // If a cc_library host+device module depends on a library that exists as both
641 // cc_library_shared and cc_library_host_shared, it will end up with two
642 // dependencies with the same name, one of which is marked disabled for each
643 // of host and device. Ignore the disabled one.
644 return
645 }
Colin Crossd3ba0392015-05-07 14:11:29 -0700646 if a.HostOrDevice() != ctx.HostOrDevice() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800647 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
648 otherName)
649 return
650 }
651
652 if outputFile := a.outputFile(); outputFile != "" {
653 if found {
654 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
655 return
656 }
657 outputFiles = append(outputFiles, outputFile)
658 modules = append(modules, a)
Colin Cross28344522015-04-22 13:07:53 -0700659 if i, ok := a.(ccExportedFlagsProducer); ok {
660 exportedFlags = append(exportedFlags, i.exportedFlags()...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800661 }
662 found = true
663 } else {
664 ctx.ModuleErrorf("module %q missing output file", otherName)
665 return
666 }
667 } else {
668 ctx.ModuleErrorf("module %q not an android module", otherName)
669 return
670 }
671 })
672 if !found {
673 ctx.ModuleErrorf("unsatisified dependency on %q", n)
674 }
675 }
676
Colin Cross28344522015-04-22 13:07:53 -0700677 return modules, outputFiles, exportedFlags
Colin Cross3f40fa42015-01-30 17:27:36 -0800678}
679
Colin Cross21b9a242015-03-24 14:15:58 -0700680// Convert depenedency names to paths. Takes a CCDeps containing names and returns a CCDeps
681// containing paths
Colin Crossfa138792015-04-24 17:31:52 -0700682func (c *CCBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) CCDeps {
Colin Cross21b9a242015-03-24 14:15:58 -0700683 var depPaths CCDeps
Colin Cross28344522015-04-22 13:07:53 -0700684 var newCflags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800685
Colin Cross21b9a242015-03-24 14:15:58 -0700686 var wholeStaticLibModules []common.AndroidModule
Colin Cross3f40fa42015-01-30 17:27:36 -0800687
Colin Cross28344522015-04-22 13:07:53 -0700688 wholeStaticLibModules, depPaths.WholeStaticLibs, newCflags =
Colin Cross21b9a242015-03-24 14:15:58 -0700689 c.depsToPathsFromList(ctx, depNames.WholeStaticLibs)
Colin Cross28344522015-04-22 13:07:53 -0700690 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800691
Colin Cross21b9a242015-03-24 14:15:58 -0700692 for _, m := range wholeStaticLibModules {
693 if staticLib, ok := m.(ccLibraryInterface); ok && staticLib.static() {
694 depPaths.WholeStaticLibObjFiles =
695 append(depPaths.WholeStaticLibObjFiles, staticLib.allObjFiles()...)
696 } else {
697 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
698 }
699 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800700
Colin Cross28344522015-04-22 13:07:53 -0700701 _, depPaths.StaticLibs, newCflags = c.depsToPathsFromList(ctx, depNames.StaticLibs)
702 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
Colin Cross21b9a242015-03-24 14:15:58 -0700703
Colin Cross28344522015-04-22 13:07:53 -0700704 _, depPaths.LateStaticLibs, newCflags = c.depsToPathsFromList(ctx, depNames.LateStaticLibs)
705 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
Colin Cross21b9a242015-03-24 14:15:58 -0700706
Colin Cross28344522015-04-22 13:07:53 -0700707 _, depPaths.SharedLibs, newCflags = c.depsToPathsFromList(ctx, depNames.SharedLibs)
708 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
Colin Cross21b9a242015-03-24 14:15:58 -0700709
710 ctx.VisitDirectDeps(func(m blueprint.Module) {
Dan Albertc3144b12015-04-28 18:17:56 -0700711 if obj, ok := m.(ccObjectProvider); ok {
Colin Cross21b9a242015-03-24 14:15:58 -0700712 otherName := ctx.OtherModuleName(m)
713 if otherName == depNames.CrtBegin {
Colin Crossfa138792015-04-24 17:31:52 -0700714 if !c.Properties.Nocrt {
Dan Albertc3144b12015-04-28 18:17:56 -0700715 depPaths.CrtBegin = obj.object().outputFile()
Colin Cross21b9a242015-03-24 14:15:58 -0700716 }
717 } else if otherName == depNames.CrtEnd {
Colin Crossfa138792015-04-24 17:31:52 -0700718 if !c.Properties.Nocrt {
Dan Albertc3144b12015-04-28 18:17:56 -0700719 depPaths.CrtEnd = obj.object().outputFile()
Colin Cross21b9a242015-03-24 14:15:58 -0700720 }
721 } else {
Dan Albertc3144b12015-04-28 18:17:56 -0700722 depPaths.ObjFiles = append(depPaths.ObjFiles, obj.object().outputFile())
Colin Cross21b9a242015-03-24 14:15:58 -0700723 }
724 }
725 })
726
727 return depPaths
Colin Cross3f40fa42015-01-30 17:27:36 -0800728}
729
Colin Cross7d5136f2015-05-11 13:39:40 -0700730type ccLinkedProperties struct {
731 VariantIsShared bool `blueprint:"mutated"`
732 VariantIsStatic bool `blueprint:"mutated"`
733 VariantIsStaticBinary bool `blueprint:"mutated"`
734}
735
Colin Crossfa138792015-04-24 17:31:52 -0700736// CCLinked contains the properties and members used by libraries and executables
737type CCLinked struct {
738 CCBase
Colin Cross7d5136f2015-05-11 13:39:40 -0700739 dynamicProperties ccLinkedProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800740}
741
Colin Crossfa138792015-04-24 17:31:52 -0700742func newCCDynamic(dynamic *CCLinked, module CCModuleType, hod common.HostOrDeviceSupported,
Colin Crossc472d572015-03-17 15:06:21 -0700743 multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
744
Colin Crossed4cf0b2015-03-26 14:43:45 -0700745 props = append(props, &dynamic.dynamicProperties)
746
Colin Crossfa138792015-04-24 17:31:52 -0700747 return newCCBase(&dynamic.CCBase, module, hod, multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700748}
749
Colin Crossfa138792015-04-24 17:31:52 -0700750func (c *CCLinked) systemSharedLibs(ctx common.AndroidBaseContext) []string {
Colin Cross28d76592015-03-26 16:14:04 -0700751 if ctx.ContainsProperty("system_shared_libs") {
Colin Crossfa138792015-04-24 17:31:52 -0700752 return c.Properties.System_shared_libs
753 } else if ctx.Device() && c.Properties.Sdk_version == "" {
Colin Cross577f6e42015-03-27 18:23:34 -0700754 return []string{"libc", "libm"}
Colin Cross28d76592015-03-26 16:14:04 -0700755 } else {
Colin Cross577f6e42015-03-27 18:23:34 -0700756 return nil
Colin Cross3f40fa42015-01-30 17:27:36 -0800757 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800758}
759
Colin Crossfa138792015-04-24 17:31:52 -0700760func (c *CCLinked) stl(ctx common.AndroidBaseContext) string {
761 if c.Properties.Sdk_version != "" && ctx.Device() {
762 switch c.Properties.Stl {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700763 case "":
764 return "ndk_system"
765 case "c++_shared", "c++_static",
766 "stlport_shared", "stlport_static",
767 "gnustl_static":
Colin Crossfa138792015-04-24 17:31:52 -0700768 return "ndk_lib" + c.Properties.Stl
Colin Crossed4cf0b2015-03-26 14:43:45 -0700769 default:
Colin Crossfa138792015-04-24 17:31:52 -0700770 ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", c.Properties.Stl)
Colin Crossed4cf0b2015-03-26 14:43:45 -0700771 return ""
772 }
773 }
774
Colin Crossfa138792015-04-24 17:31:52 -0700775 switch c.Properties.Stl {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700776 case "libc++", "libc++_static",
777 "stlport", "stlport_static",
778 "libstdc++":
Colin Crossfa138792015-04-24 17:31:52 -0700779 return c.Properties.Stl
Colin Crossed4cf0b2015-03-26 14:43:45 -0700780 case "none":
781 return ""
782 case "":
Colin Cross18b6dc52015-04-28 13:20:37 -0700783 if c.static() {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700784 return "libc++_static"
Colin Cross18b6dc52015-04-28 13:20:37 -0700785 } else {
786 return "libc++" // TODO: mingw needs libstdc++
Colin Crossed4cf0b2015-03-26 14:43:45 -0700787 }
788 default:
Colin Crossfa138792015-04-24 17:31:52 -0700789 ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
Colin Crossed4cf0b2015-03-26 14:43:45 -0700790 return ""
791 }
792}
793
Colin Cross0af4b842015-04-30 16:36:18 -0700794var hostDynamicGccLibs, hostStaticGccLibs []string
795
796func init() {
797 if runtime.GOOS == "darwin" {
798 hostDynamicGccLibs = []string{"-lc", "-lSystem"}
799 hostStaticGccLibs = []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"}
800 } else {
801 hostDynamicGccLibs = []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"}
802 hostStaticGccLibs = []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"}
803 }
804}
Colin Cross712fc022015-04-27 11:13:34 -0700805
Colin Crosse11befc2015-04-27 17:49:17 -0700806func (c *CCLinked) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700807 stl := c.stl(ctx)
808 if ctx.Failed() {
809 return flags
810 }
811
812 switch stl {
813 case "libc++", "libc++_static":
814 flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
Colin Cross28344522015-04-22 13:07:53 -0700815 flags.CFlags = append(flags.CFlags, "-I${SrcDir}/external/libcxx/include")
Colin Crossed4cf0b2015-03-26 14:43:45 -0700816 if ctx.Host() {
817 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
818 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
Colin Cross712fc022015-04-27 11:13:34 -0700819 flags.LdFlags = append(flags.LdFlags, "-lm", "-lpthread")
Colin Cross18b6dc52015-04-28 13:20:37 -0700820 if c.staticBinary() {
Colin Cross712fc022015-04-27 11:13:34 -0700821 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
Colin Cross18b6dc52015-04-28 13:20:37 -0700822 } else {
823 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
Colin Cross712fc022015-04-27 11:13:34 -0700824 }
Colin Crossed4cf0b2015-03-26 14:43:45 -0700825 }
826 case "stlport", "stlport_static":
827 if ctx.Device() {
Colin Cross28344522015-04-22 13:07:53 -0700828 flags.CFlags = append(flags.CFlags,
829 "-I${SrcDir}/external/stlport/stlport",
830 "-I${SrcDir}/bionic/libstdc++/include",
831 "-I${SrcDir}/bionic")
Colin Crossed4cf0b2015-03-26 14:43:45 -0700832 }
833 case "libstdc++":
834 // Using bionic's basic libstdc++. Not actually an STL. Only around until the
835 // tree is in good enough shape to not need it.
836 // Host builds will use GNU libstdc++.
837 if ctx.Device() {
Colin Cross28344522015-04-22 13:07:53 -0700838 flags.CFlags = append(flags.CFlags, "-I${SrcDir}/bionic/libstdc++/include")
Colin Crossed4cf0b2015-03-26 14:43:45 -0700839 }
840 case "ndk_system":
Colin Cross1332b002015-04-07 17:11:30 -0700841 ndkSrcRoot := ctx.AConfig().SrcDir() + "/prebuilts/ndk/current/sources/"
Colin Cross28344522015-04-22 13:07:53 -0700842 flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot+"cxx-stl/system/include")
Colin Crossed4cf0b2015-03-26 14:43:45 -0700843 case "ndk_libc++_shared", "ndk_libc++_static":
844 // TODO(danalbert): This really shouldn't be here...
845 flags.CppFlags = append(flags.CppFlags, "-std=c++11")
846 case "ndk_libstlport_shared", "ndk_libstlport_static", "ndk_libgnustl_static":
847 // Nothing
848 case "":
849 // None or error.
850 if ctx.Host() {
851 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
852 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
Colin Cross18b6dc52015-04-28 13:20:37 -0700853 if c.staticBinary() {
Colin Cross712fc022015-04-27 11:13:34 -0700854 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
Colin Cross18b6dc52015-04-28 13:20:37 -0700855 } else {
856 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
Colin Cross712fc022015-04-27 11:13:34 -0700857 }
Colin Crossed4cf0b2015-03-26 14:43:45 -0700858 }
859 default:
Colin Crossfa138792015-04-24 17:31:52 -0700860 panic(fmt.Errorf("Unknown stl in CCLinked.Flags: %q", stl))
Colin Crossed4cf0b2015-03-26 14:43:45 -0700861 }
862
863 return flags
864}
865
Colin Crosse11befc2015-04-27 17:49:17 -0700866func (c *CCLinked) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
867 depNames = c.CCBase.depNames(ctx, depNames)
Colin Cross3f40fa42015-01-30 17:27:36 -0800868
Colin Crossed4cf0b2015-03-26 14:43:45 -0700869 stl := c.stl(ctx)
870 if ctx.Failed() {
871 return depNames
872 }
873
874 switch stl {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700875 case "libstdc++":
876 if ctx.Device() {
877 depNames.SharedLibs = append(depNames.SharedLibs, stl)
878 }
Colin Cross74d1ec02015-04-28 13:30:13 -0700879 case "libc++", "libc++_static":
880 if stl == "libc++" {
881 depNames.SharedLibs = append(depNames.SharedLibs, stl)
882 } else {
883 depNames.StaticLibs = append(depNames.StaticLibs, stl)
884 }
885 if ctx.Device() {
886 if ctx.Arch().ArchType == common.Arm {
887 depNames.StaticLibs = append(depNames.StaticLibs, "libunwind_llvm")
888 }
889 if c.staticBinary() {
890 depNames.StaticLibs = append(depNames.StaticLibs, "libdl")
891 } else {
892 depNames.SharedLibs = append(depNames.SharedLibs, "libdl")
893 }
894 }
Colin Crossed4cf0b2015-03-26 14:43:45 -0700895 case "stlport":
896 depNames.SharedLibs = append(depNames.SharedLibs, "libstdc++", "libstlport")
897 case "stlport_static":
898 depNames.StaticLibs = append(depNames.StaticLibs, "libstdc++", "libstlport_static")
899 case "":
900 // None or error.
901 case "ndk_system":
902 // TODO: Make a system STL prebuilt for the NDK.
903 // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
Colin Crossfa138792015-04-24 17:31:52 -0700904 // its own includes. The includes are handled in CCBase.Flags().
Colin Cross577f6e42015-03-27 18:23:34 -0700905 depNames.SharedLibs = append([]string{"libstdc++"}, depNames.SharedLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -0700906 case "ndk_libc++_shared", "ndk_libstlport_shared":
907 depNames.SharedLibs = append(depNames.SharedLibs, stl)
908 case "ndk_libc++_static", "ndk_libstlport_static", "ndk_libgnustl_static":
909 depNames.StaticLibs = append(depNames.StaticLibs, stl)
910 default:
Colin Crosse11befc2015-04-27 17:49:17 -0700911 panic(fmt.Errorf("Unknown stl in CCLinked.depNames: %q", stl))
Colin Crossed4cf0b2015-03-26 14:43:45 -0700912 }
913
Colin Cross74d1ec02015-04-28 13:30:13 -0700914 if ctx.ModuleName() != "libcompiler_rt-extras" {
915 depNames.StaticLibs = append(depNames.StaticLibs, "libcompiler_rt-extras")
916 }
917
Colin Crossf6566ed2015-03-24 11:13:38 -0700918 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -0700919 // libgcc and libatomic have to be last on the command line
Colin Cross21b9a242015-03-24 14:15:58 -0700920 depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic", "libgcc")
Colin Crossed4cf0b2015-03-26 14:43:45 -0700921
Colin Cross18b6dc52015-04-28 13:20:37 -0700922 if !c.static() {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700923 depNames.SharedLibs = append(depNames.SharedLibs, c.systemSharedLibs(ctx)...)
924 }
Colin Cross577f6e42015-03-27 18:23:34 -0700925
Colin Crossfa138792015-04-24 17:31:52 -0700926 if c.Properties.Sdk_version != "" {
927 version := c.Properties.Sdk_version
Colin Cross577f6e42015-03-27 18:23:34 -0700928 depNames.SharedLibs = append(depNames.SharedLibs,
929 "ndk_libc."+version,
930 "ndk_libm."+version,
931 )
932 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800933 }
934
Colin Cross21b9a242015-03-24 14:15:58 -0700935 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -0800936}
937
Colin Crossed4cf0b2015-03-26 14:43:45 -0700938// ccLinkedInterface interface is used on ccLinked to deal with static or shared variants
939type ccLinkedInterface interface {
940 // Returns true if the build options for the module have selected a static or shared build
941 buildStatic() bool
942 buildShared() bool
943
944 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -0700945 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -0700946
Colin Cross18b6dc52015-04-28 13:20:37 -0700947 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -0700948 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -0700949
950 // Returns whether a module is a static binary
951 staticBinary() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -0700952}
953
954var _ ccLinkedInterface = (*CCLibrary)(nil)
955var _ ccLinkedInterface = (*CCBinary)(nil)
956
Colin Crossfa138792015-04-24 17:31:52 -0700957func (c *CCLinked) static() bool {
Colin Crossed4cf0b2015-03-26 14:43:45 -0700958 return c.dynamicProperties.VariantIsStatic
959}
960
Colin Cross18b6dc52015-04-28 13:20:37 -0700961func (c *CCLinked) staticBinary() bool {
962 return c.dynamicProperties.VariantIsStaticBinary
Colin Crossed4cf0b2015-03-26 14:43:45 -0700963}
964
Colin Cross18b6dc52015-04-28 13:20:37 -0700965func (c *CCLinked) setStatic(static bool) {
966 c.dynamicProperties.VariantIsStatic = static
Colin Crossed4cf0b2015-03-26 14:43:45 -0700967}
968
Colin Cross28344522015-04-22 13:07:53 -0700969type ccExportedFlagsProducer interface {
970 exportedFlags() []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800971}
972
973//
974// Combined static+shared libraries
975//
976
Colin Cross7d5136f2015-05-11 13:39:40 -0700977type CCLibraryProperties struct {
978 BuildStatic bool `blueprint:"mutated"`
979 BuildShared bool `blueprint:"mutated"`
980 Static struct {
981 Srcs []string `android:"arch_variant"`
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700982 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700983 Cflags []string `android:"arch_variant"`
984 Whole_static_libs []string `android:"arch_variant"`
985 Static_libs []string `android:"arch_variant"`
986 Shared_libs []string `android:"arch_variant"`
987 } `android:"arch_variant"`
988 Shared struct {
989 Srcs []string `android:"arch_variant"`
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700990 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700991 Cflags []string `android:"arch_variant"`
992 Whole_static_libs []string `android:"arch_variant"`
993 Static_libs []string `android:"arch_variant"`
994 Shared_libs []string `android:"arch_variant"`
995 } `android:"arch_variant"`
Colin Crossaee540a2015-07-06 17:48:31 -0700996
997 // local file name to pass to the linker as --version_script
998 Version_script string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700999}
1000
Colin Cross97ba0732015-03-23 17:50:24 -07001001type CCLibrary struct {
Colin Crossfa138792015-04-24 17:31:52 -07001002 CCLinked
Colin Cross3f40fa42015-01-30 17:27:36 -08001003
Colin Cross28344522015-04-22 13:07:53 -07001004 reuseFrom ccLibraryInterface
1005 reuseObjFiles []string
1006 objFiles []string
1007 exportFlags []string
1008 out string
Colin Cross3f40fa42015-01-30 17:27:36 -08001009
Colin Cross7d5136f2015-05-11 13:39:40 -07001010 LibraryProperties CCLibraryProperties
Colin Cross3f40fa42015-01-30 17:27:36 -08001011}
1012
Colin Crossed4cf0b2015-03-26 14:43:45 -07001013func (c *CCLibrary) buildStatic() bool {
1014 return c.LibraryProperties.BuildStatic
1015}
1016
1017func (c *CCLibrary) buildShared() bool {
1018 return c.LibraryProperties.BuildShared
1019}
1020
Colin Cross97ba0732015-03-23 17:50:24 -07001021type ccLibraryInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001022 ccLinkedInterface
Colin Cross97ba0732015-03-23 17:50:24 -07001023 ccLibrary() *CCLibrary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001024 setReuseFrom(ccLibraryInterface)
1025 getReuseFrom() ccLibraryInterface
1026 getReuseObjFiles() []string
Colin Cross97ba0732015-03-23 17:50:24 -07001027 allObjFiles() []string
Colin Crossc472d572015-03-17 15:06:21 -07001028}
1029
Colin Crossed4cf0b2015-03-26 14:43:45 -07001030var _ ccLibraryInterface = (*CCLibrary)(nil)
1031
Colin Cross97ba0732015-03-23 17:50:24 -07001032func (c *CCLibrary) ccLibrary() *CCLibrary {
1033 return c
Colin Cross3f40fa42015-01-30 17:27:36 -08001034}
1035
Colin Cross97ba0732015-03-23 17:50:24 -07001036func NewCCLibrary(library *CCLibrary, module CCModuleType,
1037 hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
1038
Colin Crossfa138792015-04-24 17:31:52 -07001039 return newCCDynamic(&library.CCLinked, module, hod, common.MultilibBoth,
Colin Cross97ba0732015-03-23 17:50:24 -07001040 &library.LibraryProperties)
1041}
1042
1043func CCLibraryFactory() (blueprint.Module, []interface{}) {
1044 module := &CCLibrary{}
1045
1046 module.LibraryProperties.BuildShared = true
1047 module.LibraryProperties.BuildStatic = true
1048
1049 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
1050}
1051
Colin Cross0676e2d2015-04-24 17:39:18 -07001052func (c *CCLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Crosse11befc2015-04-27 17:49:17 -07001053 depNames = c.CCLinked.depNames(ctx, depNames)
Colin Cross2732e9a2015-04-28 13:23:52 -07001054 if c.static() {
1055 depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.LibraryProperties.Static.Whole_static_libs...)
1056 depNames.StaticLibs = append(depNames.StaticLibs, c.LibraryProperties.Static.Static_libs...)
1057 depNames.SharedLibs = append(depNames.SharedLibs, c.LibraryProperties.Static.Shared_libs...)
1058 } else {
Colin Crossf6566ed2015-03-24 11:13:38 -07001059 if ctx.Device() {
Dan Albertc3144b12015-04-28 18:17:56 -07001060 if c.Properties.Sdk_version == "" {
1061 depNames.CrtBegin = "crtbegin_so"
1062 depNames.CrtEnd = "crtend_so"
1063 } else {
1064 depNames.CrtBegin = "ndk_crtbegin_so." + c.Properties.Sdk_version
1065 depNames.CrtEnd = "ndk_crtend_so." + c.Properties.Sdk_version
1066 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001067 }
Colin Cross2732e9a2015-04-28 13:23:52 -07001068 depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.LibraryProperties.Shared.Whole_static_libs...)
1069 depNames.StaticLibs = append(depNames.StaticLibs, c.LibraryProperties.Shared.Static_libs...)
1070 depNames.SharedLibs = append(depNames.SharedLibs, c.LibraryProperties.Shared.Shared_libs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001071 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001072
Colin Cross21b9a242015-03-24 14:15:58 -07001073 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -08001074}
1075
Colin Cross97ba0732015-03-23 17:50:24 -07001076func (c *CCLibrary) outputFile() string {
Colin Cross3f40fa42015-01-30 17:27:36 -08001077 return c.out
1078}
1079
Colin Crossed4cf0b2015-03-26 14:43:45 -07001080func (c *CCLibrary) getReuseObjFiles() []string {
1081 return c.reuseObjFiles
1082}
1083
1084func (c *CCLibrary) setReuseFrom(reuseFrom ccLibraryInterface) {
1085 c.reuseFrom = reuseFrom
1086}
1087
1088func (c *CCLibrary) getReuseFrom() ccLibraryInterface {
1089 return c.reuseFrom
1090}
1091
Colin Cross97ba0732015-03-23 17:50:24 -07001092func (c *CCLibrary) allObjFiles() []string {
Colin Cross3f40fa42015-01-30 17:27:36 -08001093 return c.objFiles
1094}
1095
Colin Cross28344522015-04-22 13:07:53 -07001096func (c *CCLibrary) exportedFlags() []string {
1097 return c.exportFlags
Colin Cross3f40fa42015-01-30 17:27:36 -08001098}
1099
Colin Cross0676e2d2015-04-24 17:39:18 -07001100func (c *CCLibrary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Crosse11befc2015-04-27 17:49:17 -07001101 flags = c.CCLinked.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001102
Colin Cross97ba0732015-03-23 17:50:24 -07001103 flags.CFlags = append(flags.CFlags, "-fPIC")
Colin Cross3f40fa42015-01-30 17:27:36 -08001104
Colin Crossd8e780d2015-04-28 17:39:43 -07001105 if c.static() {
1106 flags.CFlags = append(flags.CFlags, c.LibraryProperties.Static.Cflags...)
1107 } else {
1108 flags.CFlags = append(flags.CFlags, c.LibraryProperties.Shared.Cflags...)
1109 }
1110
Colin Cross18b6dc52015-04-28 13:20:37 -07001111 if !c.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001112 libName := ctx.ModuleName()
1113 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1114 sharedFlag := "-Wl,-shared"
Colin Crossfa138792015-04-24 17:31:52 -07001115 if c.Properties.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001116 sharedFlag = "-shared"
1117 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001118 if ctx.Device() {
Colin Cross97ba0732015-03-23 17:50:24 -07001119 flags.LdFlags = append(flags.LdFlags, "-nostdlib")
Colin Cross3f40fa42015-01-30 17:27:36 -08001120 }
Colin Cross97ba0732015-03-23 17:50:24 -07001121
Colin Cross0af4b842015-04-30 16:36:18 -07001122 if ctx.Darwin() {
1123 flags.LdFlags = append(flags.LdFlags,
1124 "-dynamiclib",
1125 "-single_module",
1126 //"-read_only_relocs suppress",
1127 "-install_name @rpath/"+libName+sharedLibraryExtension,
1128 )
1129 } else {
1130 flags.LdFlags = append(flags.LdFlags,
1131 "-Wl,--gc-sections",
1132 sharedFlag,
1133 "-Wl,-soname,"+libName+sharedLibraryExtension,
1134 )
1135 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001136 }
Colin Cross97ba0732015-03-23 17:50:24 -07001137
1138 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001139}
1140
Colin Cross97ba0732015-03-23 17:50:24 -07001141func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
1142 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001143
1144 staticFlags := flags
Colin Cross581c1892015-04-07 16:50:10 -07001145 objFilesStatic := c.customCompileObjs(ctx, staticFlags, common.DeviceStaticLibrary,
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001146 c.LibraryProperties.Static.Srcs, c.LibraryProperties.Static.Exclude_srcs)
Colin Cross3f40fa42015-01-30 17:27:36 -08001147
1148 objFiles = append(objFiles, objFilesStatic...)
Colin Cross21b9a242015-03-24 14:15:58 -07001149 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001150
1151 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
1152
Colin Cross0af4b842015-04-30 16:36:18 -07001153 if ctx.Darwin() {
1154 TransformDarwinObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1155 } else {
1156 TransformObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1157 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001158
1159 c.objFiles = objFiles
1160 c.out = outputFile
Colin Crossf2298272015-05-12 11:36:53 -07001161
1162 common.CheckModuleSrcDirsExist(ctx, c.Properties.Export_include_dirs, "export_include_dirs")
Colin Crossfa138792015-04-24 17:31:52 -07001163 includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
Colin Cross28344522015-04-22 13:07:53 -07001164 c.exportFlags = []string{includeDirsToFlags(includeDirs)}
Colin Cross3f40fa42015-01-30 17:27:36 -08001165
1166 ctx.CheckbuildFile(outputFile)
1167}
1168
Colin Cross97ba0732015-03-23 17:50:24 -07001169func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
1170 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001171
1172 sharedFlags := flags
Colin Cross581c1892015-04-07 16:50:10 -07001173 objFilesShared := c.customCompileObjs(ctx, sharedFlags, common.DeviceSharedLibrary,
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001174 c.LibraryProperties.Shared.Srcs, c.LibraryProperties.Shared.Exclude_srcs)
Colin Cross3f40fa42015-01-30 17:27:36 -08001175
1176 objFiles = append(objFiles, objFilesShared...)
1177
1178 outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
1179
Colin Crossaee540a2015-07-06 17:48:31 -07001180 var linkerDeps []string
1181
1182 if c.LibraryProperties.Version_script != "" {
1183 versionScript := filepath.Join(common.ModuleSrcDir(ctx), c.LibraryProperties.Version_script)
1184 sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,--version-script,"+versionScript)
1185 linkerDeps = append(linkerDeps, versionScript)
1186 }
1187
Colin Cross97ba0732015-03-23 17:50:24 -07001188 TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001189 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, false,
Colin Cross77b00fa2015-03-16 16:15:49 -07001190 ccFlagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001191
1192 c.out = outputFile
Colin Crossfa138792015-04-24 17:31:52 -07001193 includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
Colin Cross28344522015-04-22 13:07:53 -07001194 c.exportFlags = []string{includeDirsToFlags(includeDirs)}
Colin Cross3f40fa42015-01-30 17:27:36 -08001195}
1196
Colin Cross97ba0732015-03-23 17:50:24 -07001197func (c *CCLibrary) compileModule(ctx common.AndroidModuleContext,
1198 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001199
1200 // Reuse the object files from the matching static library if it exists
Colin Crossed4cf0b2015-03-26 14:43:45 -07001201 if c.getReuseFrom().ccLibrary() == c {
1202 c.reuseObjFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001203 } else {
Colin Cross2732e9a2015-04-28 13:23:52 -07001204 if c.getReuseFrom().ccLibrary().LibraryProperties.Static.Cflags == nil &&
1205 c.LibraryProperties.Shared.Cflags == nil {
1206 objFiles = append([]string(nil), c.getReuseFrom().getReuseObjFiles()...)
1207 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001208 }
1209
Colin Crossed4cf0b2015-03-26 14:43:45 -07001210 if c.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001211 c.compileStaticLibrary(ctx, flags, deps, objFiles)
1212 } else {
1213 c.compileSharedLibrary(ctx, flags, deps, objFiles)
1214 }
1215}
1216
Colin Cross97ba0732015-03-23 17:50:24 -07001217func (c *CCLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001218 // Static libraries do not get installed.
1219}
1220
Colin Cross97ba0732015-03-23 17:50:24 -07001221func (c *CCLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001222 installDir := "lib"
Colin Cross97ba0732015-03-23 17:50:24 -07001223 if flags.Toolchain.Is64Bit() {
Dan Albertc403f7c2015-03-18 14:01:18 -07001224 installDir = "lib64"
1225 }
1226
Colin Crossfa138792015-04-24 17:31:52 -07001227 ctx.InstallFile(filepath.Join(installDir, c.Properties.Relative_install_path), c.out)
Dan Albertc403f7c2015-03-18 14:01:18 -07001228}
1229
Colin Cross97ba0732015-03-23 17:50:24 -07001230func (c *CCLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001231 if c.static() {
Dan Albertc403f7c2015-03-18 14:01:18 -07001232 c.installStaticLibrary(ctx, flags)
1233 } else {
1234 c.installSharedLibrary(ctx, flags)
1235 }
1236}
1237
Colin Cross3f40fa42015-01-30 17:27:36 -08001238//
1239// Objects (for crt*.o)
1240//
1241
Dan Albertc3144b12015-04-28 18:17:56 -07001242type ccObjectProvider interface {
1243 object() *ccObject
1244}
1245
Colin Cross3f40fa42015-01-30 17:27:36 -08001246type ccObject struct {
Colin Crossfa138792015-04-24 17:31:52 -07001247 CCBase
Colin Cross3f40fa42015-01-30 17:27:36 -08001248 out string
1249}
1250
Dan Albertc3144b12015-04-28 18:17:56 -07001251func (c *ccObject) object() *ccObject {
1252 return c
1253}
1254
Colin Cross97ba0732015-03-23 17:50:24 -07001255func CCObjectFactory() (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001256 module := &ccObject{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001257
Colin Crossfa138792015-04-24 17:31:52 -07001258 return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth)
Colin Cross3f40fa42015-01-30 17:27:36 -08001259}
1260
1261func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1262 // object files can't have any dynamic dependencies
1263 return nil
1264}
1265
Colin Cross0676e2d2015-04-24 17:39:18 -07001266func (*ccObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Cross21b9a242015-03-24 14:15:58 -07001267 // object files can't have any dynamic dependencies
1268 return CCDeps{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001269}
1270
1271func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
Colin Cross97ba0732015-03-23 17:50:24 -07001272 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001273
Colin Cross97ba0732015-03-23 17:50:24 -07001274 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001275
1276 var outputFile string
1277 if len(objFiles) == 1 {
1278 outputFile = objFiles[0]
1279 } else {
Dan Albertc3144b12015-04-28 18:17:56 -07001280 outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+objectExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001281 TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
1282 }
1283
1284 c.out = outputFile
1285
1286 ctx.CheckbuildFile(outputFile)
1287}
1288
Colin Cross97ba0732015-03-23 17:50:24 -07001289func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001290 // Object files do not get installed.
1291}
1292
Colin Cross3f40fa42015-01-30 17:27:36 -08001293func (c *ccObject) outputFile() string {
1294 return c.out
1295}
1296
Dan Albertc3144b12015-04-28 18:17:56 -07001297var _ ccObjectProvider = (*ccObject)(nil)
1298
Colin Cross3f40fa42015-01-30 17:27:36 -08001299//
1300// Executables
1301//
1302
Colin Cross7d5136f2015-05-11 13:39:40 -07001303type CCBinaryProperties struct {
1304 // compile executable with -static
1305 Static_executable bool
1306
1307 // set the name of the output
1308 Stem string `android:"arch_variant"`
1309
1310 // append to the name of the output
1311 Suffix string `android:"arch_variant"`
1312
1313 // if set, add an extra objcopy --prefix-symbols= step
1314 Prefix_symbols string
1315}
1316
Colin Cross97ba0732015-03-23 17:50:24 -07001317type CCBinary struct {
Colin Crossfa138792015-04-24 17:31:52 -07001318 CCLinked
Dan Albertc403f7c2015-03-18 14:01:18 -07001319 out string
Colin Crossd350ecd2015-04-28 13:25:36 -07001320 installFile string
Colin Cross7d5136f2015-05-11 13:39:40 -07001321 BinaryProperties CCBinaryProperties
Colin Cross3f40fa42015-01-30 17:27:36 -08001322}
1323
Colin Crossed4cf0b2015-03-26 14:43:45 -07001324func (c *CCBinary) buildStatic() bool {
1325 return c.BinaryProperties.Static_executable
1326}
1327
1328func (c *CCBinary) buildShared() bool {
1329 return !c.BinaryProperties.Static_executable
1330}
1331
Colin Cross97ba0732015-03-23 17:50:24 -07001332func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001333 stem := ctx.ModuleName()
Colin Cross97ba0732015-03-23 17:50:24 -07001334 if c.BinaryProperties.Stem != "" {
Colin Cross4ae185c2015-03-26 15:12:10 -07001335 stem = c.BinaryProperties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001336 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001337
1338 return stem + c.BinaryProperties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001339}
1340
Colin Cross0676e2d2015-04-24 17:39:18 -07001341func (c *CCBinary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Crosse11befc2015-04-27 17:49:17 -07001342 depNames = c.CCLinked.depNames(ctx, depNames)
Colin Crossf6566ed2015-03-24 11:13:38 -07001343 if ctx.Device() {
Dan Albertc3144b12015-04-28 18:17:56 -07001344 if c.Properties.Sdk_version == "" {
1345 if c.BinaryProperties.Static_executable {
1346 depNames.CrtBegin = "crtbegin_static"
1347 } else {
1348 depNames.CrtBegin = "crtbegin_dynamic"
1349 }
1350 depNames.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001351 } else {
Dan Albertc3144b12015-04-28 18:17:56 -07001352 if c.BinaryProperties.Static_executable {
1353 depNames.CrtBegin = "ndk_crtbegin_static." + c.Properties.Sdk_version
1354 } else {
1355 depNames.CrtBegin = "ndk_crtbegin_dynamic." + c.Properties.Sdk_version
1356 }
1357 depNames.CrtEnd = "ndk_crtend_android." + c.Properties.Sdk_version
Colin Cross3f40fa42015-01-30 17:27:36 -08001358 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001359
1360 if c.BinaryProperties.Static_executable {
Colin Cross74d1ec02015-04-28 13:30:13 -07001361 if c.stl(ctx) == "libc++_static" {
1362 depNames.StaticLibs = append(depNames.StaticLibs, "libm", "libc", "libdl")
1363 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001364 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1365 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1366 // move them to the beginning of deps.LateStaticLibs
1367 var groupLibs []string
1368 depNames.StaticLibs, groupLibs = filterList(depNames.StaticLibs,
1369 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
1370 depNames.LateStaticLibs = append(groupLibs, depNames.LateStaticLibs...)
1371 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001372 }
Colin Cross21b9a242015-03-24 14:15:58 -07001373 return depNames
Colin Cross3f40fa42015-01-30 17:27:36 -08001374}
1375
Colin Cross97ba0732015-03-23 17:50:24 -07001376func NewCCBinary(binary *CCBinary, module CCModuleType,
Colin Cross1f8f2342015-03-26 16:09:47 -07001377 hod common.HostOrDeviceSupported, props ...interface{}) (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001378
Colin Cross1f8f2342015-03-26 16:09:47 -07001379 props = append(props, &binary.BinaryProperties)
1380
Colin Crossfa138792015-04-24 17:31:52 -07001381 return newCCDynamic(&binary.CCLinked, module, hod, common.MultilibFirst, props...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001382}
1383
Colin Cross97ba0732015-03-23 17:50:24 -07001384func CCBinaryFactory() (blueprint.Module, []interface{}) {
1385 module := &CCBinary{}
1386
1387 return NewCCBinary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001388}
1389
Colin Cross18b6dc52015-04-28 13:20:37 -07001390func (c *CCBinary) ModifyProperties(ctx common.AndroidBaseContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001391 if ctx.Darwin() {
1392 c.BinaryProperties.Static_executable = false
1393 }
Colin Cross18b6dc52015-04-28 13:20:37 -07001394 if c.BinaryProperties.Static_executable {
1395 c.dynamicProperties.VariantIsStaticBinary = true
1396 }
1397}
1398
Colin Cross0676e2d2015-04-24 17:39:18 -07001399func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Crosse11befc2015-04-27 17:49:17 -07001400 flags = c.CCLinked.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001401
Colin Cross97ba0732015-03-23 17:50:24 -07001402 flags.CFlags = append(flags.CFlags, "-fpie")
1403
Colin Crossf6566ed2015-03-24 11:13:38 -07001404 if ctx.Device() {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001405 if c.BinaryProperties.Static_executable {
1406 // Clang driver needs -static to create static executable.
1407 // However, bionic/linker uses -shared to overwrite.
1408 // Linker for x86 targets does not allow coexistance of -static and -shared,
1409 // so we add -static only if -shared is not used.
1410 if !inList("-shared", flags.LdFlags) {
1411 flags.LdFlags = append(flags.LdFlags, "-static")
1412 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001413
Colin Crossed4cf0b2015-03-26 14:43:45 -07001414 flags.LdFlags = append(flags.LdFlags,
1415 "-nostdlib",
1416 "-Bstatic",
1417 "-Wl,--gc-sections",
1418 )
1419
1420 } else {
1421 linker := "/system/bin/linker"
1422 if flags.Toolchain.Is64Bit() {
1423 linker = "/system/bin/linker64"
1424 }
1425
1426 flags.LdFlags = append(flags.LdFlags,
1427 "-nostdlib",
1428 "-Bdynamic",
1429 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1430 "-Wl,--gc-sections",
1431 "-Wl,-z,nocopyreloc",
1432 )
1433 }
Colin Cross0af4b842015-04-30 16:36:18 -07001434 } else if ctx.Darwin() {
1435 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001436 }
1437
Colin Cross97ba0732015-03-23 17:50:24 -07001438 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001439}
1440
Colin Cross97ba0732015-03-23 17:50:24 -07001441func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
1442 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001443
Colin Crossfa138792015-04-24 17:31:52 -07001444 if !c.BinaryProperties.Static_executable && inList("libc", c.Properties.Static_libs) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001445 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1446 "from static libs or set static_executable: true")
1447 }
1448
1449 outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
Dan Albertc403f7c2015-03-18 14:01:18 -07001450 c.out = outputFile
Colin Crossbfae8852015-03-26 14:44:11 -07001451 if c.BinaryProperties.Prefix_symbols != "" {
1452 afterPrefixSymbols := outputFile
1453 outputFile = outputFile + ".intermediate"
1454 TransformBinaryPrefixSymbols(ctx, c.BinaryProperties.Prefix_symbols, outputFile,
1455 ccFlagsToBuilderFlags(flags), afterPrefixSymbols)
1456 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001457
Colin Crossaee540a2015-07-06 17:48:31 -07001458 var linkerDeps []string
1459
Colin Cross97ba0732015-03-23 17:50:24 -07001460 TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001461 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Cross77b00fa2015-03-16 16:15:49 -07001462 ccFlagsToBuilderFlags(flags), outputFile)
Dan Albertc403f7c2015-03-18 14:01:18 -07001463}
Colin Cross3f40fa42015-01-30 17:27:36 -08001464
Colin Cross97ba0732015-03-23 17:50:24 -07001465func (c *CCBinary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Colin Crossd350ecd2015-04-28 13:25:36 -07001466 c.installFile = ctx.InstallFile(filepath.Join("bin", c.Properties.Relative_install_path), c.out)
1467}
1468
1469func (c *CCBinary) HostToolPath() string {
1470 if c.HostOrDevice().Host() {
1471 return c.installFile
1472 }
1473 return ""
Dan Albertc403f7c2015-03-18 14:01:18 -07001474}
1475
Colin Cross7d5136f2015-05-11 13:39:40 -07001476type CCTestProperties struct {
1477 // Create a separate test for each source file. Useful when there is
1478 // global state that can not be torn down and reset between each test suite.
1479 Test_per_src bool
1480}
1481
Colin Cross9ffb4f52015-04-24 17:48:09 -07001482type CCTest struct {
Colin Cross97ba0732015-03-23 17:50:24 -07001483 CCBinary
Colin Cross6b290692015-03-19 14:05:33 -07001484
Colin Cross7d5136f2015-05-11 13:39:40 -07001485 TestProperties CCTestProperties
Dan Albertc403f7c2015-03-18 14:01:18 -07001486}
1487
Colin Cross9ffb4f52015-04-24 17:48:09 -07001488func (c *CCTest) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
Colin Cross0676e2d2015-04-24 17:39:18 -07001489 flags = c.CCBinary.flags(ctx, flags)
Dan Albertc403f7c2015-03-18 14:01:18 -07001490
Colin Cross97ba0732015-03-23 17:50:24 -07001491 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001492 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001493 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Colin Cross28344522015-04-22 13:07:53 -07001494 flags.LdFlags = append(flags.LdFlags, "-lpthread")
Dan Albertc403f7c2015-03-18 14:01:18 -07001495 }
1496
1497 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross28344522015-04-22 13:07:53 -07001498 flags.CFlags = append(flags.CFlags,
1499 "-I"+filepath.Join(ctx.AConfig().SrcDir(), "external/gtest/include"))
Dan Albertc403f7c2015-03-18 14:01:18 -07001500
Colin Cross21b9a242015-03-24 14:15:58 -07001501 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07001502}
1503
Colin Cross9ffb4f52015-04-24 17:48:09 -07001504func (c *CCTest) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Cross21b9a242015-03-24 14:15:58 -07001505 depNames.StaticLibs = append(depNames.StaticLibs, "libgtest", "libgtest_main")
Colin Crossa8a93d32015-04-28 13:26:49 -07001506 depNames = c.CCBinary.depNames(ctx, depNames)
Colin Cross21b9a242015-03-24 14:15:58 -07001507 return depNames
Dan Albertc403f7c2015-03-18 14:01:18 -07001508}
1509
Colin Cross9ffb4f52015-04-24 17:48:09 -07001510func (c *CCTest) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Colin Crossf6566ed2015-03-24 11:13:38 -07001511 if ctx.Device() {
Colin Crossa8a93d32015-04-28 13:26:49 -07001512 ctx.InstallFile("../data/nativetest"+ctx.Arch().ArchType.Multilib[3:]+"/"+ctx.ModuleName(), c.out)
Dan Albertc403f7c2015-03-18 14:01:18 -07001513 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001514 c.CCBinary.installModule(ctx, flags)
Dan Albertc403f7c2015-03-18 14:01:18 -07001515 }
1516}
1517
Colin Cross9ffb4f52015-04-24 17:48:09 -07001518func (c *CCTest) testPerSrc() bool {
1519 return c.TestProperties.Test_per_src
Colin Cross6b290692015-03-19 14:05:33 -07001520}
1521
Colin Cross9ffb4f52015-04-24 17:48:09 -07001522func (c *CCTest) test() *CCTest {
1523 return c
1524}
1525
1526func NewCCTest(test *CCTest, module CCModuleType,
1527 hod common.HostOrDeviceSupported, props ...interface{}) (blueprint.Module, []interface{}) {
1528
1529 props = append(props, &test.TestProperties)
1530
1531 return NewCCBinary(&test.CCBinary, module, hod, props...)
1532}
1533
1534func CCTestFactory() (blueprint.Module, []interface{}) {
1535 module := &CCTest{}
1536
1537 return NewCCTest(module, module, common.HostAndDeviceSupported)
1538}
1539
1540type testPerSrc interface {
1541 test() *CCTest
1542 testPerSrc() bool
1543}
1544
1545var _ testPerSrc = (*CCTest)(nil)
1546
Colin Cross6b290692015-03-19 14:05:33 -07001547func TestPerSrcMutator(mctx blueprint.EarlyMutatorContext) {
Colin Cross9ffb4f52015-04-24 17:48:09 -07001548 if test, ok := mctx.Module().(testPerSrc); ok {
1549 if test.testPerSrc() {
1550 testNames := make([]string, len(test.test().Properties.Srcs))
1551 for i, src := range test.test().Properties.Srcs {
Colin Cross6b290692015-03-19 14:05:33 -07001552 testNames[i] = strings.TrimSuffix(src, filepath.Ext(src))
1553 }
1554 tests := mctx.CreateLocalVariations(testNames...)
Colin Cross9ffb4f52015-04-24 17:48:09 -07001555 for i, src := range test.test().Properties.Srcs {
1556 tests[i].(testPerSrc).test().Properties.Srcs = []string{src}
1557 tests[i].(testPerSrc).test().BinaryProperties.Stem = testNames[i]
Colin Cross6b290692015-03-19 14:05:33 -07001558 }
1559 }
1560 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001561}
1562
Colin Cross2ba19d92015-05-07 15:44:20 -07001563type CCBenchmark struct {
1564 CCBinary
1565}
1566
1567func (c *CCBenchmark) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
1568 depNames = c.CCBinary.depNames(ctx, depNames)
1569 depNames.StaticLibs = append(depNames.StaticLibs, "libbenchmark")
1570 return depNames
1571}
1572
1573func (c *CCBenchmark) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
1574 if ctx.Device() {
1575 ctx.InstallFile("../data/nativetest"+ctx.Arch().ArchType.Multilib[3:]+"/"+ctx.ModuleName(), c.out)
1576 } else {
1577 c.CCBinary.installModule(ctx, flags)
1578 }
1579}
1580
1581func NewCCBenchmark(test *CCBenchmark, module CCModuleType,
1582 hod common.HostOrDeviceSupported, props ...interface{}) (blueprint.Module, []interface{}) {
1583
1584 return NewCCBinary(&test.CCBinary, module, hod, props...)
1585}
1586
1587func CCBenchmarkFactory() (blueprint.Module, []interface{}) {
1588 module := &CCBenchmark{}
1589
1590 return NewCCBenchmark(module, module, common.HostAndDeviceSupported)
1591}
1592
Colin Cross3f40fa42015-01-30 17:27:36 -08001593//
1594// Static library
1595//
1596
Colin Cross97ba0732015-03-23 17:50:24 -07001597func CCLibraryStaticFactory() (blueprint.Module, []interface{}) {
1598 module := &CCLibrary{}
1599 module.LibraryProperties.BuildStatic = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001600
Colin Cross97ba0732015-03-23 17:50:24 -07001601 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001602}
1603
1604//
1605// Shared libraries
1606//
1607
Colin Cross97ba0732015-03-23 17:50:24 -07001608func CCLibrarySharedFactory() (blueprint.Module, []interface{}) {
1609 module := &CCLibrary{}
1610 module.LibraryProperties.BuildShared = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001611
Colin Cross97ba0732015-03-23 17:50:24 -07001612 return NewCCLibrary(module, module, common.HostAndDeviceSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001613}
1614
1615//
1616// Host static library
1617//
1618
Colin Cross97ba0732015-03-23 17:50:24 -07001619func CCLibraryHostStaticFactory() (blueprint.Module, []interface{}) {
1620 module := &CCLibrary{}
1621 module.LibraryProperties.BuildStatic = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001622
Colin Cross97ba0732015-03-23 17:50:24 -07001623 return NewCCLibrary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001624}
1625
1626//
1627// Host Shared libraries
1628//
1629
Colin Cross97ba0732015-03-23 17:50:24 -07001630func CCLibraryHostSharedFactory() (blueprint.Module, []interface{}) {
1631 module := &CCLibrary{}
1632 module.LibraryProperties.BuildShared = true
Colin Cross3f40fa42015-01-30 17:27:36 -08001633
Colin Cross97ba0732015-03-23 17:50:24 -07001634 return NewCCLibrary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001635}
1636
1637//
1638// Host Binaries
1639//
1640
Colin Cross97ba0732015-03-23 17:50:24 -07001641func CCBinaryHostFactory() (blueprint.Module, []interface{}) {
1642 module := &CCBinary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001643
Colin Cross97ba0732015-03-23 17:50:24 -07001644 return NewCCBinary(module, module, common.HostSupported)
Colin Cross3f40fa42015-01-30 17:27:36 -08001645}
1646
1647//
Colin Cross1f8f2342015-03-26 16:09:47 -07001648// Host Tests
1649//
1650
1651func CCTestHostFactory() (blueprint.Module, []interface{}) {
Colin Cross9ffb4f52015-04-24 17:48:09 -07001652 module := &CCTest{}
Colin Cross1f8f2342015-03-26 16:09:47 -07001653 return NewCCBinary(&module.CCBinary, module, common.HostSupported,
Colin Cross9ffb4f52015-04-24 17:48:09 -07001654 &module.TestProperties)
Colin Cross1f8f2342015-03-26 16:09:47 -07001655}
1656
1657//
Colin Cross2ba19d92015-05-07 15:44:20 -07001658// Host Benchmarks
1659//
1660
1661func CCBenchmarkHostFactory() (blueprint.Module, []interface{}) {
1662 module := &CCBenchmark{}
1663 return NewCCBinary(&module.CCBinary, module, common.HostSupported)
1664}
1665
1666//
Colin Cross3f40fa42015-01-30 17:27:36 -08001667// Device libraries shipped with gcc
1668//
1669
1670type toolchainLibrary struct {
Colin Cross97ba0732015-03-23 17:50:24 -07001671 CCLibrary
Colin Cross3f40fa42015-01-30 17:27:36 -08001672}
1673
1674func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
1675 // toolchain libraries can't have any dependencies
1676 return nil
1677}
1678
Colin Cross0676e2d2015-04-24 17:39:18 -07001679func (*toolchainLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Colin Cross3f40fa42015-01-30 17:27:36 -08001680 // toolchain libraries can't have any dependencies
Colin Cross21b9a242015-03-24 14:15:58 -07001681 return CCDeps{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001682}
1683
Colin Cross97ba0732015-03-23 17:50:24 -07001684func ToolchainLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001685 module := &toolchainLibrary{}
Colin Cross3f40fa42015-01-30 17:27:36 -08001686
Colin Cross97ba0732015-03-23 17:50:24 -07001687 module.LibraryProperties.BuildStatic = true
1688
Colin Crossfa138792015-04-24 17:31:52 -07001689 return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth,
Colin Cross21b9a242015-03-24 14:15:58 -07001690 &module.LibraryProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001691}
1692
1693func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
Colin Cross97ba0732015-03-23 17:50:24 -07001694 flags CCFlags, deps CCDeps, objFiles []string) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001695
1696 libName := ctx.ModuleName() + staticLibraryExtension
1697 outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
1698
1699 CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
1700
1701 c.out = outputFile
1702
1703 ctx.CheckbuildFile(outputFile)
1704}
1705
Colin Cross97ba0732015-03-23 17:50:24 -07001706func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc403f7c2015-03-18 14:01:18 -07001707 // Toolchain libraries do not get installed.
1708}
1709
Dan Albertbe961682015-03-18 23:38:50 -07001710// NDK prebuilt libraries.
1711//
1712// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
1713// either (with the exception of the shared STLs, which are installed to the app's directory rather
1714// than to the system image).
1715
1716func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) string {
1717 return fmt.Sprintf("%s/prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
Colin Cross1332b002015-04-07 17:11:30 -07001718 ctx.AConfig().SrcDir(), version, toolchain.Name())
Dan Albertbe961682015-03-18 23:38:50 -07001719}
1720
Dan Albertc3144b12015-04-28 18:17:56 -07001721func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
1722 ext string, version string) string {
1723
1724 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
1725 // We want to translate to just NAME.EXT
1726 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
1727 dir := getNdkLibDir(ctx, toolchain, version)
1728 return filepath.Join(dir, name+ext)
1729}
1730
1731type ndkPrebuiltObject struct {
1732 ccObject
1733}
1734
1735func (*ndkPrebuiltObject) AndroidDynamicDependencies(
1736 ctx common.AndroidDynamicDependerModuleContext) []string {
1737
1738 // NDK objects can't have any dependencies
1739 return nil
1740}
1741
1742func (*ndkPrebuiltObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
1743 // NDK objects can't have any dependencies
1744 return CCDeps{}
1745}
1746
1747func NdkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
1748 module := &ndkPrebuiltObject{}
1749 return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth)
1750}
1751
1752func (c *ndkPrebuiltObject) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
1753 deps CCDeps, objFiles []string) {
1754 // A null build step, but it sets up the output path.
1755 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
1756 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
1757 }
1758
1759 c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, c.Properties.Sdk_version)
1760}
1761
1762func (c *ndkPrebuiltObject) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
1763 // Objects do not get installed.
1764}
1765
1766var _ ccObjectProvider = (*ndkPrebuiltObject)(nil)
1767
Dan Albertbe961682015-03-18 23:38:50 -07001768type ndkPrebuiltLibrary struct {
1769 CCLibrary
1770}
1771
1772func (*ndkPrebuiltLibrary) AndroidDynamicDependencies(
1773 ctx common.AndroidDynamicDependerModuleContext) []string {
1774
1775 // NDK libraries can't have any dependencies
1776 return nil
1777}
1778
Colin Cross0676e2d2015-04-24 17:39:18 -07001779func (*ndkPrebuiltLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
Dan Albertbe961682015-03-18 23:38:50 -07001780 // NDK libraries can't have any dependencies
1781 return CCDeps{}
1782}
1783
1784func NdkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
1785 module := &ndkPrebuiltLibrary{}
1786 module.LibraryProperties.BuildShared = true
1787 return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
1788}
1789
1790func (c *ndkPrebuiltLibrary) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
1791 deps CCDeps, objFiles []string) {
1792 // A null build step, but it sets up the output path.
1793 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
1794 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
1795 }
1796
Colin Crossfa138792015-04-24 17:31:52 -07001797 includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
Colin Cross28344522015-04-22 13:07:53 -07001798 c.exportFlags = []string{common.JoinWithPrefix(includeDirs, "-isystem ")}
Dan Albertbe961682015-03-18 23:38:50 -07001799
Dan Albertc3144b12015-04-28 18:17:56 -07001800 c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, sharedLibraryExtension,
1801 c.Properties.Sdk_version)
Dan Albertbe961682015-03-18 23:38:50 -07001802}
1803
1804func (c *ndkPrebuiltLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
Dan Albertc3144b12015-04-28 18:17:56 -07001805 // NDK prebuilt libraries do not get installed.
Dan Albertbe961682015-03-18 23:38:50 -07001806}
1807
1808// The NDK STLs are slightly different from the prebuilt system libraries:
1809// * Are not specific to each platform version.
1810// * The libraries are not in a predictable location for each STL.
1811
1812type ndkPrebuiltStl struct {
1813 ndkPrebuiltLibrary
1814}
1815
1816type ndkPrebuiltStaticStl struct {
1817 ndkPrebuiltStl
1818}
1819
1820type ndkPrebuiltSharedStl struct {
1821 ndkPrebuiltStl
1822}
1823
1824func NdkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
1825 module := &ndkPrebuiltSharedStl{}
1826 module.LibraryProperties.BuildShared = true
1827 return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
1828}
1829
1830func NdkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
1831 module := &ndkPrebuiltStaticStl{}
1832 module.LibraryProperties.BuildStatic = true
1833 return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
1834}
1835
1836func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) string {
1837 gccVersion := toolchain.GccVersion()
1838 var libDir string
1839 switch stl {
1840 case "libstlport":
1841 libDir = "cxx-stl/stlport/libs"
1842 case "libc++":
1843 libDir = "cxx-stl/llvm-libc++/libs"
1844 case "libgnustl":
1845 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
1846 }
1847
1848 if libDir != "" {
Colin Cross1332b002015-04-07 17:11:30 -07001849 ndkSrcRoot := ctx.AConfig().SrcDir() + "/prebuilts/ndk/current/sources"
Dan Albertbe961682015-03-18 23:38:50 -07001850 return fmt.Sprintf("%s/%s/%s", ndkSrcRoot, libDir, ctx.Arch().Abi)
1851 }
1852
1853 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
1854 return ""
1855}
1856
1857func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
1858 deps CCDeps, objFiles []string) {
1859 // A null build step, but it sets up the output path.
1860 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
1861 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
1862 }
1863
Colin Crossfa138792015-04-24 17:31:52 -07001864 includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
Colin Cross28344522015-04-22 13:07:53 -07001865 c.exportFlags = []string{includeDirsToFlags(includeDirs)}
Dan Albertbe961682015-03-18 23:38:50 -07001866
1867 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
1868 libExt := sharedLibraryExtension
1869 if c.LibraryProperties.BuildStatic {
1870 libExt = staticLibraryExtension
1871 }
1872
1873 stlName := strings.TrimSuffix(libName, "_shared")
1874 stlName = strings.TrimSuffix(stlName, "_static")
1875 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
1876 c.out = libDir + "/" + libName + libExt
1877}
1878
Colin Cross3f40fa42015-01-30 17:27:36 -08001879func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001880 if c, ok := mctx.Module().(ccLinkedInterface); ok {
Colin Cross3f40fa42015-01-30 17:27:36 -08001881 var modules []blueprint.Module
Colin Crossed4cf0b2015-03-26 14:43:45 -07001882 if c.buildStatic() && c.buildShared() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001883 modules = mctx.CreateLocalVariations("static", "shared")
Colin Cross18b6dc52015-04-28 13:20:37 -07001884 modules[0].(ccLinkedInterface).setStatic(true)
1885 modules[1].(ccLinkedInterface).setStatic(false)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001886 } else if c.buildStatic() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001887 modules = mctx.CreateLocalVariations("static")
Colin Cross18b6dc52015-04-28 13:20:37 -07001888 modules[0].(ccLinkedInterface).setStatic(true)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001889 } else if c.buildShared() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001890 modules = mctx.CreateLocalVariations("shared")
Colin Cross18b6dc52015-04-28 13:20:37 -07001891 modules[0].(ccLinkedInterface).setStatic(false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001892 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001893 panic(fmt.Errorf("ccLibrary %q not static or shared", mctx.ModuleName()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001894 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001895
1896 if _, ok := c.(ccLibraryInterface); ok {
1897 reuseFrom := modules[0].(ccLibraryInterface)
1898 for _, m := range modules {
1899 m.(ccLibraryInterface).setReuseFrom(reuseFrom)
Colin Cross3f40fa42015-01-30 17:27:36 -08001900 }
1901 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001902 }
1903}
Colin Cross74d1ec02015-04-28 13:30:13 -07001904
1905// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
1906// modifies the slice contents in place, and returns a subslice of the original slice
1907func lastUniqueElements(list []string) []string {
1908 totalSkip := 0
1909 for i := len(list) - 1; i >= totalSkip; i-- {
1910 skip := 0
1911 for j := i - 1; j >= totalSkip; j-- {
1912 if list[i] == list[j] {
1913 skip++
1914 } else {
1915 list[j+skip] = list[j]
1916 }
1917 }
1918 totalSkip += skip
1919 }
1920 return list[totalSkip:]
1921}