blob: 8910ce748507e2d964da8f1f6d2ba3dfa19908e6 [file] [log] [blame]
Colin Cross5049f022015-03-18 13:28:46 -07001// Copyright 2015 Google Inc. All rights reserved.
Colin Cross3f40fa42015-01-30 17:27:36 -08002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17// This file contains the module types for compiling C/C++ for Android, and converts the properties
18// into the flags and filenames necessary to pass to the compiler. The final creation of the rules
19// is handled in builder.go
20
21import (
Colin Cross3f40fa42015-01-30 17:27:36 -080022 "fmt"
23 "path/filepath"
24 "strings"
25
Colin Cross97ba0732015-03-23 17:50:24 -070026 "github.com/google/blueprint"
Colin Cross06a931b2015-10-28 17:23:31 -070027 "github.com/google/blueprint/proptools"
Colin Cross97ba0732015-03-23 17:50:24 -070028
Colin Cross463a90e2015-06-17 14:20:06 -070029 "android/soong"
Colin Cross3f40fa42015-01-30 17:27:36 -080030 "android/soong/common"
Colin Cross5049f022015-03-18 13:28:46 -070031 "android/soong/genrule"
Colin Cross3f40fa42015-01-30 17:27:36 -080032)
33
Colin Cross463a90e2015-06-17 14:20:06 -070034func init() {
Colin Crossca860ac2016-01-04 14:34:37 -080035 soong.RegisterModuleType("cc_library_static", libraryStaticFactory)
36 soong.RegisterModuleType("cc_library_shared", librarySharedFactory)
37 soong.RegisterModuleType("cc_library", libraryFactory)
38 soong.RegisterModuleType("cc_object", objectFactory)
39 soong.RegisterModuleType("cc_binary", binaryFactory)
40 soong.RegisterModuleType("cc_test", testFactory)
41 soong.RegisterModuleType("cc_benchmark", benchmarkFactory)
42 soong.RegisterModuleType("cc_defaults", defaultsFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070043
Colin Crossca860ac2016-01-04 14:34:37 -080044 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)
Colin Cross463a90e2015-06-17 14:20:06 -070049
Colin Crossca860ac2016-01-04 14:34:37 -080050 soong.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory)
51 soong.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory)
52 soong.RegisterModuleType("cc_binary_host", binaryHostFactory)
53 soong.RegisterModuleType("cc_test_host", testHostFactory)
54 soong.RegisterModuleType("cc_benchmark_host", benchmarkHostFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070055
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.
Colin Cross6362e272015-10-29 15:25:03 -070059 common.RegisterBottomUpMutator("link", linkageMutator)
60 common.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
61 common.RegisterBottomUpMutator("deps", depsMutator)
Colin Cross463a90e2015-06-17 14:20:06 -070062}
63
Colin Cross3f40fa42015-01-30 17:27:36 -080064var (
Colin Cross1332b002015-04-07 17:11:30 -070065 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
Colin Cross3f40fa42015-01-30 17:27:36 -080066
Dan Willemsen34cc69e2015-09-23 15:26:20 -070067 LibcRoot = pctx.SourcePathVariable("LibcRoot", "bionic/libc")
Colin Cross3f40fa42015-01-30 17:27:36 -080068)
69
70// Flags used by lots of devices. Putting them in package static variables will save bytes in
71// build.ninja so they aren't repeated for every file
72var (
73 commonGlobalCflags = []string{
74 "-DANDROID",
75 "-fmessage-length=0",
76 "-W",
77 "-Wall",
78 "-Wno-unused",
79 "-Winit-self",
80 "-Wpointer-arith",
81
82 // COMMON_RELEASE_CFLAGS
83 "-DNDEBUG",
84 "-UDEBUG",
85 }
86
87 deviceGlobalCflags = []string{
Dan Willemsen490fd492015-11-24 17:53:15 -080088 "-fdiagnostics-color",
89
Colin Cross3f40fa42015-01-30 17:27:36 -080090 // TARGET_ERROR_FLAGS
91 "-Werror=return-type",
92 "-Werror=non-virtual-dtor",
93 "-Werror=address",
94 "-Werror=sequence-point",
Dan Willemsena6084a32016-03-01 15:16:50 -080095 "-Werror=date-time",
Colin Cross3f40fa42015-01-30 17:27:36 -080096 }
97
98 hostGlobalCflags = []string{}
99
100 commonGlobalCppflags = []string{
101 "-Wsign-promo",
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700102 }
103
Dan Willemsenbe03f342016-03-03 17:21:04 -0800104 noOverrideGlobalCflags = []string{
105 "-Werror=int-to-pointer-cast",
106 "-Werror=pointer-to-int-cast",
107 }
108
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700109 illegalFlags = []string{
110 "-w",
Colin Cross3f40fa42015-01-30 17:27:36 -0800111 }
112)
113
114func init() {
Dan Willemsen0c38c5e2016-03-29 17:31:57 -0700115 if common.CurrentHostType() == common.Linux {
116 commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
117 }
118
Colin Cross3f40fa42015-01-30 17:27:36 -0800119 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
120 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
121 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800122 pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800123
124 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
125
126 pctx.StaticVariable("commonClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800127 strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800128 pctx.StaticVariable("deviceClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800129 strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800130 pctx.StaticVariable("hostClangGlobalCflags",
131 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800132 pctx.StaticVariable("noOverrideClangGlobalCflags",
133 strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
134
Tim Kilbournf2948142015-03-11 12:03:03 -0700135 pctx.StaticVariable("commonClangGlobalCppflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800136 strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800137
138 // Everything in this list is a crime against abstraction and dependency tracking.
139 // Do not add anything to this list.
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800140 pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700141 []string{
142 "system/core/include",
Dan Willemsen98f93c72016-03-01 15:27:03 -0800143 "system/media/audio/include",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700144 "hardware/libhardware/include",
145 "hardware/libhardware_legacy/include",
146 "hardware/ril/include",
147 "libnativehelper/include",
148 "frameworks/native/include",
149 "frameworks/native/opengl/include",
150 "frameworks/av/include",
151 "frameworks/base/include",
152 })
Dan Willemsene0378dd2016-01-07 17:42:34 -0800153 // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
154 // with this, since there is no associated library.
155 pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
156 []string{"libnativehelper/include/nativehelper"})
Colin Cross3f40fa42015-01-30 17:27:36 -0800157
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700158 pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
159 pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
160 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
161 return override, nil
162 }
163 return "${clangDefaultBase}", nil
164 })
165 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
166 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
167 return override, nil
168 }
Colin Cross7253e0b2016-03-21 15:12:34 -0700169 return "clang-2690385", nil
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700170 })
171 pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}/bin")
Colin Cross3f40fa42015-01-30 17:27:36 -0800172}
173
Colin Crossca860ac2016-01-04 14:34:37 -0800174type Deps struct {
175 SharedLibs, LateSharedLibs []string
176 StaticLibs, LateStaticLibs, WholeStaticLibs []string
Colin Crossc472d572015-03-17 15:06:21 -0700177
Colin Cross81413472016-04-11 14:37:39 -0700178 ObjFiles []string
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700179
Dan Willemsenb40aab62016-04-20 14:21:14 -0700180 GeneratedSources []string
181 GeneratedHeaders []string
182
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700183 Cflags, ReexportedCflags []string
Colin Cross21b9a242015-03-24 14:15:58 -0700184
Colin Cross97ba0732015-03-23 17:50:24 -0700185 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700186}
187
Colin Crossca860ac2016-01-04 14:34:37 -0800188type PathDeps struct {
189 SharedLibs, LateSharedLibs common.Paths
190 StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700191
192 ObjFiles common.Paths
193 WholeStaticLibObjFiles common.Paths
194
Dan Willemsenb40aab62016-04-20 14:21:14 -0700195 GeneratedSources common.Paths
196 GeneratedHeaders common.Paths
197
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700198 Cflags, ReexportedCflags []string
199
200 CrtBegin, CrtEnd common.OptionalPath
201}
202
Colin Crossca860ac2016-01-04 14:34:37 -0800203type Flags struct {
Colin Cross28344522015-04-22 13:07:53 -0700204 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
205 AsFlags []string // Flags that apply to assembly source files
206 CFlags []string // Flags that apply to C and C++ source files
207 ConlyFlags []string // Flags that apply to C source files
208 CppFlags []string // Flags that apply to C++ source files
209 YaccFlags []string // Flags that apply to Yacc source files
210 LdFlags []string // Flags that apply to linker command lines
211
212 Nocrt bool
213 Toolchain Toolchain
214 Clang bool
Colin Crossca860ac2016-01-04 14:34:37 -0800215
216 RequiredInstructionSet string
Colin Crossc472d572015-03-17 15:06:21 -0700217}
218
Colin Crossca860ac2016-01-04 14:34:37 -0800219type BaseCompilerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700220 // 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 -0700221 Srcs []string `android:"arch_variant"`
222
223 // list of source files that should not be used to build the C/C++ module.
224 // This is most useful in the arch/multilib variants to remove non-common files
225 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700226
227 // list of module-specific flags that will be used for C and C++ compiles.
228 Cflags []string `android:"arch_variant"`
229
230 // list of module-specific flags that will be used for C++ compiles
231 Cppflags []string `android:"arch_variant"`
232
233 // list of module-specific flags that will be used for C compiles
234 Conlyflags []string `android:"arch_variant"`
235
236 // list of module-specific flags that will be used for .S compiles
237 Asflags []string `android:"arch_variant"`
238
Colin Crossca860ac2016-01-04 14:34:37 -0800239 // 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
Colin Cross7d5136f2015-05-11 13:39:40 -0700247 // list of module-specific flags that will be used for .y and .yy compiles
248 Yaccflags []string
249
Colin Cross7d5136f2015-05-11 13:39:40 -0700250 // the instruction set architecture to use to compile the C/C++
251 // module.
252 Instruction_set string `android:"arch_variant"`
253
254 // list of directories relative to the root of the source tree that will
255 // be added to the include path using -I.
256 // If possible, don't use this. If adding paths from the current directory use
257 // local_include_dirs, if adding paths from other modules use export_include_dirs in
258 // that module.
259 Include_dirs []string `android:"arch_variant"`
260
Colin Cross39d97f22015-09-14 12:30:50 -0700261 // list of files relative to the root of the source tree that will be included
262 // using -include.
263 // If possible, don't use this.
264 Include_files []string `android:"arch_variant"`
265
Colin Cross7d5136f2015-05-11 13:39:40 -0700266 // list of directories relative to the Blueprints file that will
267 // be added to the include path using -I
268 Local_include_dirs []string `android:"arch_variant"`
269
Colin Cross39d97f22015-09-14 12:30:50 -0700270 // list of files relative to the Blueprints file that will be included
271 // using -include.
272 // If possible, don't use this.
273 Local_include_files []string `android:"arch_variant"`
274
Dan Willemsenb40aab62016-04-20 14:21:14 -0700275 // list of generated sources to compile. These are the names of gensrcs or
276 // genrule modules.
277 Generated_sources []string `android:"arch_variant"`
278
279 // list of generated headers to add to the include path. These are the names
280 // of genrule modules.
281 Generated_headers []string `android:"arch_variant"`
282
Colin Crossca860ac2016-01-04 14:34:37 -0800283 // pass -frtti instead of -fno-rtti
284 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700285
Colin Crossca860ac2016-01-04 14:34:37 -0800286 Debug, Release struct {
287 // list of module-specific flags that will be used for C and C++ compiles in debug or
288 // release builds
289 Cflags []string `android:"arch_variant"`
290 } `android:"arch_variant"`
291}
Colin Cross7d5136f2015-05-11 13:39:40 -0700292
Colin Crossca860ac2016-01-04 14:34:37 -0800293type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700294 // list of modules whose object files should be linked into this module
295 // in their entirety. For static library modules, all of the .o files from the intermediate
296 // directory of the dependency will be linked into this modules .a file. For a shared library,
297 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
298 Whole_static_libs []string `android:"arch_variant"`
299
300 // list of modules that should be statically linked into this module.
301 Static_libs []string `android:"arch_variant"`
302
303 // list of modules that should be dynamically linked into this module.
304 Shared_libs []string `android:"arch_variant"`
305
Colin Crossca860ac2016-01-04 14:34:37 -0800306 // list of module-specific flags that will be used for all link steps
307 Ldflags []string `android:"arch_variant"`
308
309 // don't insert default compiler flags into asflags, cflags,
310 // cppflags, conlyflags, ldflags, or include_dirs
311 No_default_compiler_flags *bool
312
313 // list of system libraries that will be dynamically linked to
314 // shared library and executable modules. If unset, generally defaults to libc
315 // and libm. Set to [] to prevent linking against libc and libm.
316 System_shared_libs []string
317
Colin Cross7d5136f2015-05-11 13:39:40 -0700318 // allow the module to contain undefined symbols. By default,
319 // modules cannot contain undefined symbols that are not satisified by their immediate
320 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
321 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700322 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700323
Dan Willemsend67be222015-09-16 15:19:33 -0700324 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700325 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700326
Colin Cross7d5136f2015-05-11 13:39:40 -0700327 // -l arguments to pass to linker for host-provided shared libraries
328 Host_ldlibs []string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800329}
Colin Cross7d5136f2015-05-11 13:39:40 -0700330
Colin Crossca860ac2016-01-04 14:34:37 -0800331type LibraryCompilerProperties struct {
332 Static struct {
333 Srcs []string `android:"arch_variant"`
334 Exclude_srcs []string `android:"arch_variant"`
335 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700336 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800337 Shared struct {
338 Srcs []string `android:"arch_variant"`
339 Exclude_srcs []string `android:"arch_variant"`
340 Cflags []string `android:"arch_variant"`
341 } `android:"arch_variant"`
342}
343
344type LibraryLinkerProperties struct {
345 Static struct {
346 Whole_static_libs []string `android:"arch_variant"`
347 Static_libs []string `android:"arch_variant"`
348 Shared_libs []string `android:"arch_variant"`
349 } `android:"arch_variant"`
350 Shared struct {
351 Whole_static_libs []string `android:"arch_variant"`
352 Static_libs []string `android:"arch_variant"`
353 Shared_libs []string `android:"arch_variant"`
354 } `android:"arch_variant"`
355
356 // local file name to pass to the linker as --version_script
357 Version_script *string `android:"arch_variant"`
358 // local file name to pass to the linker as -unexported_symbols_list
359 Unexported_symbols_list *string `android:"arch_variant"`
360 // local file name to pass to the linker as -force_symbols_not_weak_list
361 Force_symbols_not_weak_list *string `android:"arch_variant"`
362 // local file name to pass to the linker as -force_symbols_weak_list
363 Force_symbols_weak_list *string `android:"arch_variant"`
364
365 // list of directories relative to the Blueprints file that will
366 // be added to the include path using -I for any module that links against this module
367 Export_include_dirs []string `android:"arch_variant"`
368
369 // don't link in crt_begin and crt_end. This flag should only be necessary for
370 // compiling crt or libc.
371 Nocrt *bool `android:"arch_variant"`
372}
373
374type BinaryLinkerProperties struct {
375 // compile executable with -static
376 Static_executable *bool
377
378 // set the name of the output
379 Stem string `android:"arch_variant"`
380
381 // append to the name of the output
382 Suffix string `android:"arch_variant"`
383
384 // if set, add an extra objcopy --prefix-symbols= step
385 Prefix_symbols string
386}
387
388type TestLinkerProperties struct {
389 // if set, build against the gtest library. Defaults to true.
390 Gtest bool
391
392 // Create a separate binary for each source file. Useful when there is
393 // global state that can not be torn down and reset between each test suite.
394 Test_per_src *bool
395}
396
Colin Cross81413472016-04-11 14:37:39 -0700397type ObjectLinkerProperties struct {
398 // names of other cc_object modules to link into this module using partial linking
399 Objs []string `android:"arch_variant"`
400}
401
Colin Crossca860ac2016-01-04 14:34:37 -0800402// Properties used to compile all C or C++ modules
403type BaseProperties struct {
404 // compile module with clang instead of gcc
405 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700406
407 // Minimum sdk version supported when compiling against the ndk
408 Sdk_version string
409
Colin Crossca860ac2016-01-04 14:34:37 -0800410 // don't insert default compiler flags into asflags, cflags,
411 // cppflags, conlyflags, ldflags, or include_dirs
412 No_default_compiler_flags *bool
Colin Crossc99deeb2016-04-11 15:06:20 -0700413
414 AndroidMkSharedLibs []string `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800415}
416
417type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700418 // install to a subdirectory of the default install path for the module
419 Relative_install_path string
420}
421
Colin Crossca860ac2016-01-04 14:34:37 -0800422type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700423 Native_coverage *bool
424 Required []string
425 Strip string
426 Tags []string
427 Sanitize struct {
428 Never bool `android:"arch_variant"`
429 Address bool `android:"arch_variant"`
430 Thread bool `android:"arch_variant"`
431 Undefined bool `android:"arch_variant"`
432 All_undefined bool `android:"arch_variant"`
433 Misc_undefined []string `android:"arch_variant"`
434 Coverage bool `android:"arch_variant"`
435 Recover []string
436 } `android:"arch_variant"`
Colin Crosscfad1192015-11-02 16:43:11 -0800437}
438
Colin Crossca860ac2016-01-04 14:34:37 -0800439type ModuleContextIntf interface {
440 module() *Module
441 static() bool
442 staticBinary() bool
443 clang() bool
444 toolchain() Toolchain
445 noDefaultCompilerFlags() bool
446 sdk() bool
447 sdkVersion() string
448}
449
450type ModuleContext interface {
451 common.AndroidModuleContext
452 ModuleContextIntf
453}
454
455type BaseModuleContext interface {
456 common.AndroidBaseContext
457 ModuleContextIntf
458}
459
460type Customizer interface {
461 CustomizeProperties(BaseModuleContext)
462 Properties() []interface{}
463}
464
465type feature interface {
466 begin(ctx BaseModuleContext)
467 deps(ctx BaseModuleContext, deps Deps) Deps
468 flags(ctx ModuleContext, flags Flags) Flags
469 props() []interface{}
470}
471
472type compiler interface {
473 feature
Dan Willemsenb40aab62016-04-20 14:21:14 -0700474 compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800475}
476
477type linker interface {
478 feature
479 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
Colin Crossc99deeb2016-04-11 15:06:20 -0700480 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800481}
482
483type installer interface {
484 props() []interface{}
485 install(ctx ModuleContext, path common.Path)
486 inData() bool
487}
488
Colin Crossc99deeb2016-04-11 15:06:20 -0700489type dependencyTag struct {
490 blueprint.BaseDependencyTag
491 name string
492 library bool
493}
494
495var (
496 sharedDepTag = dependencyTag{name: "shared", library: true}
497 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
498 staticDepTag = dependencyTag{name: "static", library: true}
499 lateStaticDepTag = dependencyTag{name: "late static", library: true}
500 wholeStaticDepTag = dependencyTag{name: "whole static", library: true}
Dan Willemsenb40aab62016-04-20 14:21:14 -0700501 genSourceDepTag = dependencyTag{name: "gen source"}
502 genHeaderDepTag = dependencyTag{name: "gen header"}
Colin Crossc99deeb2016-04-11 15:06:20 -0700503 objDepTag = dependencyTag{name: "obj"}
504 crtBeginDepTag = dependencyTag{name: "crtbegin"}
505 crtEndDepTag = dependencyTag{name: "crtend"}
506 reuseObjTag = dependencyTag{name: "reuse objects"}
507)
508
Colin Crossca860ac2016-01-04 14:34:37 -0800509// Module contains the properties and members used by all C/C++ module types, and implements
510// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
511// to construct the output file. Behavior can be customized with a Customizer interface
512type Module struct {
Colin Crossc472d572015-03-17 15:06:21 -0700513 common.AndroidModuleBase
Colin Crosscfad1192015-11-02 16:43:11 -0800514 common.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700515
Colin Crossca860ac2016-01-04 14:34:37 -0800516 Properties BaseProperties
517 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700518
Colin Crossca860ac2016-01-04 14:34:37 -0800519 // initialize before calling Init
520 hod common.HostOrDeviceSupported
521 multilib common.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700522
Colin Crossca860ac2016-01-04 14:34:37 -0800523 // delegates, initialize before calling Init
524 customizer Customizer
525 features []feature
526 compiler compiler
527 linker linker
528 installer installer
Colin Cross74d1ec02015-04-28 13:30:13 -0700529
Colin Crossca860ac2016-01-04 14:34:37 -0800530 outputFile common.OptionalPath
531
532 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700533}
534
Colin Crossca860ac2016-01-04 14:34:37 -0800535func (c *Module) Init() (blueprint.Module, []interface{}) {
536 props := []interface{}{&c.Properties, &c.unused}
537 if c.customizer != nil {
538 props = append(props, c.customizer.Properties()...)
539 }
540 if c.compiler != nil {
541 props = append(props, c.compiler.props()...)
542 }
543 if c.linker != nil {
544 props = append(props, c.linker.props()...)
545 }
546 if c.installer != nil {
547 props = append(props, c.installer.props()...)
548 }
549 for _, feature := range c.features {
550 props = append(props, feature.props()...)
551 }
Colin Crossc472d572015-03-17 15:06:21 -0700552
Colin Crossca860ac2016-01-04 14:34:37 -0800553 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700554
Colin Crossca860ac2016-01-04 14:34:37 -0800555 return common.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700556}
557
Colin Crossca860ac2016-01-04 14:34:37 -0800558type baseModuleContext struct {
559 common.AndroidBaseContext
560 moduleContextImpl
561}
562
563type moduleContext struct {
564 common.AndroidModuleContext
565 moduleContextImpl
566}
567
568type moduleContextImpl struct {
569 mod *Module
570 ctx BaseModuleContext
571}
572
573func (ctx *moduleContextImpl) module() *Module {
574 return ctx.mod
575}
576
577func (ctx *moduleContextImpl) clang() bool {
578 return ctx.mod.clang(ctx.ctx)
579}
580
581func (ctx *moduleContextImpl) toolchain() Toolchain {
582 return ctx.mod.toolchain(ctx.ctx)
583}
584
585func (ctx *moduleContextImpl) static() bool {
586 if ctx.mod.linker == nil {
587 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
588 }
589 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
590 return linker.static()
591 } else {
592 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
593 }
594}
595
596func (ctx *moduleContextImpl) staticBinary() bool {
597 if ctx.mod.linker == nil {
598 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
599 }
600 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
601 return linker.staticBinary()
602 } else {
603 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
604 }
605}
606
607func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
608 return Bool(ctx.mod.Properties.No_default_compiler_flags)
609}
610
611func (ctx *moduleContextImpl) sdk() bool {
612 return ctx.mod.Properties.Sdk_version != ""
613}
614
615func (ctx *moduleContextImpl) sdkVersion() string {
616 return ctx.mod.Properties.Sdk_version
617}
618
619func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
620 return &Module{
621 hod: hod,
622 multilib: multilib,
623 }
624}
625
626func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
627 module := newBaseModule(hod, multilib)
628 module.features = []feature{
629 &stlFeature{},
630 }
631 return module
632}
633
634func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
635 ctx := &moduleContext{
636 AndroidModuleContext: actx,
637 moduleContextImpl: moduleContextImpl{
638 mod: c,
639 },
640 }
641 ctx.ctx = ctx
642
643 flags := Flags{
644 Toolchain: c.toolchain(ctx),
645 Clang: c.clang(ctx),
646 }
647
648 if c.compiler != nil {
649 flags = c.compiler.flags(ctx, flags)
650 }
651 if c.linker != nil {
652 flags = c.linker.flags(ctx, flags)
653 }
654 for _, feature := range c.features {
655 flags = feature.flags(ctx, flags)
656 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800657 if ctx.Failed() {
658 return
659 }
660
Colin Crossca860ac2016-01-04 14:34:37 -0800661 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
662 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
663 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800664
Colin Crossca860ac2016-01-04 14:34:37 -0800665 // Optimization to reduce size of build.ninja
666 // Replace the long list of flags for each file with a module-local variable
667 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
668 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
669 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
670 flags.CFlags = []string{"$cflags"}
671 flags.CppFlags = []string{"$cppflags"}
672 flags.AsFlags = []string{"$asflags"}
673
Colin Crossc99deeb2016-04-11 15:06:20 -0700674 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800675 if ctx.Failed() {
676 return
677 }
678
Colin Cross28344522015-04-22 13:07:53 -0700679 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700680
Colin Crossca860ac2016-01-04 14:34:37 -0800681 var objFiles common.Paths
682 if c.compiler != nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700683 objFiles = c.compiler.compile(ctx, flags, deps)
Colin Crossca860ac2016-01-04 14:34:37 -0800684 if ctx.Failed() {
685 return
686 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800687 }
688
Colin Crossca860ac2016-01-04 14:34:37 -0800689 if c.linker != nil {
690 outputFile := c.linker.link(ctx, flags, deps, objFiles)
691 if ctx.Failed() {
692 return
693 }
694 c.outputFile = common.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700695
Colin Crossc99deeb2016-04-11 15:06:20 -0700696 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800697 c.installer.install(ctx, outputFile)
698 if ctx.Failed() {
699 return
700 }
701 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700702 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800703}
704
Colin Crossca860ac2016-01-04 14:34:37 -0800705func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
706 if c.cachedToolchain == nil {
707 arch := ctx.Arch()
708 hod := ctx.HostOrDevice()
709 ht := ctx.HostType()
710 factory := toolchainFactories[hod][ht][arch.ArchType]
711 if factory == nil {
712 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
713 return nil
714 }
715 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800716 }
Colin Crossca860ac2016-01-04 14:34:37 -0800717 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800718}
719
Colin Crossca860ac2016-01-04 14:34:37 -0800720func (c *Module) begin(ctx BaseModuleContext) {
721 if c.compiler != nil {
722 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700723 }
Colin Crossca860ac2016-01-04 14:34:37 -0800724 if c.linker != nil {
725 c.linker.begin(ctx)
726 }
727 for _, feature := range c.features {
728 feature.begin(ctx)
729 }
730}
731
Colin Crossc99deeb2016-04-11 15:06:20 -0700732func (c *Module) deps(ctx BaseModuleContext) Deps {
733 deps := Deps{}
734
735 if c.compiler != nil {
736 deps = c.compiler.deps(ctx, deps)
737 }
738 if c.linker != nil {
739 deps = c.linker.deps(ctx, deps)
740 }
741 for _, feature := range c.features {
742 deps = feature.deps(ctx, deps)
743 }
744
745 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
746 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
747 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
748 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
749 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
750
751 return deps
752}
753
Colin Crossca860ac2016-01-04 14:34:37 -0800754func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
755 ctx := &baseModuleContext{
756 AndroidBaseContext: actx,
757 moduleContextImpl: moduleContextImpl{
758 mod: c,
759 },
760 }
761 ctx.ctx = ctx
762
763 if c.customizer != nil {
764 c.customizer.CustomizeProperties(ctx)
765 }
766
767 c.begin(ctx)
768
Colin Crossc99deeb2016-04-11 15:06:20 -0700769 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800770
Colin Crossc99deeb2016-04-11 15:06:20 -0700771 c.Properties.AndroidMkSharedLibs = deps.SharedLibs
772
773 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
774 deps.WholeStaticLibs...)
775
776 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticDepTag,
777 deps.StaticLibs...)
778
779 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
780 deps.LateStaticLibs...)
781
782 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedDepTag,
783 deps.SharedLibs...)
784
785 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
786 deps.LateSharedLibs...)
787
Dan Willemsenb40aab62016-04-20 14:21:14 -0700788 actx.AddDependency(ctx.module(), genSourceDepTag, deps.GeneratedSources...)
789 actx.AddDependency(ctx.module(), genHeaderDepTag, deps.GeneratedHeaders...)
790
Colin Crossc99deeb2016-04-11 15:06:20 -0700791 actx.AddDependency(ctx.module(), objDepTag, deps.ObjFiles...)
792
793 if deps.CrtBegin != "" {
794 actx.AddDependency(ctx.module(), crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800795 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700796 if deps.CrtEnd != "" {
797 actx.AddDependency(ctx.module(), crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700798 }
Colin Cross6362e272015-10-29 15:25:03 -0700799}
Colin Cross21b9a242015-03-24 14:15:58 -0700800
Colin Cross6362e272015-10-29 15:25:03 -0700801func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800802 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700803 c.depsMutator(ctx)
804 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800805}
806
Colin Crossca860ac2016-01-04 14:34:37 -0800807func (c *Module) clang(ctx BaseModuleContext) bool {
808 clang := Bool(c.Properties.Clang)
809
810 if c.Properties.Clang == nil {
811 if ctx.Host() {
812 clang = true
813 }
814
815 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
816 clang = true
817 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800818 }
Colin Cross28344522015-04-22 13:07:53 -0700819
Colin Crossca860ac2016-01-04 14:34:37 -0800820 if !c.toolchain(ctx).ClangSupported() {
821 clang = false
822 }
823
824 return clang
825}
826
Colin Crossc99deeb2016-04-11 15:06:20 -0700827// Convert dependencies to paths. Returns a PathDeps containing paths
828func (c *Module) depsToPaths(ctx common.AndroidModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800829 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800830
Colin Crossc99deeb2016-04-11 15:06:20 -0700831 ctx.VisitDirectDeps(func(m blueprint.Module) {
832 name := ctx.OtherModuleName(m)
833 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800834
Colin Crossc99deeb2016-04-11 15:06:20 -0700835 a, _ := m.(common.AndroidModule)
836 if a == nil {
837 ctx.ModuleErrorf("module %q not an android module", name)
838 return
Colin Crossca860ac2016-01-04 14:34:37 -0800839 }
Colin Crossca860ac2016-01-04 14:34:37 -0800840
Colin Crossc99deeb2016-04-11 15:06:20 -0700841 c, _ := m.(*Module)
842 if c == nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700843 switch tag {
844 case common.DefaultsDepTag:
845 case genSourceDepTag:
846 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
847 depPaths.GeneratedSources = append(depPaths.GeneratedSources,
848 genRule.GeneratedSourceFiles()...)
849 } else {
850 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
851 }
852 case genHeaderDepTag:
853 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
854 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
855 genRule.GeneratedSourceFiles()...)
856 depPaths.Cflags = append(depPaths.Cflags,
857 includeDirsToFlags(common.Paths{genRule.GeneratedHeaderDir()}))
858 } else {
859 ctx.ModuleErrorf("module %q is not a genrule", name)
860 }
861 default:
Colin Crossc99deeb2016-04-11 15:06:20 -0700862 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -0800863 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700864 return
865 }
866
867 if !a.Enabled() {
868 ctx.ModuleErrorf("depends on disabled module %q", name)
869 return
870 }
871
872 if a.HostOrDevice() != ctx.HostOrDevice() {
873 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(), name)
874 return
875 }
876
877 if !c.outputFile.Valid() {
878 ctx.ModuleErrorf("module %q missing output file", name)
879 return
880 }
881
882 if tag == reuseObjTag {
883 depPaths.ObjFiles = append(depPaths.ObjFiles,
884 c.compiler.(*libraryCompiler).reuseObjFiles...)
885 return
886 }
887
888 var cflags []string
889 if t, _ := tag.(dependencyTag); t.library {
890 if i, ok := c.linker.(exportedFlagsProducer); ok {
891 cflags = i.exportedFlags()
892 depPaths.Cflags = append(depPaths.Cflags, cflags...)
893 }
894 }
895
896 var depPtr *common.Paths
897
898 switch tag {
899 case sharedDepTag:
900 depPtr = &depPaths.SharedLibs
901 case lateSharedDepTag:
902 depPtr = &depPaths.LateSharedLibs
903 case staticDepTag:
904 depPtr = &depPaths.StaticLibs
905 case lateStaticDepTag:
906 depPtr = &depPaths.LateStaticLibs
907 case wholeStaticDepTag:
908 depPtr = &depPaths.WholeStaticLibs
909 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, cflags...)
910 staticLib, _ := c.linker.(*libraryLinker)
911 if staticLib == nil || !staticLib.static() {
912 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
913 return
914 }
915
916 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
917 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
918 for i := range missingDeps {
919 missingDeps[i] += postfix
920 }
921 ctx.AddMissingDependencies(missingDeps)
922 }
923 depPaths.WholeStaticLibObjFiles =
924 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
925 case objDepTag:
926 depPtr = &depPaths.ObjFiles
927 case crtBeginDepTag:
928 depPaths.CrtBegin = c.outputFile
929 case crtEndDepTag:
930 depPaths.CrtEnd = c.outputFile
931 default:
932 panic(fmt.Errorf("unknown dependency tag: %s", ctx.OtherModuleDependencyTag(m)))
933 }
934
935 if depPtr != nil {
936 *depPtr = append(*depPtr, c.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -0800937 }
938 })
939
940 return depPaths
941}
942
943func (c *Module) InstallInData() bool {
944 if c.installer == nil {
945 return false
946 }
947 return c.installer.inData()
948}
949
950// Compiler
951
952type baseCompiler struct {
953 Properties BaseCompilerProperties
954}
955
956var _ compiler = (*baseCompiler)(nil)
957
958func (compiler *baseCompiler) props() []interface{} {
959 return []interface{}{&compiler.Properties}
960}
961
Dan Willemsenb40aab62016-04-20 14:21:14 -0700962func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
963
964func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
965 deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
966 deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
967
968 return deps
969}
Colin Crossca860ac2016-01-04 14:34:37 -0800970
971// Create a Flags struct that collects the compile flags from global values,
972// per-target values, module type values, and per-module Blueprints properties
973func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
974 toolchain := ctx.toolchain()
975
976 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
977 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
978 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
979 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
980 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
981
Colin Cross28344522015-04-22 13:07:53 -0700982 // Include dir cflags
Colin Crossca860ac2016-01-04 14:34:37 -0800983 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
984 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -0700985 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -0700986 includeDirsToFlags(localIncludeDirs),
987 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -0700988
Colin Crossca860ac2016-01-04 14:34:37 -0800989 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
990 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -0700991
992 flags.GlobalFlags = append(flags.GlobalFlags,
993 includeFilesToFlags(rootIncludeFiles),
994 includeFilesToFlags(localIncludeFiles))
995
Colin Crossca860ac2016-01-04 14:34:37 -0800996 if !ctx.noDefaultCompilerFlags() {
997 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -0700998 flags.GlobalFlags = append(flags.GlobalFlags,
999 "${commonGlobalIncludes}",
1000 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -08001001 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -07001002 }
1003
1004 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001005 "-I" + common.PathForModuleSrc(ctx).String(),
1006 "-I" + common.PathForModuleOut(ctx).String(),
1007 "-I" + common.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -07001008 }...)
1009 }
1010
Colin Crossca860ac2016-01-04 14:34:37 -08001011 instructionSet := compiler.Properties.Instruction_set
1012 if flags.RequiredInstructionSet != "" {
1013 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -08001014 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001015 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
1016 if flags.Clang {
1017 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
1018 }
1019 if err != nil {
1020 ctx.ModuleErrorf("%s", err)
1021 }
1022
1023 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -08001024 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001025
Colin Cross97ba0732015-03-23 17:50:24 -07001026 if flags.Clang {
1027 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001028 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
1029 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -07001030 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
1031 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
1032 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001033
1034 target := "-target " + toolchain.ClangTriple()
1035 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
1036
Colin Cross97ba0732015-03-23 17:50:24 -07001037 flags.CFlags = append(flags.CFlags, target, gccPrefix)
1038 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
1039 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -08001040 }
1041
Colin Crossca860ac2016-01-04 14:34:37 -08001042 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001043 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1044
Colin Cross97ba0732015-03-23 17:50:24 -07001045 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001046 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001047 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001048 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001049 toolchain.ClangCflags(),
1050 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001051 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001052
1053 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001054 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001055 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001056 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001057 toolchain.Cflags(),
1058 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001059 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001060 }
1061
Colin Cross7b66f152015-12-15 16:07:43 -08001062 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1063 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1064 }
1065
Colin Crossf6566ed2015-03-24 11:13:38 -07001066 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001067 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001068 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001069 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001070 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001071 }
1072 }
1073
Colin Cross97ba0732015-03-23 17:50:24 -07001074 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001075
Colin Cross97ba0732015-03-23 17:50:24 -07001076 if flags.Clang {
1077 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001078 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001079 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001080 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001081 }
1082
Colin Crossc4bde762015-11-23 16:11:30 -08001083 if flags.Clang {
1084 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1085 } else {
1086 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001087 }
1088
Colin Crossca860ac2016-01-04 14:34:37 -08001089 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001090 if ctx.Host() && !flags.Clang {
1091 // The host GCC doesn't support C++14 (and is deprecated, so likely
1092 // never will). Build these modules with C++11.
1093 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1094 } else {
1095 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1096 }
1097 }
1098
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001099 // We can enforce some rules more strictly in the code we own. strict
1100 // indicates if this is code that we can be stricter with. If we have
1101 // rules that we want to apply to *our* code (but maybe can't for
1102 // vendor/device specific things), we could extend this to be a ternary
1103 // value.
1104 strict := true
1105 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1106 strict = false
1107 }
1108
1109 // Can be used to make some annotations stricter for code we can fix
1110 // (such as when we mark functions as deprecated).
1111 if strict {
1112 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1113 }
1114
Colin Cross3f40fa42015-01-30 17:27:36 -08001115 return flags
1116}
1117
Dan Willemsenb40aab62016-04-20 14:21:14 -07001118func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001119 // Compile files listed in c.Properties.Srcs into objects
Dan Willemsenb40aab62016-04-20 14:21:14 -07001120 objFiles := compiler.compileObjs(ctx, flags, "",
1121 compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
1122 deps.GeneratedSources, deps.GeneratedHeaders)
1123
Colin Crossca860ac2016-01-04 14:34:37 -08001124 if ctx.Failed() {
1125 return nil
1126 }
1127
Colin Crossca860ac2016-01-04 14:34:37 -08001128 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001129}
1130
1131// Compile a list of source files into objects a specified subdirectory
Colin Crossca860ac2016-01-04 14:34:37 -08001132func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001133 subdir string, srcFiles, excludes []string, extraSrcs, deps common.Paths) common.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001134
Colin Crossca860ac2016-01-04 14:34:37 -08001135 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001136
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001137 inputFiles := ctx.ExpandSources(srcFiles, excludes)
Dan Willemsenb40aab62016-04-20 14:21:14 -07001138 inputFiles = append(inputFiles, extraSrcs...)
1139 srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)
1140
1141 deps = append(deps, gendeps...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001142
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001143 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001144}
1145
Colin Crossca860ac2016-01-04 14:34:37 -08001146// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1147type baseLinker struct {
1148 Properties BaseLinkerProperties
1149 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001150 VariantIsShared bool `blueprint:"mutated"`
1151 VariantIsStatic bool `blueprint:"mutated"`
1152 VariantIsStaticBinary bool `blueprint:"mutated"`
1153 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001154 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001155}
1156
Dan Willemsend30e6102016-03-30 17:35:50 -07001157func (linker *baseLinker) begin(ctx BaseModuleContext) {
1158 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001159 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001160 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001161 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001162 }
1163}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001164
Colin Crossca860ac2016-01-04 14:34:37 -08001165func (linker *baseLinker) props() []interface{} {
1166 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001167}
1168
Colin Crossca860ac2016-01-04 14:34:37 -08001169func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1170 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1171 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1172 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001173
Colin Cross74d1ec02015-04-28 13:30:13 -07001174 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001175 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001176 }
1177
Colin Crossf6566ed2015-03-24 11:13:38 -07001178 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001179 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001180 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1181 if !Bool(linker.Properties.No_libgcc) {
1182 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001183 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001184
Colin Crossca860ac2016-01-04 14:34:37 -08001185 if !linker.static() {
1186 if linker.Properties.System_shared_libs != nil {
1187 deps.LateSharedLibs = append(deps.LateSharedLibs,
1188 linker.Properties.System_shared_libs...)
1189 } else if !ctx.sdk() {
1190 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1191 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001192 }
Colin Cross577f6e42015-03-27 18:23:34 -07001193
Colin Crossca860ac2016-01-04 14:34:37 -08001194 if ctx.sdk() {
1195 version := ctx.sdkVersion()
1196 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001197 "ndk_libc."+version,
1198 "ndk_libm."+version,
1199 )
1200 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001201 }
1202
Colin Crossca860ac2016-01-04 14:34:37 -08001203 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001204}
1205
Colin Crossca860ac2016-01-04 14:34:37 -08001206func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1207 toolchain := ctx.toolchain()
1208
1209 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1210
1211 if !ctx.noDefaultCompilerFlags() {
1212 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1213 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1214 }
1215
1216 if flags.Clang {
1217 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1218 } else {
1219 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1220 }
1221
1222 if ctx.Host() {
1223 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1224 }
1225 }
1226
Dan Willemsend30e6102016-03-30 17:35:50 -07001227 if ctx.Host() && !linker.static() {
1228 rpath_prefix := `\$$ORIGIN/`
1229 if ctx.Darwin() {
1230 rpath_prefix = "@loader_path/"
1231 }
1232
Colin Crossc99deeb2016-04-11 15:06:20 -07001233 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001234 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1235 }
1236 }
1237
Dan Willemsene7174922016-03-30 17:33:52 -07001238 if flags.Clang {
1239 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1240 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001241 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1242 }
1243
1244 return flags
1245}
1246
1247func (linker *baseLinker) static() bool {
1248 return linker.dynamicProperties.VariantIsStatic
1249}
1250
1251func (linker *baseLinker) staticBinary() bool {
1252 return linker.dynamicProperties.VariantIsStaticBinary
1253}
1254
1255func (linker *baseLinker) setStatic(static bool) {
1256 linker.dynamicProperties.VariantIsStatic = static
1257}
1258
1259type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001260 // Returns true if the build options for the module have selected a static or shared build
1261 buildStatic() bool
1262 buildShared() bool
1263
1264 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001265 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001266
Colin Cross18b6dc52015-04-28 13:20:37 -07001267 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001268 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001269
1270 // Returns whether a module is a static binary
1271 staticBinary() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001272}
1273
Colin Crossca860ac2016-01-04 14:34:37 -08001274type exportedFlagsProducer interface {
Colin Cross28344522015-04-22 13:07:53 -07001275 exportedFlags() []string
Colin Cross3f40fa42015-01-30 17:27:36 -08001276}
1277
Colin Crossca860ac2016-01-04 14:34:37 -08001278type baseInstaller struct {
1279 Properties InstallerProperties
1280
1281 dir string
1282 dir64 string
1283 data bool
1284
Colin Crossa2344662016-03-24 13:14:12 -07001285 path common.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001286}
1287
1288var _ installer = (*baseInstaller)(nil)
1289
1290func (installer *baseInstaller) props() []interface{} {
1291 return []interface{}{&installer.Properties}
1292}
1293
1294func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1295 subDir := installer.dir
1296 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1297 subDir = installer.dir64
1298 }
1299 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1300 installer.path = ctx.InstallFile(dir, file)
1301}
1302
1303func (installer *baseInstaller) inData() bool {
1304 return installer.data
1305}
1306
Colin Cross3f40fa42015-01-30 17:27:36 -08001307//
1308// Combined static+shared libraries
1309//
1310
Colin Crossca860ac2016-01-04 14:34:37 -08001311type libraryCompiler struct {
1312 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001313
Colin Crossca860ac2016-01-04 14:34:37 -08001314 linker *libraryLinker
1315 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001316
Colin Crossca860ac2016-01-04 14:34:37 -08001317 // For reusing static library objects for shared library
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001318 reuseObjFiles common.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001319}
1320
Colin Crossca860ac2016-01-04 14:34:37 -08001321var _ compiler = (*libraryCompiler)(nil)
1322
1323func (library *libraryCompiler) props() []interface{} {
1324 props := library.baseCompiler.props()
1325 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001326}
1327
Colin Crossca860ac2016-01-04 14:34:37 -08001328func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1329 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001330
Dan Willemsen490fd492015-11-24 17:53:15 -08001331 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1332 // all code is position independent, and then those warnings get promoted to
1333 // errors.
1334 if ctx.HostType() != common.Windows {
1335 flags.CFlags = append(flags.CFlags, "-fPIC")
1336 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001337
Colin Crossca860ac2016-01-04 14:34:37 -08001338 if library.linker.static() {
1339 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001340 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001341 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001342 }
1343
Colin Crossca860ac2016-01-04 14:34:37 -08001344 return flags
1345}
1346
Dan Willemsenb40aab62016-04-20 14:21:14 -07001347func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001348 var objFiles common.Paths
1349
Dan Willemsenb40aab62016-04-20 14:21:14 -07001350 objFiles = library.baseCompiler.compile(ctx, flags, deps)
Colin Crossc99deeb2016-04-11 15:06:20 -07001351 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001352
1353 if library.linker.static() {
1354 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001355 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
1356 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001357 } else {
1358 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001359 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
1360 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001361 }
1362
1363 return objFiles
1364}
1365
1366type libraryLinker struct {
1367 baseLinker
1368
1369 Properties LibraryLinkerProperties
1370
1371 dynamicProperties struct {
1372 BuildStatic bool `blueprint:"mutated"`
1373 BuildShared bool `blueprint:"mutated"`
1374 }
1375
1376 exportFlags []string
1377
1378 // If we're used as a whole_static_lib, our missing dependencies need
1379 // to be given
1380 wholeStaticMissingDeps []string
1381
1382 // For whole_static_libs
1383 objFiles common.Paths
1384}
1385
1386var _ linker = (*libraryLinker)(nil)
1387var _ exportedFlagsProducer = (*libraryLinker)(nil)
1388
1389func (library *libraryLinker) props() []interface{} {
1390 props := library.baseLinker.props()
1391 return append(props, &library.Properties, &library.dynamicProperties)
1392}
1393
1394func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1395 flags = library.baseLinker.flags(ctx, flags)
1396
1397 flags.Nocrt = Bool(library.Properties.Nocrt)
1398
1399 if !library.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001400 libName := ctx.ModuleName()
1401 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1402 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001403 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001404 sharedFlag = "-shared"
1405 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001406 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001407 flags.LdFlags = append(flags.LdFlags,
1408 "-nostdlib",
1409 "-Wl,--gc-sections",
1410 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001411 }
Colin Cross97ba0732015-03-23 17:50:24 -07001412
Colin Cross0af4b842015-04-30 16:36:18 -07001413 if ctx.Darwin() {
1414 flags.LdFlags = append(flags.LdFlags,
1415 "-dynamiclib",
1416 "-single_module",
1417 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001418 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001419 )
1420 } else {
1421 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001422 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001423 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001424 )
1425 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001426 }
Colin Cross97ba0732015-03-23 17:50:24 -07001427
1428 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001429}
1430
Colin Crossca860ac2016-01-04 14:34:37 -08001431func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1432 deps = library.baseLinker.deps(ctx, deps)
1433 if library.static() {
1434 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1435 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1436 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1437 } else {
1438 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1439 if !ctx.sdk() {
1440 deps.CrtBegin = "crtbegin_so"
1441 deps.CrtEnd = "crtend_so"
1442 } else {
1443 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1444 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1445 }
1446 }
1447 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1448 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1449 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1450 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001451
Colin Crossca860ac2016-01-04 14:34:37 -08001452 return deps
1453}
Colin Cross3f40fa42015-01-30 17:27:36 -08001454
Colin Crossca860ac2016-01-04 14:34:37 -08001455func (library *libraryLinker) exportedFlags() []string {
1456 return library.exportFlags
1457}
1458
1459func (library *libraryLinker) linkStatic(ctx ModuleContext,
1460 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1461
Colin Cross21b9a242015-03-24 14:15:58 -07001462 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Crossca860ac2016-01-04 14:34:37 -08001463 library.objFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001464
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001465 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001466
Colin Cross0af4b842015-04-30 16:36:18 -07001467 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001468 TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001469 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001470 TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001471 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001472
Colin Crossca860ac2016-01-04 14:34:37 -08001473 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001474
1475 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001476
1477 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001478}
1479
Colin Crossca860ac2016-01-04 14:34:37 -08001480func (library *libraryLinker) linkShared(ctx ModuleContext,
1481 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001482
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001483 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
Colin Cross3f40fa42015-01-30 17:27:36 -08001484
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001485 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001486
Colin Crossca860ac2016-01-04 14:34:37 -08001487 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1488 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1489 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1490 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001491 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001492 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001493 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001494 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001495 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001496 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001497 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1498 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001499 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001500 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1501 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001502 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001503 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1504 }
1505 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001506 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001507 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1508 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001509 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001510 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001511 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001512 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001513 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001514 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001515 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001516 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001517 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001518 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001519 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001520 }
Colin Crossaee540a2015-07-06 17:48:31 -07001521 }
1522
Colin Crossca860ac2016-01-04 14:34:37 -08001523 sharedLibs := deps.SharedLibs
1524 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001525
Colin Crossca860ac2016-01-04 14:34:37 -08001526 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1527 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1528 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile)
1529
1530 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001531}
1532
Colin Crossca860ac2016-01-04 14:34:37 -08001533func (library *libraryLinker) link(ctx ModuleContext,
1534 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001535
Colin Crossc99deeb2016-04-11 15:06:20 -07001536 objFiles = append(objFiles, deps.ObjFiles...)
1537
Colin Crossca860ac2016-01-04 14:34:37 -08001538 var out common.Path
1539 if library.static() {
1540 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001541 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001542 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001543 }
1544
Colin Crossca860ac2016-01-04 14:34:37 -08001545 includeDirs := common.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)
1546 library.exportFlags = []string{includeDirsToFlags(includeDirs)}
1547 library.exportFlags = append(library.exportFlags, deps.ReexportedCflags...)
1548
1549 return out
1550}
1551
1552func (library *libraryLinker) buildStatic() bool {
1553 return library.dynamicProperties.BuildStatic
1554}
1555
1556func (library *libraryLinker) buildShared() bool {
1557 return library.dynamicProperties.BuildShared
1558}
1559
1560func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1561 return library.wholeStaticMissingDeps
1562}
1563
Colin Crossc99deeb2016-04-11 15:06:20 -07001564func (library *libraryLinker) installable() bool {
1565 return !library.static()
1566}
1567
Colin Crossca860ac2016-01-04 14:34:37 -08001568type libraryInstaller struct {
1569 baseInstaller
1570
1571 linker *libraryLinker
1572}
1573
1574func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1575 if !library.linker.static() {
1576 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001577 }
1578}
1579
Colin Crossca860ac2016-01-04 14:34:37 -08001580func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1581 module := newModule(hod, common.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001582
Colin Crossca860ac2016-01-04 14:34:37 -08001583 linker := &libraryLinker{}
1584 linker.dynamicProperties.BuildShared = shared
1585 linker.dynamicProperties.BuildStatic = static
1586 module.linker = linker
1587
1588 module.compiler = &libraryCompiler{
1589 linker: linker,
1590 }
1591 module.installer = &libraryInstaller{
1592 baseInstaller: baseInstaller{
1593 dir: "lib",
1594 dir64: "lib64",
1595 },
1596 linker: linker,
Dan Albertc403f7c2015-03-18 14:01:18 -07001597 }
1598
Colin Crossca860ac2016-01-04 14:34:37 -08001599 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001600}
1601
Colin Crossca860ac2016-01-04 14:34:37 -08001602func libraryFactory() (blueprint.Module, []interface{}) {
1603 module := NewLibrary(common.HostAndDeviceSupported, true, true)
1604 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001605}
1606
Colin Cross3f40fa42015-01-30 17:27:36 -08001607//
1608// Objects (for crt*.o)
1609//
1610
Colin Crossca860ac2016-01-04 14:34:37 -08001611type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001612 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001613}
1614
Colin Crossca860ac2016-01-04 14:34:37 -08001615func objectFactory() (blueprint.Module, []interface{}) {
1616 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1617 module.compiler = &baseCompiler{}
1618 module.linker = &objectLinker{}
1619 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001620}
1621
Colin Cross81413472016-04-11 14:37:39 -07001622func (object *objectLinker) props() []interface{} {
1623 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001624}
1625
Colin Crossca860ac2016-01-04 14:34:37 -08001626func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001627
Colin Cross81413472016-04-11 14:37:39 -07001628func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1629 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001630 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001631}
1632
Colin Crossca860ac2016-01-04 14:34:37 -08001633func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001634 if flags.Clang {
1635 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1636 } else {
1637 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1638 }
1639
Colin Crossca860ac2016-01-04 14:34:37 -08001640 return flags
1641}
1642
1643func (object *objectLinker) link(ctx ModuleContext,
1644 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001645
Colin Cross97ba0732015-03-23 17:50:24 -07001646 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001647
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001648 var outputFile common.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001649 if len(objFiles) == 1 {
1650 outputFile = objFiles[0]
1651 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001652 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001653 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001654 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001655 }
1656
Colin Cross3f40fa42015-01-30 17:27:36 -08001657 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001658 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001659}
1660
Colin Crossc99deeb2016-04-11 15:06:20 -07001661func (*objectLinker) installable() bool {
1662 return false
1663}
1664
Colin Cross3f40fa42015-01-30 17:27:36 -08001665//
1666// Executables
1667//
1668
Colin Crossca860ac2016-01-04 14:34:37 -08001669type binaryLinker struct {
1670 baseLinker
Colin Cross7d5136f2015-05-11 13:39:40 -07001671
Colin Crossca860ac2016-01-04 14:34:37 -08001672 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001673
Colin Crossca860ac2016-01-04 14:34:37 -08001674 hostToolPath common.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001675}
1676
Colin Crossca860ac2016-01-04 14:34:37 -08001677var _ linker = (*binaryLinker)(nil)
1678
1679func (binary *binaryLinker) props() []interface{} {
1680 return append(binary.baseLinker.props(), &binary.Properties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001681}
1682
Colin Crossca860ac2016-01-04 14:34:37 -08001683func (binary *binaryLinker) buildStatic() bool {
1684 return Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001685}
1686
Colin Crossca860ac2016-01-04 14:34:37 -08001687func (binary *binaryLinker) buildShared() bool {
1688 return !Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001689}
1690
Colin Crossca860ac2016-01-04 14:34:37 -08001691func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001692 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001693 if binary.Properties.Stem != "" {
1694 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001695 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001696
Colin Crossca860ac2016-01-04 14:34:37 -08001697 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001698}
1699
Colin Crossca860ac2016-01-04 14:34:37 -08001700func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1701 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001702 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001703 if !ctx.sdk() {
1704 if Bool(binary.Properties.Static_executable) {
1705 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001706 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001707 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001708 }
Colin Crossca860ac2016-01-04 14:34:37 -08001709 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001710 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001711 if Bool(binary.Properties.Static_executable) {
1712 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001713 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001714 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001715 }
Colin Crossca860ac2016-01-04 14:34:37 -08001716 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001717 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001718
Colin Crossca860ac2016-01-04 14:34:37 -08001719 if Bool(binary.Properties.Static_executable) {
1720 if inList("libc++_static", deps.StaticLibs) {
1721 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001722 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001723 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1724 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1725 // move them to the beginning of deps.LateStaticLibs
1726 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001727 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001728 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001729 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001730 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001731 }
Colin Crossca860ac2016-01-04 14:34:37 -08001732
1733 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1734 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1735 "from static libs or set static_executable: true")
1736 }
1737 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001738}
1739
Colin Crossc99deeb2016-04-11 15:06:20 -07001740func (*binaryLinker) installable() bool {
1741 return true
1742}
1743
Colin Crossca860ac2016-01-04 14:34:37 -08001744func NewBinary(hod common.HostOrDeviceSupported) *Module {
1745 module := newModule(hod, common.MultilibFirst)
1746 module.compiler = &baseCompiler{}
1747 module.linker = &binaryLinker{}
1748 module.installer = &baseInstaller{
1749 dir: "bin",
1750 }
1751 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001752}
1753
Colin Crossca860ac2016-01-04 14:34:37 -08001754func binaryFactory() (blueprint.Module, []interface{}) {
1755 module := NewBinary(common.HostAndDeviceSupported)
1756 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001757}
1758
Colin Crossca860ac2016-01-04 14:34:37 -08001759func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001760 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001761 binary.Properties.Static_executable = proptools.BoolPtr(false)
Colin Cross0af4b842015-04-30 16:36:18 -07001762 }
Colin Crossca860ac2016-01-04 14:34:37 -08001763 if Bool(binary.Properties.Static_executable) {
1764 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001765 }
1766}
1767
Colin Crossca860ac2016-01-04 14:34:37 -08001768func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1769 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001770
Dan Willemsen490fd492015-11-24 17:53:15 -08001771 if ctx.Host() {
1772 flags.LdFlags = append(flags.LdFlags, "-pie")
1773 if ctx.HostType() == common.Windows {
1774 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1775 }
1776 }
1777
1778 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1779 // all code is position independent, and then those warnings get promoted to
1780 // errors.
1781 if ctx.HostType() != common.Windows {
1782 flags.CFlags = append(flags.CFlags, "-fpie")
1783 }
Colin Cross97ba0732015-03-23 17:50:24 -07001784
Colin Crossf6566ed2015-03-24 11:13:38 -07001785 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001786 if Bool(binary.Properties.Static_executable) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001787 // Clang driver needs -static to create static executable.
1788 // However, bionic/linker uses -shared to overwrite.
1789 // Linker for x86 targets does not allow coexistance of -static and -shared,
1790 // so we add -static only if -shared is not used.
1791 if !inList("-shared", flags.LdFlags) {
1792 flags.LdFlags = append(flags.LdFlags, "-static")
1793 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001794
Colin Crossed4cf0b2015-03-26 14:43:45 -07001795 flags.LdFlags = append(flags.LdFlags,
1796 "-nostdlib",
1797 "-Bstatic",
1798 "-Wl,--gc-sections",
1799 )
1800
1801 } else {
1802 linker := "/system/bin/linker"
1803 if flags.Toolchain.Is64Bit() {
Colin Crossca860ac2016-01-04 14:34:37 -08001804 linker += "64"
Colin Crossed4cf0b2015-03-26 14:43:45 -07001805 }
1806
1807 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001808 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001809 "-nostdlib",
1810 "-Bdynamic",
1811 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1812 "-Wl,--gc-sections",
1813 "-Wl,-z,nocopyreloc",
1814 )
1815 }
Colin Cross0af4b842015-04-30 16:36:18 -07001816 } else if ctx.Darwin() {
1817 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001818 }
1819
Colin Cross97ba0732015-03-23 17:50:24 -07001820 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001821}
1822
Colin Crossca860ac2016-01-04 14:34:37 -08001823func (binary *binaryLinker) link(ctx ModuleContext,
1824 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001825
Colin Crossca860ac2016-01-04 14:34:37 -08001826 outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
1827 if ctx.HostOrDevice().Host() {
1828 binary.hostToolPath = common.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001829 }
Colin Crossca860ac2016-01-04 14:34:37 -08001830 ret := outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001831
Colin Crossca860ac2016-01-04 14:34:37 -08001832 if binary.Properties.Prefix_symbols != "" {
Colin Crossbfae8852015-03-26 14:44:11 -07001833 afterPrefixSymbols := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001834 outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate")
1835 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1836 flagsToBuilderFlags(flags), afterPrefixSymbols)
Colin Crossbfae8852015-03-26 14:44:11 -07001837 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001838
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001839 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001840
Colin Crossca860ac2016-01-04 14:34:37 -08001841 sharedLibs := deps.SharedLibs
1842 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1843
1844 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001845 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Crossca860ac2016-01-04 14:34:37 -08001846 flagsToBuilderFlags(flags), outputFile)
1847
1848 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001849}
Colin Cross3f40fa42015-01-30 17:27:36 -08001850
Colin Crossca860ac2016-01-04 14:34:37 -08001851func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1852 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001853}
1854
Colin Cross6362e272015-10-29 15:25:03 -07001855func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08001856 if m, ok := mctx.Module().(*Module); ok {
1857 if test, ok := m.linker.(*testLinker); ok {
1858 if Bool(test.Properties.Test_per_src) {
1859 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
1860 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1861 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
1862 }
1863 tests := mctx.CreateLocalVariations(testNames...)
1864 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1865 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
1866 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
1867 }
Colin Cross6002e052015-09-16 16:00:08 -07001868 }
1869 }
1870 }
Colin Cross7d5136f2015-05-11 13:39:40 -07001871}
1872
Colin Crossca860ac2016-01-04 14:34:37 -08001873type testLinker struct {
1874 binaryLinker
1875 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001876}
1877
Dan Willemsend30e6102016-03-30 17:35:50 -07001878func (test *testLinker) begin(ctx BaseModuleContext) {
1879 test.binaryLinker.begin(ctx)
1880
1881 runpath := "../../lib"
1882 if ctx.toolchain().Is64Bit() {
1883 runpath += "64"
1884 }
Colin Crossc99deeb2016-04-11 15:06:20 -07001885 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
Dan Willemsend30e6102016-03-30 17:35:50 -07001886}
1887
Colin Crossca860ac2016-01-04 14:34:37 -08001888func (test *testLinker) props() []interface{} {
1889 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07001890}
1891
Colin Crossca860ac2016-01-04 14:34:37 -08001892func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
1893 flags = test.binaryLinker.flags(ctx, flags)
1894
1895 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001896 return flags
1897 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001898
Colin Cross97ba0732015-03-23 17:50:24 -07001899 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001900 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001901 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001902
1903 if ctx.HostType() == common.Windows {
1904 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
1905 } else {
1906 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
1907 flags.LdFlags = append(flags.LdFlags, "-lpthread")
1908 }
1909 } else {
1910 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07001911 }
1912
1913 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross28344522015-04-22 13:07:53 -07001914 flags.CFlags = append(flags.CFlags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001915 "-I"+common.PathForSource(ctx, "external/gtest/include").String())
Dan Albertc403f7c2015-03-18 14:01:18 -07001916
Colin Cross21b9a242015-03-24 14:15:58 -07001917 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07001918}
1919
Colin Crossca860ac2016-01-04 14:34:37 -08001920func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1921 if test.Properties.Gtest {
1922 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001923 }
Colin Crossca860ac2016-01-04 14:34:37 -08001924 deps = test.binaryLinker.deps(ctx, deps)
1925 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07001926}
1927
Colin Crossca860ac2016-01-04 14:34:37 -08001928type testInstaller struct {
1929 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08001930}
1931
Colin Crossca860ac2016-01-04 14:34:37 -08001932func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
1933 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
1934 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
1935 installer.baseInstaller.install(ctx, file)
1936}
1937
1938func NewTest(hod common.HostOrDeviceSupported) *Module {
1939 module := newModule(hod, common.MultilibBoth)
1940 module.compiler = &baseCompiler{}
1941 linker := &testLinker{}
1942 linker.Properties.Gtest = true
1943 module.linker = linker
1944 module.installer = &testInstaller{
1945 baseInstaller: baseInstaller{
1946 dir: "nativetest",
1947 dir64: "nativetest64",
1948 data: true,
1949 },
Dan Albertc403f7c2015-03-18 14:01:18 -07001950 }
Colin Crossca860ac2016-01-04 14:34:37 -08001951 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001952}
1953
Colin Crossca860ac2016-01-04 14:34:37 -08001954func testFactory() (blueprint.Module, []interface{}) {
1955 module := NewTest(common.HostAndDeviceSupported)
1956 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001957}
1958
Colin Crossca860ac2016-01-04 14:34:37 -08001959type benchmarkLinker struct {
1960 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07001961}
1962
Colin Crossca860ac2016-01-04 14:34:37 -08001963func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1964 deps = benchmark.binaryLinker.deps(ctx, deps)
1965 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
1966 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07001967}
1968
Colin Crossca860ac2016-01-04 14:34:37 -08001969func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
1970 module := newModule(hod, common.MultilibFirst)
1971 module.compiler = &baseCompiler{}
1972 module.linker = &benchmarkLinker{}
1973 module.installer = &baseInstaller{
1974 dir: "nativetest",
1975 dir64: "nativetest64",
1976 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07001977 }
Colin Crossca860ac2016-01-04 14:34:37 -08001978 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07001979}
1980
Colin Crossca860ac2016-01-04 14:34:37 -08001981func benchmarkFactory() (blueprint.Module, []interface{}) {
1982 module := NewBenchmark(common.HostAndDeviceSupported)
1983 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07001984}
1985
Colin Cross3f40fa42015-01-30 17:27:36 -08001986//
1987// Static library
1988//
1989
Colin Crossca860ac2016-01-04 14:34:37 -08001990func libraryStaticFactory() (blueprint.Module, []interface{}) {
1991 module := NewLibrary(common.HostAndDeviceSupported, false, true)
1992 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001993}
1994
1995//
1996// Shared libraries
1997//
1998
Colin Crossca860ac2016-01-04 14:34:37 -08001999func librarySharedFactory() (blueprint.Module, []interface{}) {
2000 module := NewLibrary(common.HostAndDeviceSupported, true, false)
2001 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002002}
2003
2004//
2005// Host static library
2006//
2007
Colin Crossca860ac2016-01-04 14:34:37 -08002008func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
2009 module := NewLibrary(common.HostSupported, false, true)
2010 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002011}
2012
2013//
2014// Host Shared libraries
2015//
2016
Colin Crossca860ac2016-01-04 14:34:37 -08002017func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
2018 module := NewLibrary(common.HostSupported, true, false)
2019 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002020}
2021
2022//
2023// Host Binaries
2024//
2025
Colin Crossca860ac2016-01-04 14:34:37 -08002026func binaryHostFactory() (blueprint.Module, []interface{}) {
2027 module := NewBinary(common.HostSupported)
2028 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002029}
2030
2031//
Colin Cross1f8f2342015-03-26 16:09:47 -07002032// Host Tests
2033//
2034
Colin Crossca860ac2016-01-04 14:34:37 -08002035func testHostFactory() (blueprint.Module, []interface{}) {
2036 module := NewTest(common.HostSupported)
2037 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07002038}
2039
2040//
Colin Cross2ba19d92015-05-07 15:44:20 -07002041// Host Benchmarks
2042//
2043
Colin Crossca860ac2016-01-04 14:34:37 -08002044func benchmarkHostFactory() (blueprint.Module, []interface{}) {
2045 module := NewBenchmark(common.HostSupported)
2046 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002047}
2048
2049//
Colin Crosscfad1192015-11-02 16:43:11 -08002050// Defaults
2051//
Colin Crossca860ac2016-01-04 14:34:37 -08002052type Defaults struct {
Colin Crosscfad1192015-11-02 16:43:11 -08002053 common.AndroidModuleBase
2054 common.DefaultsModule
2055}
2056
Colin Crossca860ac2016-01-04 14:34:37 -08002057func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002058}
2059
Colin Crossca860ac2016-01-04 14:34:37 -08002060func defaultsFactory() (blueprint.Module, []interface{}) {
2061 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002062
2063 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002064 &BaseProperties{},
2065 &BaseCompilerProperties{},
2066 &BaseLinkerProperties{},
2067 &LibraryCompilerProperties{},
2068 &LibraryLinkerProperties{},
2069 &BinaryLinkerProperties{},
2070 &TestLinkerProperties{},
2071 &UnusedProperties{},
2072 &StlProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002073 }
2074
Dan Willemsen218f6562015-07-08 18:13:11 -07002075 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
2076 common.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002077
2078 return common.InitDefaultsModule(module, module, propertyStructs...)
2079}
2080
2081//
Colin Cross3f40fa42015-01-30 17:27:36 -08002082// Device libraries shipped with gcc
2083//
2084
Colin Crossca860ac2016-01-04 14:34:37 -08002085type toolchainLibraryLinker struct {
2086 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002087}
2088
Colin Crossca860ac2016-01-04 14:34:37 -08002089var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2090
2091func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002092 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002093 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002094}
2095
Colin Crossca860ac2016-01-04 14:34:37 -08002096func (*toolchainLibraryLinker) buildStatic() bool {
2097 return true
2098}
Colin Cross3f40fa42015-01-30 17:27:36 -08002099
Colin Crossca860ac2016-01-04 14:34:37 -08002100func (*toolchainLibraryLinker) buildShared() bool {
2101 return false
2102}
2103
2104func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
2105 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2106 module.compiler = &baseCompiler{}
2107 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002108 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002109 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002110}
2111
Colin Crossca860ac2016-01-04 14:34:37 -08002112func (library *toolchainLibraryLinker) link(ctx ModuleContext,
2113 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002114
2115 libName := ctx.ModuleName() + staticLibraryExtension
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002116 outputFile := common.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002117
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002118 if flags.Clang {
2119 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2120 }
2121
Colin Crossca860ac2016-01-04 14:34:37 -08002122 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002123
2124 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002125
Colin Crossca860ac2016-01-04 14:34:37 -08002126 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002127}
2128
Colin Crossc99deeb2016-04-11 15:06:20 -07002129func (*toolchainLibraryLinker) installable() bool {
2130 return false
2131}
2132
Dan Albertbe961682015-03-18 23:38:50 -07002133// NDK prebuilt libraries.
2134//
2135// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2136// either (with the exception of the shared STLs, which are installed to the app's directory rather
2137// than to the system image).
2138
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002139func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2140 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2141 version, toolchain.Name()))
Dan Albertbe961682015-03-18 23:38:50 -07002142}
2143
Dan Albertc3144b12015-04-28 18:17:56 -07002144func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002145 ext string, version string) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002146
2147 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2148 // We want to translate to just NAME.EXT
2149 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2150 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002151 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002152}
2153
Colin Crossca860ac2016-01-04 14:34:37 -08002154type ndkPrebuiltObjectLinker struct {
2155 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002156}
2157
Colin Crossca860ac2016-01-04 14:34:37 -08002158func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002159 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002160 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002161}
2162
Colin Crossca860ac2016-01-04 14:34:37 -08002163func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2164 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2165 module.linker = &ndkPrebuiltObjectLinker{}
2166 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002167}
2168
Colin Crossca860ac2016-01-04 14:34:37 -08002169func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2170 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002171 // A null build step, but it sets up the output path.
2172 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2173 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2174 }
2175
Colin Crossca860ac2016-01-04 14:34:37 -08002176 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002177}
2178
Colin Crossca860ac2016-01-04 14:34:37 -08002179type ndkPrebuiltLibraryLinker struct {
2180 libraryLinker
2181 Properties struct {
2182 Export_include_dirs []string `android:"arch_variant"`
2183 }
Dan Albertc3144b12015-04-28 18:17:56 -07002184}
2185
Colin Crossca860ac2016-01-04 14:34:37 -08002186var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2187var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002188
Colin Crossca860ac2016-01-04 14:34:37 -08002189func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Crossc99deeb2016-04-11 15:06:20 -07002190 return append(ndk.libraryLinker.props(), &ndk.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002191}
2192
Colin Crossca860ac2016-01-04 14:34:37 -08002193func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002194 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002195 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002196}
2197
Colin Crossca860ac2016-01-04 14:34:37 -08002198func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2199 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2200 linker := &ndkPrebuiltLibraryLinker{}
2201 linker.dynamicProperties.BuildShared = true
2202 module.linker = linker
2203 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002204}
2205
Colin Crossca860ac2016-01-04 14:34:37 -08002206func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2207 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002208 // A null build step, but it sets up the output path.
2209 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2210 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2211 }
2212
Colin Crossca860ac2016-01-04 14:34:37 -08002213 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2214 ndk.exportFlags = []string{common.JoinWithPrefix(includeDirs.Strings(), "-isystem ")}
Dan Albertbe961682015-03-18 23:38:50 -07002215
Colin Crossca860ac2016-01-04 14:34:37 -08002216 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2217 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002218}
2219
2220// The NDK STLs are slightly different from the prebuilt system libraries:
2221// * Are not specific to each platform version.
2222// * The libraries are not in a predictable location for each STL.
2223
Colin Crossca860ac2016-01-04 14:34:37 -08002224type ndkPrebuiltStlLinker struct {
2225 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002226}
2227
Colin Crossca860ac2016-01-04 14:34:37 -08002228func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2229 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2230 linker := &ndkPrebuiltStlLinker{}
2231 linker.dynamicProperties.BuildShared = true
2232 module.linker = linker
2233 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002234}
2235
Colin Crossca860ac2016-01-04 14:34:37 -08002236func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2237 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2238 linker := &ndkPrebuiltStlLinker{}
2239 linker.dynamicProperties.BuildStatic = true
2240 module.linker = linker
2241 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002242}
2243
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002244func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002245 gccVersion := toolchain.GccVersion()
2246 var libDir string
2247 switch stl {
2248 case "libstlport":
2249 libDir = "cxx-stl/stlport/libs"
2250 case "libc++":
2251 libDir = "cxx-stl/llvm-libc++/libs"
2252 case "libgnustl":
2253 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2254 }
2255
2256 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002257 ndkSrcRoot := "prebuilts/ndk/current/sources"
2258 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002259 }
2260
2261 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002262 return common.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002263}
2264
Colin Crossca860ac2016-01-04 14:34:37 -08002265func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2266 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002267 // A null build step, but it sets up the output path.
2268 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2269 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2270 }
2271
Colin Crossca860ac2016-01-04 14:34:37 -08002272 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2273 ndk.exportFlags = []string{includeDirsToFlags(includeDirs)}
Dan Albertbe961682015-03-18 23:38:50 -07002274
2275 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002276 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002277 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002278 libExt = staticLibraryExtension
2279 }
2280
2281 stlName := strings.TrimSuffix(libName, "_shared")
2282 stlName = strings.TrimSuffix(stlName, "_static")
2283 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002284 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002285}
2286
Colin Cross6362e272015-10-29 15:25:03 -07002287func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002288 if m, ok := mctx.Module().(*Module); ok {
2289 if m.linker != nil {
2290 if linker, ok := m.linker.(baseLinkerInterface); ok {
2291 var modules []blueprint.Module
2292 if linker.buildStatic() && linker.buildShared() {
2293 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002294 static := modules[0].(*Module)
2295 shared := modules[1].(*Module)
2296
2297 static.linker.(baseLinkerInterface).setStatic(true)
2298 shared.linker.(baseLinkerInterface).setStatic(false)
2299
2300 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2301 sharedCompiler := shared.compiler.(*libraryCompiler)
2302 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2303 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2304 // Optimize out compiling common .o files twice for static+shared libraries
2305 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2306 sharedCompiler.baseCompiler.Properties.Srcs = nil
2307 }
2308 }
Colin Crossca860ac2016-01-04 14:34:37 -08002309 } else if linker.buildStatic() {
2310 modules = mctx.CreateLocalVariations("static")
2311 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2312 } else if linker.buildShared() {
2313 modules = mctx.CreateLocalVariations("shared")
2314 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2315 } else {
2316 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2317 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002318 }
2319 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002320 }
2321}
Colin Cross74d1ec02015-04-28 13:30:13 -07002322
2323// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2324// modifies the slice contents in place, and returns a subslice of the original slice
2325func lastUniqueElements(list []string) []string {
2326 totalSkip := 0
2327 for i := len(list) - 1; i >= totalSkip; i-- {
2328 skip := 0
2329 for j := i - 1; j >= totalSkip; j-- {
2330 if list[i] == list[j] {
2331 skip++
2332 } else {
2333 list[j+skip] = list[j]
2334 }
2335 }
2336 totalSkip += skip
2337 }
2338 return list[totalSkip:]
2339}
Colin Cross06a931b2015-10-28 17:23:31 -07002340
2341var Bool = proptools.Bool