blob: 1c1ef10e66bf396cfd52455305e9a97d9d62af86 [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
180 Cflags, ReexportedCflags []string
Colin Cross21b9a242015-03-24 14:15:58 -0700181
Colin Cross97ba0732015-03-23 17:50:24 -0700182 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700183}
184
Colin Crossca860ac2016-01-04 14:34:37 -0800185type PathDeps struct {
186 SharedLibs, LateSharedLibs common.Paths
187 StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700188
189 ObjFiles common.Paths
190 WholeStaticLibObjFiles common.Paths
191
192 Cflags, ReexportedCflags []string
193
194 CrtBegin, CrtEnd common.OptionalPath
195}
196
Colin Crossca860ac2016-01-04 14:34:37 -0800197type Flags struct {
Colin Cross28344522015-04-22 13:07:53 -0700198 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
199 AsFlags []string // Flags that apply to assembly source files
200 CFlags []string // Flags that apply to C and C++ source files
201 ConlyFlags []string // Flags that apply to C source files
202 CppFlags []string // Flags that apply to C++ source files
203 YaccFlags []string // Flags that apply to Yacc source files
204 LdFlags []string // Flags that apply to linker command lines
205
206 Nocrt bool
207 Toolchain Toolchain
208 Clang bool
Colin Crossca860ac2016-01-04 14:34:37 -0800209
210 RequiredInstructionSet string
Colin Crossc472d572015-03-17 15:06:21 -0700211}
212
Colin Crossca860ac2016-01-04 14:34:37 -0800213type BaseCompilerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700214 // 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 -0700215 Srcs []string `android:"arch_variant"`
216
217 // list of source files that should not be used to build the C/C++ module.
218 // This is most useful in the arch/multilib variants to remove non-common files
219 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700220
221 // list of module-specific flags that will be used for C and C++ compiles.
222 Cflags []string `android:"arch_variant"`
223
224 // list of module-specific flags that will be used for C++ compiles
225 Cppflags []string `android:"arch_variant"`
226
227 // list of module-specific flags that will be used for C compiles
228 Conlyflags []string `android:"arch_variant"`
229
230 // list of module-specific flags that will be used for .S compiles
231 Asflags []string `android:"arch_variant"`
232
Colin Crossca860ac2016-01-04 14:34:37 -0800233 // list of module-specific flags that will be used for C and C++ compiles when
234 // compiling with clang
235 Clang_cflags []string `android:"arch_variant"`
236
237 // list of module-specific flags that will be used for .S compiles when
238 // compiling with clang
239 Clang_asflags []string `android:"arch_variant"`
240
Colin Cross7d5136f2015-05-11 13:39:40 -0700241 // list of module-specific flags that will be used for .y and .yy compiles
242 Yaccflags []string
243
Colin Cross7d5136f2015-05-11 13:39:40 -0700244 // the instruction set architecture to use to compile the C/C++
245 // module.
246 Instruction_set string `android:"arch_variant"`
247
248 // list of directories relative to the root of the source tree that will
249 // be added to the include path using -I.
250 // If possible, don't use this. If adding paths from the current directory use
251 // local_include_dirs, if adding paths from other modules use export_include_dirs in
252 // that module.
253 Include_dirs []string `android:"arch_variant"`
254
Colin Cross39d97f22015-09-14 12:30:50 -0700255 // list of files relative to the root of the source tree that will be included
256 // using -include.
257 // If possible, don't use this.
258 Include_files []string `android:"arch_variant"`
259
Colin Cross7d5136f2015-05-11 13:39:40 -0700260 // list of directories relative to the Blueprints file that will
261 // be added to the include path using -I
262 Local_include_dirs []string `android:"arch_variant"`
263
Colin Cross39d97f22015-09-14 12:30:50 -0700264 // list of files relative to the Blueprints file that will be included
265 // using -include.
266 // If possible, don't use this.
267 Local_include_files []string `android:"arch_variant"`
268
Colin Crossca860ac2016-01-04 14:34:37 -0800269 // pass -frtti instead of -fno-rtti
270 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700271
Colin Crossca860ac2016-01-04 14:34:37 -0800272 Debug, Release struct {
273 // list of module-specific flags that will be used for C and C++ compiles in debug or
274 // release builds
275 Cflags []string `android:"arch_variant"`
276 } `android:"arch_variant"`
277}
Colin Cross7d5136f2015-05-11 13:39:40 -0700278
Colin Crossca860ac2016-01-04 14:34:37 -0800279type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700280 // list of modules whose object files should be linked into this module
281 // in their entirety. For static library modules, all of the .o files from the intermediate
282 // directory of the dependency will be linked into this modules .a file. For a shared library,
283 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
284 Whole_static_libs []string `android:"arch_variant"`
285
286 // list of modules that should be statically linked into this module.
287 Static_libs []string `android:"arch_variant"`
288
289 // list of modules that should be dynamically linked into this module.
290 Shared_libs []string `android:"arch_variant"`
291
Colin Crossca860ac2016-01-04 14:34:37 -0800292 // list of module-specific flags that will be used for all link steps
293 Ldflags []string `android:"arch_variant"`
294
295 // don't insert default compiler flags into asflags, cflags,
296 // cppflags, conlyflags, ldflags, or include_dirs
297 No_default_compiler_flags *bool
298
299 // list of system libraries that will be dynamically linked to
300 // shared library and executable modules. If unset, generally defaults to libc
301 // and libm. Set to [] to prevent linking against libc and libm.
302 System_shared_libs []string
303
Colin Cross7d5136f2015-05-11 13:39:40 -0700304 // allow the module to contain undefined symbols. By default,
305 // modules cannot contain undefined symbols that are not satisified by their immediate
306 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
307 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700308 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700309
Dan Willemsend67be222015-09-16 15:19:33 -0700310 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700311 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700312
Colin Cross7d5136f2015-05-11 13:39:40 -0700313 // -l arguments to pass to linker for host-provided shared libraries
314 Host_ldlibs []string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800315}
Colin Cross7d5136f2015-05-11 13:39:40 -0700316
Colin Crossca860ac2016-01-04 14:34:37 -0800317type LibraryCompilerProperties struct {
318 Static struct {
319 Srcs []string `android:"arch_variant"`
320 Exclude_srcs []string `android:"arch_variant"`
321 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700322 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800323 Shared struct {
324 Srcs []string `android:"arch_variant"`
325 Exclude_srcs []string `android:"arch_variant"`
326 Cflags []string `android:"arch_variant"`
327 } `android:"arch_variant"`
328}
329
330type LibraryLinkerProperties struct {
331 Static struct {
332 Whole_static_libs []string `android:"arch_variant"`
333 Static_libs []string `android:"arch_variant"`
334 Shared_libs []string `android:"arch_variant"`
335 } `android:"arch_variant"`
336 Shared struct {
337 Whole_static_libs []string `android:"arch_variant"`
338 Static_libs []string `android:"arch_variant"`
339 Shared_libs []string `android:"arch_variant"`
340 } `android:"arch_variant"`
341
342 // local file name to pass to the linker as --version_script
343 Version_script *string `android:"arch_variant"`
344 // local file name to pass to the linker as -unexported_symbols_list
345 Unexported_symbols_list *string `android:"arch_variant"`
346 // local file name to pass to the linker as -force_symbols_not_weak_list
347 Force_symbols_not_weak_list *string `android:"arch_variant"`
348 // local file name to pass to the linker as -force_symbols_weak_list
349 Force_symbols_weak_list *string `android:"arch_variant"`
350
351 // list of directories relative to the Blueprints file that will
352 // be added to the include path using -I for any module that links against this module
353 Export_include_dirs []string `android:"arch_variant"`
354
355 // don't link in crt_begin and crt_end. This flag should only be necessary for
356 // compiling crt or libc.
357 Nocrt *bool `android:"arch_variant"`
358}
359
360type BinaryLinkerProperties struct {
361 // compile executable with -static
362 Static_executable *bool
363
364 // set the name of the output
365 Stem string `android:"arch_variant"`
366
367 // append to the name of the output
368 Suffix string `android:"arch_variant"`
369
370 // if set, add an extra objcopy --prefix-symbols= step
371 Prefix_symbols string
372}
373
374type TestLinkerProperties struct {
375 // if set, build against the gtest library. Defaults to true.
376 Gtest bool
377
378 // Create a separate binary for each source file. Useful when there is
379 // global state that can not be torn down and reset between each test suite.
380 Test_per_src *bool
381}
382
Colin Cross81413472016-04-11 14:37:39 -0700383type ObjectLinkerProperties struct {
384 // names of other cc_object modules to link into this module using partial linking
385 Objs []string `android:"arch_variant"`
386}
387
Colin Crossca860ac2016-01-04 14:34:37 -0800388// Properties used to compile all C or C++ modules
389type BaseProperties struct {
390 // compile module with clang instead of gcc
391 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700392
393 // Minimum sdk version supported when compiling against the ndk
394 Sdk_version string
395
Colin Crossca860ac2016-01-04 14:34:37 -0800396 // don't insert default compiler flags into asflags, cflags,
397 // cppflags, conlyflags, ldflags, or include_dirs
398 No_default_compiler_flags *bool
Colin Crossc99deeb2016-04-11 15:06:20 -0700399
400 AndroidMkSharedLibs []string `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800401}
402
403type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700404 // install to a subdirectory of the default install path for the module
405 Relative_install_path string
406}
407
Colin Crossca860ac2016-01-04 14:34:37 -0800408type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700409 Native_coverage *bool
410 Required []string
411 Strip string
412 Tags []string
413 Sanitize struct {
414 Never bool `android:"arch_variant"`
415 Address bool `android:"arch_variant"`
416 Thread bool `android:"arch_variant"`
417 Undefined bool `android:"arch_variant"`
418 All_undefined bool `android:"arch_variant"`
419 Misc_undefined []string `android:"arch_variant"`
420 Coverage bool `android:"arch_variant"`
421 Recover []string
422 } `android:"arch_variant"`
Colin Crosscfad1192015-11-02 16:43:11 -0800423}
424
Colin Crossca860ac2016-01-04 14:34:37 -0800425type ModuleContextIntf interface {
426 module() *Module
427 static() bool
428 staticBinary() bool
429 clang() bool
430 toolchain() Toolchain
431 noDefaultCompilerFlags() bool
432 sdk() bool
433 sdkVersion() string
434}
435
436type ModuleContext interface {
437 common.AndroidModuleContext
438 ModuleContextIntf
439}
440
441type BaseModuleContext interface {
442 common.AndroidBaseContext
443 ModuleContextIntf
444}
445
446type Customizer interface {
447 CustomizeProperties(BaseModuleContext)
448 Properties() []interface{}
449}
450
451type feature interface {
452 begin(ctx BaseModuleContext)
453 deps(ctx BaseModuleContext, deps Deps) Deps
454 flags(ctx ModuleContext, flags Flags) Flags
455 props() []interface{}
456}
457
458type compiler interface {
459 feature
460 compile(ctx ModuleContext, flags Flags) common.Paths
461}
462
463type linker interface {
464 feature
465 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
Colin Crossc99deeb2016-04-11 15:06:20 -0700466 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800467}
468
469type installer interface {
470 props() []interface{}
471 install(ctx ModuleContext, path common.Path)
472 inData() bool
473}
474
Colin Crossc99deeb2016-04-11 15:06:20 -0700475type dependencyTag struct {
476 blueprint.BaseDependencyTag
477 name string
478 library bool
479}
480
481var (
482 sharedDepTag = dependencyTag{name: "shared", library: true}
483 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
484 staticDepTag = dependencyTag{name: "static", library: true}
485 lateStaticDepTag = dependencyTag{name: "late static", library: true}
486 wholeStaticDepTag = dependencyTag{name: "whole static", library: true}
487 objDepTag = dependencyTag{name: "obj"}
488 crtBeginDepTag = dependencyTag{name: "crtbegin"}
489 crtEndDepTag = dependencyTag{name: "crtend"}
490 reuseObjTag = dependencyTag{name: "reuse objects"}
491)
492
Colin Crossca860ac2016-01-04 14:34:37 -0800493// Module contains the properties and members used by all C/C++ module types, and implements
494// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
495// to construct the output file. Behavior can be customized with a Customizer interface
496type Module struct {
Colin Crossc472d572015-03-17 15:06:21 -0700497 common.AndroidModuleBase
Colin Crosscfad1192015-11-02 16:43:11 -0800498 common.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700499
Colin Crossca860ac2016-01-04 14:34:37 -0800500 Properties BaseProperties
501 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700502
Colin Crossca860ac2016-01-04 14:34:37 -0800503 // initialize before calling Init
504 hod common.HostOrDeviceSupported
505 multilib common.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700506
Colin Crossca860ac2016-01-04 14:34:37 -0800507 // delegates, initialize before calling Init
508 customizer Customizer
509 features []feature
510 compiler compiler
511 linker linker
512 installer installer
Colin Cross74d1ec02015-04-28 13:30:13 -0700513
Colin Crossca860ac2016-01-04 14:34:37 -0800514 outputFile common.OptionalPath
515
516 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700517}
518
Colin Crossca860ac2016-01-04 14:34:37 -0800519func (c *Module) Init() (blueprint.Module, []interface{}) {
520 props := []interface{}{&c.Properties, &c.unused}
521 if c.customizer != nil {
522 props = append(props, c.customizer.Properties()...)
523 }
524 if c.compiler != nil {
525 props = append(props, c.compiler.props()...)
526 }
527 if c.linker != nil {
528 props = append(props, c.linker.props()...)
529 }
530 if c.installer != nil {
531 props = append(props, c.installer.props()...)
532 }
533 for _, feature := range c.features {
534 props = append(props, feature.props()...)
535 }
Colin Crossc472d572015-03-17 15:06:21 -0700536
Colin Crossca860ac2016-01-04 14:34:37 -0800537 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700538
Colin Crossca860ac2016-01-04 14:34:37 -0800539 return common.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700540}
541
Colin Crossca860ac2016-01-04 14:34:37 -0800542type baseModuleContext struct {
543 common.AndroidBaseContext
544 moduleContextImpl
545}
546
547type moduleContext struct {
548 common.AndroidModuleContext
549 moduleContextImpl
550}
551
552type moduleContextImpl struct {
553 mod *Module
554 ctx BaseModuleContext
555}
556
557func (ctx *moduleContextImpl) module() *Module {
558 return ctx.mod
559}
560
561func (ctx *moduleContextImpl) clang() bool {
562 return ctx.mod.clang(ctx.ctx)
563}
564
565func (ctx *moduleContextImpl) toolchain() Toolchain {
566 return ctx.mod.toolchain(ctx.ctx)
567}
568
569func (ctx *moduleContextImpl) static() bool {
570 if ctx.mod.linker == nil {
571 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
572 }
573 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
574 return linker.static()
575 } else {
576 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
577 }
578}
579
580func (ctx *moduleContextImpl) staticBinary() bool {
581 if ctx.mod.linker == nil {
582 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
583 }
584 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
585 return linker.staticBinary()
586 } else {
587 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
588 }
589}
590
591func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
592 return Bool(ctx.mod.Properties.No_default_compiler_flags)
593}
594
595func (ctx *moduleContextImpl) sdk() bool {
596 return ctx.mod.Properties.Sdk_version != ""
597}
598
599func (ctx *moduleContextImpl) sdkVersion() string {
600 return ctx.mod.Properties.Sdk_version
601}
602
603func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
604 return &Module{
605 hod: hod,
606 multilib: multilib,
607 }
608}
609
610func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
611 module := newBaseModule(hod, multilib)
612 module.features = []feature{
613 &stlFeature{},
614 }
615 return module
616}
617
618func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
619 ctx := &moduleContext{
620 AndroidModuleContext: actx,
621 moduleContextImpl: moduleContextImpl{
622 mod: c,
623 },
624 }
625 ctx.ctx = ctx
626
627 flags := Flags{
628 Toolchain: c.toolchain(ctx),
629 Clang: c.clang(ctx),
630 }
631
632 if c.compiler != nil {
633 flags = c.compiler.flags(ctx, flags)
634 }
635 if c.linker != nil {
636 flags = c.linker.flags(ctx, flags)
637 }
638 for _, feature := range c.features {
639 flags = feature.flags(ctx, flags)
640 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800641 if ctx.Failed() {
642 return
643 }
644
Colin Crossca860ac2016-01-04 14:34:37 -0800645 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
646 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
647 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800648
Colin Crossca860ac2016-01-04 14:34:37 -0800649 // Optimization to reduce size of build.ninja
650 // Replace the long list of flags for each file with a module-local variable
651 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
652 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
653 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
654 flags.CFlags = []string{"$cflags"}
655 flags.CppFlags = []string{"$cppflags"}
656 flags.AsFlags = []string{"$asflags"}
657
Colin Crossc99deeb2016-04-11 15:06:20 -0700658 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800659 if ctx.Failed() {
660 return
661 }
662
Colin Cross28344522015-04-22 13:07:53 -0700663 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700664
Colin Crossca860ac2016-01-04 14:34:37 -0800665 var objFiles common.Paths
666 if c.compiler != nil {
667 objFiles = c.compiler.compile(ctx, flags)
668 if ctx.Failed() {
669 return
670 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800671 }
672
Colin Crossca860ac2016-01-04 14:34:37 -0800673 if c.linker != nil {
674 outputFile := c.linker.link(ctx, flags, deps, objFiles)
675 if ctx.Failed() {
676 return
677 }
678 c.outputFile = common.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700679
Colin Crossc99deeb2016-04-11 15:06:20 -0700680 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800681 c.installer.install(ctx, outputFile)
682 if ctx.Failed() {
683 return
684 }
685 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700686 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800687}
688
Colin Crossca860ac2016-01-04 14:34:37 -0800689func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
690 if c.cachedToolchain == nil {
691 arch := ctx.Arch()
692 hod := ctx.HostOrDevice()
693 ht := ctx.HostType()
694 factory := toolchainFactories[hod][ht][arch.ArchType]
695 if factory == nil {
696 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
697 return nil
698 }
699 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800700 }
Colin Crossca860ac2016-01-04 14:34:37 -0800701 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800702}
703
Colin Crossca860ac2016-01-04 14:34:37 -0800704func (c *Module) begin(ctx BaseModuleContext) {
705 if c.compiler != nil {
706 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700707 }
Colin Crossca860ac2016-01-04 14:34:37 -0800708 if c.linker != nil {
709 c.linker.begin(ctx)
710 }
711 for _, feature := range c.features {
712 feature.begin(ctx)
713 }
714}
715
Colin Crossc99deeb2016-04-11 15:06:20 -0700716func (c *Module) deps(ctx BaseModuleContext) Deps {
717 deps := Deps{}
718
719 if c.compiler != nil {
720 deps = c.compiler.deps(ctx, deps)
721 }
722 if c.linker != nil {
723 deps = c.linker.deps(ctx, deps)
724 }
725 for _, feature := range c.features {
726 deps = feature.deps(ctx, deps)
727 }
728
729 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
730 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
731 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
732 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
733 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
734
735 return deps
736}
737
Colin Crossca860ac2016-01-04 14:34:37 -0800738func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
739 ctx := &baseModuleContext{
740 AndroidBaseContext: actx,
741 moduleContextImpl: moduleContextImpl{
742 mod: c,
743 },
744 }
745 ctx.ctx = ctx
746
747 if c.customizer != nil {
748 c.customizer.CustomizeProperties(ctx)
749 }
750
751 c.begin(ctx)
752
Colin Crossc99deeb2016-04-11 15:06:20 -0700753 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800754
Colin Crossc99deeb2016-04-11 15:06:20 -0700755 c.Properties.AndroidMkSharedLibs = deps.SharedLibs
756
757 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
758 deps.WholeStaticLibs...)
759
760 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticDepTag,
761 deps.StaticLibs...)
762
763 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
764 deps.LateStaticLibs...)
765
766 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedDepTag,
767 deps.SharedLibs...)
768
769 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
770 deps.LateSharedLibs...)
771
772 actx.AddDependency(ctx.module(), objDepTag, deps.ObjFiles...)
773
774 if deps.CrtBegin != "" {
775 actx.AddDependency(ctx.module(), crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800776 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700777 if deps.CrtEnd != "" {
778 actx.AddDependency(ctx.module(), crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700779 }
Colin Cross6362e272015-10-29 15:25:03 -0700780}
Colin Cross21b9a242015-03-24 14:15:58 -0700781
Colin Cross6362e272015-10-29 15:25:03 -0700782func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800783 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700784 c.depsMutator(ctx)
785 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800786}
787
Colin Crossca860ac2016-01-04 14:34:37 -0800788func (c *Module) clang(ctx BaseModuleContext) bool {
789 clang := Bool(c.Properties.Clang)
790
791 if c.Properties.Clang == nil {
792 if ctx.Host() {
793 clang = true
794 }
795
796 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
797 clang = true
798 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800799 }
Colin Cross28344522015-04-22 13:07:53 -0700800
Colin Crossca860ac2016-01-04 14:34:37 -0800801 if !c.toolchain(ctx).ClangSupported() {
802 clang = false
803 }
804
805 return clang
806}
807
Colin Crossc99deeb2016-04-11 15:06:20 -0700808// Convert dependencies to paths. Returns a PathDeps containing paths
809func (c *Module) depsToPaths(ctx common.AndroidModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800810 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800811
Colin Crossc99deeb2016-04-11 15:06:20 -0700812 ctx.VisitDirectDeps(func(m blueprint.Module) {
813 name := ctx.OtherModuleName(m)
814 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800815
Colin Crossc99deeb2016-04-11 15:06:20 -0700816 a, _ := m.(common.AndroidModule)
817 if a == nil {
818 ctx.ModuleErrorf("module %q not an android module", name)
819 return
Colin Crossca860ac2016-01-04 14:34:37 -0800820 }
Colin Crossca860ac2016-01-04 14:34:37 -0800821
Colin Crossc99deeb2016-04-11 15:06:20 -0700822 c, _ := m.(*Module)
823 if c == nil {
824 if tag != common.DefaultsDepTag {
825 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -0800826 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700827 return
828 }
829
830 if !a.Enabled() {
831 ctx.ModuleErrorf("depends on disabled module %q", name)
832 return
833 }
834
835 if a.HostOrDevice() != ctx.HostOrDevice() {
836 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(), name)
837 return
838 }
839
840 if !c.outputFile.Valid() {
841 ctx.ModuleErrorf("module %q missing output file", name)
842 return
843 }
844
845 if tag == reuseObjTag {
846 depPaths.ObjFiles = append(depPaths.ObjFiles,
847 c.compiler.(*libraryCompiler).reuseObjFiles...)
848 return
849 }
850
851 var cflags []string
852 if t, _ := tag.(dependencyTag); t.library {
853 if i, ok := c.linker.(exportedFlagsProducer); ok {
854 cflags = i.exportedFlags()
855 depPaths.Cflags = append(depPaths.Cflags, cflags...)
856 }
857 }
858
859 var depPtr *common.Paths
860
861 switch tag {
862 case sharedDepTag:
863 depPtr = &depPaths.SharedLibs
864 case lateSharedDepTag:
865 depPtr = &depPaths.LateSharedLibs
866 case staticDepTag:
867 depPtr = &depPaths.StaticLibs
868 case lateStaticDepTag:
869 depPtr = &depPaths.LateStaticLibs
870 case wholeStaticDepTag:
871 depPtr = &depPaths.WholeStaticLibs
872 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, cflags...)
873 staticLib, _ := c.linker.(*libraryLinker)
874 if staticLib == nil || !staticLib.static() {
875 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
876 return
877 }
878
879 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
880 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
881 for i := range missingDeps {
882 missingDeps[i] += postfix
883 }
884 ctx.AddMissingDependencies(missingDeps)
885 }
886 depPaths.WholeStaticLibObjFiles =
887 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
888 case objDepTag:
889 depPtr = &depPaths.ObjFiles
890 case crtBeginDepTag:
891 depPaths.CrtBegin = c.outputFile
892 case crtEndDepTag:
893 depPaths.CrtEnd = c.outputFile
894 default:
895 panic(fmt.Errorf("unknown dependency tag: %s", ctx.OtherModuleDependencyTag(m)))
896 }
897
898 if depPtr != nil {
899 *depPtr = append(*depPtr, c.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -0800900 }
901 })
902
903 return depPaths
904}
905
906func (c *Module) InstallInData() bool {
907 if c.installer == nil {
908 return false
909 }
910 return c.installer.inData()
911}
912
913// Compiler
914
915type baseCompiler struct {
916 Properties BaseCompilerProperties
917}
918
919var _ compiler = (*baseCompiler)(nil)
920
921func (compiler *baseCompiler) props() []interface{} {
922 return []interface{}{&compiler.Properties}
923}
924
925func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
926func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps { return deps }
927
928// Create a Flags struct that collects the compile flags from global values,
929// per-target values, module type values, and per-module Blueprints properties
930func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
931 toolchain := ctx.toolchain()
932
933 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
934 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
935 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
936 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
937 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
938
Colin Cross28344522015-04-22 13:07:53 -0700939 // Include dir cflags
Colin Crossca860ac2016-01-04 14:34:37 -0800940 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
941 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -0700942 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -0700943 includeDirsToFlags(localIncludeDirs),
944 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -0700945
Colin Crossca860ac2016-01-04 14:34:37 -0800946 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
947 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -0700948
949 flags.GlobalFlags = append(flags.GlobalFlags,
950 includeFilesToFlags(rootIncludeFiles),
951 includeFilesToFlags(localIncludeFiles))
952
Colin Crossca860ac2016-01-04 14:34:37 -0800953 if !ctx.noDefaultCompilerFlags() {
954 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -0700955 flags.GlobalFlags = append(flags.GlobalFlags,
956 "${commonGlobalIncludes}",
957 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -0800958 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -0700959 }
960
961 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700962 "-I" + common.PathForModuleSrc(ctx).String(),
963 "-I" + common.PathForModuleOut(ctx).String(),
964 "-I" + common.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -0700965 }...)
966 }
967
Colin Crossca860ac2016-01-04 14:34:37 -0800968 instructionSet := compiler.Properties.Instruction_set
969 if flags.RequiredInstructionSet != "" {
970 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -0800971 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -0800972 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
973 if flags.Clang {
974 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
975 }
976 if err != nil {
977 ctx.ModuleErrorf("%s", err)
978 }
979
980 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -0800981 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -0800982
Colin Cross97ba0732015-03-23 17:50:24 -0700983 if flags.Clang {
984 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -0800985 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
986 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -0700987 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
988 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
989 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800990
991 target := "-target " + toolchain.ClangTriple()
992 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
993
Colin Cross97ba0732015-03-23 17:50:24 -0700994 flags.CFlags = append(flags.CFlags, target, gccPrefix)
995 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
996 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800997 }
998
Colin Crossca860ac2016-01-04 14:34:37 -0800999 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001000 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1001
Colin Cross97ba0732015-03-23 17:50:24 -07001002 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001003 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001004 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001005 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001006 toolchain.ClangCflags(),
1007 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001008 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001009
1010 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001011 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001012 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001013 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001014 toolchain.Cflags(),
1015 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001016 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001017 }
1018
Colin Cross7b66f152015-12-15 16:07:43 -08001019 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1020 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1021 }
1022
Colin Crossf6566ed2015-03-24 11:13:38 -07001023 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001024 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001025 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001026 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001027 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001028 }
1029 }
1030
Colin Cross97ba0732015-03-23 17:50:24 -07001031 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001032
Colin Cross97ba0732015-03-23 17:50:24 -07001033 if flags.Clang {
1034 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001035 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001036 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001037 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001038 }
1039
Colin Crossc4bde762015-11-23 16:11:30 -08001040 if flags.Clang {
1041 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1042 } else {
1043 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001044 }
1045
Colin Crossca860ac2016-01-04 14:34:37 -08001046 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001047 if ctx.Host() && !flags.Clang {
1048 // The host GCC doesn't support C++14 (and is deprecated, so likely
1049 // never will). Build these modules with C++11.
1050 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1051 } else {
1052 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1053 }
1054 }
1055
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001056 // We can enforce some rules more strictly in the code we own. strict
1057 // indicates if this is code that we can be stricter with. If we have
1058 // rules that we want to apply to *our* code (but maybe can't for
1059 // vendor/device specific things), we could extend this to be a ternary
1060 // value.
1061 strict := true
1062 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1063 strict = false
1064 }
1065
1066 // Can be used to make some annotations stricter for code we can fix
1067 // (such as when we mark functions as deprecated).
1068 if strict {
1069 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1070 }
1071
Colin Cross3f40fa42015-01-30 17:27:36 -08001072 return flags
1073}
1074
Colin Crossca860ac2016-01-04 14:34:37 -08001075func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1076 // Compile files listed in c.Properties.Srcs into objects
1077 objFiles := compiler.compileObjs(ctx, flags, "", compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
1078 if ctx.Failed() {
1079 return nil
1080 }
1081
1082 var genSrcs common.Paths
1083 ctx.VisitDirectDeps(func(module blueprint.Module) {
1084 if gen, ok := module.(genrule.SourceFileGenerator); ok {
1085 genSrcs = append(genSrcs, gen.GeneratedSourceFiles()...)
1086 }
1087 })
1088
1089 if len(genSrcs) != 0 {
1090 genObjs := TransformSourceToObj(ctx, "", genSrcs, flagsToBuilderFlags(flags), nil)
1091 objFiles = append(objFiles, genObjs...)
1092 }
1093
1094 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001095}
1096
1097// Compile a list of source files into objects a specified subdirectory
Colin Crossca860ac2016-01-04 14:34:37 -08001098func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001099 subdir string, srcFiles, excludes []string) common.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001100
Colin Crossca860ac2016-01-04 14:34:37 -08001101 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001102
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001103 inputFiles := ctx.ExpandSources(srcFiles, excludes)
1104 srcPaths, deps := genSources(ctx, inputFiles, buildFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001105
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001106 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001107}
1108
Colin Crossca860ac2016-01-04 14:34:37 -08001109// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1110type baseLinker struct {
1111 Properties BaseLinkerProperties
1112 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001113 VariantIsShared bool `blueprint:"mutated"`
1114 VariantIsStatic bool `blueprint:"mutated"`
1115 VariantIsStaticBinary bool `blueprint:"mutated"`
1116 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001117 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001118}
1119
Dan Willemsend30e6102016-03-30 17:35:50 -07001120func (linker *baseLinker) begin(ctx BaseModuleContext) {
1121 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001122 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001123 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001124 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001125 }
1126}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001127
Colin Crossca860ac2016-01-04 14:34:37 -08001128func (linker *baseLinker) props() []interface{} {
1129 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001130}
1131
Colin Crossca860ac2016-01-04 14:34:37 -08001132func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1133 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1134 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1135 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001136
Colin Cross74d1ec02015-04-28 13:30:13 -07001137 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001138 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001139 }
1140
Colin Crossf6566ed2015-03-24 11:13:38 -07001141 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001142 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001143 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1144 if !Bool(linker.Properties.No_libgcc) {
1145 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001146 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001147
Colin Crossca860ac2016-01-04 14:34:37 -08001148 if !linker.static() {
1149 if linker.Properties.System_shared_libs != nil {
1150 deps.LateSharedLibs = append(deps.LateSharedLibs,
1151 linker.Properties.System_shared_libs...)
1152 } else if !ctx.sdk() {
1153 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1154 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001155 }
Colin Cross577f6e42015-03-27 18:23:34 -07001156
Colin Crossca860ac2016-01-04 14:34:37 -08001157 if ctx.sdk() {
1158 version := ctx.sdkVersion()
1159 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001160 "ndk_libc."+version,
1161 "ndk_libm."+version,
1162 )
1163 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001164 }
1165
Colin Crossca860ac2016-01-04 14:34:37 -08001166 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001167}
1168
Colin Crossca860ac2016-01-04 14:34:37 -08001169func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1170 toolchain := ctx.toolchain()
1171
1172 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1173
1174 if !ctx.noDefaultCompilerFlags() {
1175 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1176 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1177 }
1178
1179 if flags.Clang {
1180 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1181 } else {
1182 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1183 }
1184
1185 if ctx.Host() {
1186 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1187 }
1188 }
1189
Dan Willemsend30e6102016-03-30 17:35:50 -07001190 if ctx.Host() && !linker.static() {
1191 rpath_prefix := `\$$ORIGIN/`
1192 if ctx.Darwin() {
1193 rpath_prefix = "@loader_path/"
1194 }
1195
Colin Crossc99deeb2016-04-11 15:06:20 -07001196 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001197 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1198 }
1199 }
1200
Dan Willemsene7174922016-03-30 17:33:52 -07001201 if flags.Clang {
1202 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1203 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001204 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1205 }
1206
1207 return flags
1208}
1209
1210func (linker *baseLinker) static() bool {
1211 return linker.dynamicProperties.VariantIsStatic
1212}
1213
1214func (linker *baseLinker) staticBinary() bool {
1215 return linker.dynamicProperties.VariantIsStaticBinary
1216}
1217
1218func (linker *baseLinker) setStatic(static bool) {
1219 linker.dynamicProperties.VariantIsStatic = static
1220}
1221
1222type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001223 // Returns true if the build options for the module have selected a static or shared build
1224 buildStatic() bool
1225 buildShared() bool
1226
1227 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001228 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001229
Colin Cross18b6dc52015-04-28 13:20:37 -07001230 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001231 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001232
1233 // Returns whether a module is a static binary
1234 staticBinary() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001235}
1236
Colin Crossca860ac2016-01-04 14:34:37 -08001237type exportedFlagsProducer interface {
Colin Cross28344522015-04-22 13:07:53 -07001238 exportedFlags() []string
Colin Cross3f40fa42015-01-30 17:27:36 -08001239}
1240
Colin Crossca860ac2016-01-04 14:34:37 -08001241type baseInstaller struct {
1242 Properties InstallerProperties
1243
1244 dir string
1245 dir64 string
1246 data bool
1247
Colin Crossa2344662016-03-24 13:14:12 -07001248 path common.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001249}
1250
1251var _ installer = (*baseInstaller)(nil)
1252
1253func (installer *baseInstaller) props() []interface{} {
1254 return []interface{}{&installer.Properties}
1255}
1256
1257func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1258 subDir := installer.dir
1259 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1260 subDir = installer.dir64
1261 }
1262 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1263 installer.path = ctx.InstallFile(dir, file)
1264}
1265
1266func (installer *baseInstaller) inData() bool {
1267 return installer.data
1268}
1269
Colin Cross3f40fa42015-01-30 17:27:36 -08001270//
1271// Combined static+shared libraries
1272//
1273
Colin Crossca860ac2016-01-04 14:34:37 -08001274type libraryCompiler struct {
1275 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001276
Colin Crossca860ac2016-01-04 14:34:37 -08001277 linker *libraryLinker
1278 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001279
Colin Crossca860ac2016-01-04 14:34:37 -08001280 // For reusing static library objects for shared library
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001281 reuseObjFiles common.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001282}
1283
Colin Crossca860ac2016-01-04 14:34:37 -08001284var _ compiler = (*libraryCompiler)(nil)
1285
1286func (library *libraryCompiler) props() []interface{} {
1287 props := library.baseCompiler.props()
1288 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001289}
1290
Colin Crossca860ac2016-01-04 14:34:37 -08001291func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1292 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001293
Dan Willemsen490fd492015-11-24 17:53:15 -08001294 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1295 // all code is position independent, and then those warnings get promoted to
1296 // errors.
1297 if ctx.HostType() != common.Windows {
1298 flags.CFlags = append(flags.CFlags, "-fPIC")
1299 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001300
Colin Crossca860ac2016-01-04 14:34:37 -08001301 if library.linker.static() {
1302 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001303 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001304 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001305 }
1306
Colin Crossca860ac2016-01-04 14:34:37 -08001307 return flags
1308}
1309
1310func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1311 var objFiles common.Paths
1312
Colin Crossc99deeb2016-04-11 15:06:20 -07001313 objFiles = library.baseCompiler.compile(ctx, flags)
1314 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001315
1316 if library.linker.static() {
1317 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
1318 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs)...)
1319 } else {
1320 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
1321 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs)...)
1322 }
1323
1324 return objFiles
1325}
1326
1327type libraryLinker struct {
1328 baseLinker
1329
1330 Properties LibraryLinkerProperties
1331
1332 dynamicProperties struct {
1333 BuildStatic bool `blueprint:"mutated"`
1334 BuildShared bool `blueprint:"mutated"`
1335 }
1336
1337 exportFlags []string
1338
1339 // If we're used as a whole_static_lib, our missing dependencies need
1340 // to be given
1341 wholeStaticMissingDeps []string
1342
1343 // For whole_static_libs
1344 objFiles common.Paths
1345}
1346
1347var _ linker = (*libraryLinker)(nil)
1348var _ exportedFlagsProducer = (*libraryLinker)(nil)
1349
1350func (library *libraryLinker) props() []interface{} {
1351 props := library.baseLinker.props()
1352 return append(props, &library.Properties, &library.dynamicProperties)
1353}
1354
1355func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1356 flags = library.baseLinker.flags(ctx, flags)
1357
1358 flags.Nocrt = Bool(library.Properties.Nocrt)
1359
1360 if !library.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001361 libName := ctx.ModuleName()
1362 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1363 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001364 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001365 sharedFlag = "-shared"
1366 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001367 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001368 flags.LdFlags = append(flags.LdFlags,
1369 "-nostdlib",
1370 "-Wl,--gc-sections",
1371 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001372 }
Colin Cross97ba0732015-03-23 17:50:24 -07001373
Colin Cross0af4b842015-04-30 16:36:18 -07001374 if ctx.Darwin() {
1375 flags.LdFlags = append(flags.LdFlags,
1376 "-dynamiclib",
1377 "-single_module",
1378 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001379 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001380 )
1381 } else {
1382 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001383 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001384 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001385 )
1386 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001387 }
Colin Cross97ba0732015-03-23 17:50:24 -07001388
1389 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001390}
1391
Colin Crossca860ac2016-01-04 14:34:37 -08001392func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1393 deps = library.baseLinker.deps(ctx, deps)
1394 if library.static() {
1395 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1396 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1397 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1398 } else {
1399 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1400 if !ctx.sdk() {
1401 deps.CrtBegin = "crtbegin_so"
1402 deps.CrtEnd = "crtend_so"
1403 } else {
1404 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1405 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1406 }
1407 }
1408 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1409 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1410 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1411 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001412
Colin Crossca860ac2016-01-04 14:34:37 -08001413 return deps
1414}
Colin Cross3f40fa42015-01-30 17:27:36 -08001415
Colin Crossca860ac2016-01-04 14:34:37 -08001416func (library *libraryLinker) exportedFlags() []string {
1417 return library.exportFlags
1418}
1419
1420func (library *libraryLinker) linkStatic(ctx ModuleContext,
1421 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1422
Colin Cross21b9a242015-03-24 14:15:58 -07001423 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Crossca860ac2016-01-04 14:34:37 -08001424 library.objFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001425
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001426 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001427
Colin Cross0af4b842015-04-30 16:36:18 -07001428 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001429 TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001430 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001431 TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001432 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001433
Colin Crossca860ac2016-01-04 14:34:37 -08001434 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001435
1436 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001437
1438 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001439}
1440
Colin Crossca860ac2016-01-04 14:34:37 -08001441func (library *libraryLinker) linkShared(ctx ModuleContext,
1442 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001443
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001444 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
Colin Cross3f40fa42015-01-30 17:27:36 -08001445
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001446 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001447
Colin Crossca860ac2016-01-04 14:34:37 -08001448 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1449 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1450 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1451 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001452 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001453 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001454 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001455 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001456 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001457 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001458 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1459 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001460 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001461 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1462 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001463 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001464 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1465 }
1466 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001467 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001468 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1469 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001470 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001471 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001472 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001473 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001474 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001475 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001476 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001477 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001478 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001479 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001480 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001481 }
Colin Crossaee540a2015-07-06 17:48:31 -07001482 }
1483
Colin Crossca860ac2016-01-04 14:34:37 -08001484 sharedLibs := deps.SharedLibs
1485 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001486
Colin Crossca860ac2016-01-04 14:34:37 -08001487 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1488 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1489 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile)
1490
1491 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001492}
1493
Colin Crossca860ac2016-01-04 14:34:37 -08001494func (library *libraryLinker) link(ctx ModuleContext,
1495 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001496
Colin Crossc99deeb2016-04-11 15:06:20 -07001497 objFiles = append(objFiles, deps.ObjFiles...)
1498
Colin Crossca860ac2016-01-04 14:34:37 -08001499 var out common.Path
1500 if library.static() {
1501 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001502 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001503 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001504 }
1505
Colin Crossca860ac2016-01-04 14:34:37 -08001506 includeDirs := common.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)
1507 library.exportFlags = []string{includeDirsToFlags(includeDirs)}
1508 library.exportFlags = append(library.exportFlags, deps.ReexportedCflags...)
1509
1510 return out
1511}
1512
1513func (library *libraryLinker) buildStatic() bool {
1514 return library.dynamicProperties.BuildStatic
1515}
1516
1517func (library *libraryLinker) buildShared() bool {
1518 return library.dynamicProperties.BuildShared
1519}
1520
1521func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1522 return library.wholeStaticMissingDeps
1523}
1524
Colin Crossc99deeb2016-04-11 15:06:20 -07001525func (library *libraryLinker) installable() bool {
1526 return !library.static()
1527}
1528
Colin Crossca860ac2016-01-04 14:34:37 -08001529type libraryInstaller struct {
1530 baseInstaller
1531
1532 linker *libraryLinker
1533}
1534
1535func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1536 if !library.linker.static() {
1537 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001538 }
1539}
1540
Colin Crossca860ac2016-01-04 14:34:37 -08001541func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1542 module := newModule(hod, common.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001543
Colin Crossca860ac2016-01-04 14:34:37 -08001544 linker := &libraryLinker{}
1545 linker.dynamicProperties.BuildShared = shared
1546 linker.dynamicProperties.BuildStatic = static
1547 module.linker = linker
1548
1549 module.compiler = &libraryCompiler{
1550 linker: linker,
1551 }
1552 module.installer = &libraryInstaller{
1553 baseInstaller: baseInstaller{
1554 dir: "lib",
1555 dir64: "lib64",
1556 },
1557 linker: linker,
Dan Albertc403f7c2015-03-18 14:01:18 -07001558 }
1559
Colin Crossca860ac2016-01-04 14:34:37 -08001560 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001561}
1562
Colin Crossca860ac2016-01-04 14:34:37 -08001563func libraryFactory() (blueprint.Module, []interface{}) {
1564 module := NewLibrary(common.HostAndDeviceSupported, true, true)
1565 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001566}
1567
Colin Cross3f40fa42015-01-30 17:27:36 -08001568//
1569// Objects (for crt*.o)
1570//
1571
Colin Crossca860ac2016-01-04 14:34:37 -08001572type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001573 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001574}
1575
Colin Crossca860ac2016-01-04 14:34:37 -08001576func objectFactory() (blueprint.Module, []interface{}) {
1577 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1578 module.compiler = &baseCompiler{}
1579 module.linker = &objectLinker{}
1580 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001581}
1582
Colin Cross81413472016-04-11 14:37:39 -07001583func (object *objectLinker) props() []interface{} {
1584 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001585}
1586
Colin Crossca860ac2016-01-04 14:34:37 -08001587func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001588
Colin Cross81413472016-04-11 14:37:39 -07001589func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1590 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001591 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001592}
1593
Colin Crossca860ac2016-01-04 14:34:37 -08001594func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001595 if flags.Clang {
1596 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1597 } else {
1598 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1599 }
1600
Colin Crossca860ac2016-01-04 14:34:37 -08001601 return flags
1602}
1603
1604func (object *objectLinker) link(ctx ModuleContext,
1605 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001606
Colin Cross97ba0732015-03-23 17:50:24 -07001607 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001608
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001609 var outputFile common.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001610 if len(objFiles) == 1 {
1611 outputFile = objFiles[0]
1612 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001613 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001614 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001615 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001616 }
1617
Colin Cross3f40fa42015-01-30 17:27:36 -08001618 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001619 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001620}
1621
Colin Crossc99deeb2016-04-11 15:06:20 -07001622func (*objectLinker) installable() bool {
1623 return false
1624}
1625
Colin Cross3f40fa42015-01-30 17:27:36 -08001626//
1627// Executables
1628//
1629
Colin Crossca860ac2016-01-04 14:34:37 -08001630type binaryLinker struct {
1631 baseLinker
Colin Cross7d5136f2015-05-11 13:39:40 -07001632
Colin Crossca860ac2016-01-04 14:34:37 -08001633 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001634
Colin Crossca860ac2016-01-04 14:34:37 -08001635 hostToolPath common.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001636}
1637
Colin Crossca860ac2016-01-04 14:34:37 -08001638var _ linker = (*binaryLinker)(nil)
1639
1640func (binary *binaryLinker) props() []interface{} {
1641 return append(binary.baseLinker.props(), &binary.Properties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001642}
1643
Colin Crossca860ac2016-01-04 14:34:37 -08001644func (binary *binaryLinker) buildStatic() bool {
1645 return Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001646}
1647
Colin Crossca860ac2016-01-04 14:34:37 -08001648func (binary *binaryLinker) buildShared() bool {
1649 return !Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001650}
1651
Colin Crossca860ac2016-01-04 14:34:37 -08001652func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001653 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001654 if binary.Properties.Stem != "" {
1655 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001656 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001657
Colin Crossca860ac2016-01-04 14:34:37 -08001658 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001659}
1660
Colin Crossca860ac2016-01-04 14:34:37 -08001661func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1662 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001663 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001664 if !ctx.sdk() {
1665 if Bool(binary.Properties.Static_executable) {
1666 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001667 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001668 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001669 }
Colin Crossca860ac2016-01-04 14:34:37 -08001670 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001671 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001672 if Bool(binary.Properties.Static_executable) {
1673 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001674 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001675 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001676 }
Colin Crossca860ac2016-01-04 14:34:37 -08001677 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001678 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001679
Colin Crossca860ac2016-01-04 14:34:37 -08001680 if Bool(binary.Properties.Static_executable) {
1681 if inList("libc++_static", deps.StaticLibs) {
1682 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001683 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001684 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1685 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1686 // move them to the beginning of deps.LateStaticLibs
1687 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001688 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001689 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001690 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001691 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001692 }
Colin Crossca860ac2016-01-04 14:34:37 -08001693
1694 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1695 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1696 "from static libs or set static_executable: true")
1697 }
1698 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001699}
1700
Colin Crossc99deeb2016-04-11 15:06:20 -07001701func (*binaryLinker) installable() bool {
1702 return true
1703}
1704
Colin Crossca860ac2016-01-04 14:34:37 -08001705func NewBinary(hod common.HostOrDeviceSupported) *Module {
1706 module := newModule(hod, common.MultilibFirst)
1707 module.compiler = &baseCompiler{}
1708 module.linker = &binaryLinker{}
1709 module.installer = &baseInstaller{
1710 dir: "bin",
1711 }
1712 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001713}
1714
Colin Crossca860ac2016-01-04 14:34:37 -08001715func binaryFactory() (blueprint.Module, []interface{}) {
1716 module := NewBinary(common.HostAndDeviceSupported)
1717 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001718}
1719
Colin Crossca860ac2016-01-04 14:34:37 -08001720func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001721 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001722 binary.Properties.Static_executable = proptools.BoolPtr(false)
Colin Cross0af4b842015-04-30 16:36:18 -07001723 }
Colin Crossca860ac2016-01-04 14:34:37 -08001724 if Bool(binary.Properties.Static_executable) {
1725 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001726 }
1727}
1728
Colin Crossca860ac2016-01-04 14:34:37 -08001729func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1730 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001731
Dan Willemsen490fd492015-11-24 17:53:15 -08001732 if ctx.Host() {
1733 flags.LdFlags = append(flags.LdFlags, "-pie")
1734 if ctx.HostType() == common.Windows {
1735 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1736 }
1737 }
1738
1739 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1740 // all code is position independent, and then those warnings get promoted to
1741 // errors.
1742 if ctx.HostType() != common.Windows {
1743 flags.CFlags = append(flags.CFlags, "-fpie")
1744 }
Colin Cross97ba0732015-03-23 17:50:24 -07001745
Colin Crossf6566ed2015-03-24 11:13:38 -07001746 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001747 if Bool(binary.Properties.Static_executable) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001748 // Clang driver needs -static to create static executable.
1749 // However, bionic/linker uses -shared to overwrite.
1750 // Linker for x86 targets does not allow coexistance of -static and -shared,
1751 // so we add -static only if -shared is not used.
1752 if !inList("-shared", flags.LdFlags) {
1753 flags.LdFlags = append(flags.LdFlags, "-static")
1754 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001755
Colin Crossed4cf0b2015-03-26 14:43:45 -07001756 flags.LdFlags = append(flags.LdFlags,
1757 "-nostdlib",
1758 "-Bstatic",
1759 "-Wl,--gc-sections",
1760 )
1761
1762 } else {
1763 linker := "/system/bin/linker"
1764 if flags.Toolchain.Is64Bit() {
Colin Crossca860ac2016-01-04 14:34:37 -08001765 linker += "64"
Colin Crossed4cf0b2015-03-26 14:43:45 -07001766 }
1767
1768 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001769 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001770 "-nostdlib",
1771 "-Bdynamic",
1772 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1773 "-Wl,--gc-sections",
1774 "-Wl,-z,nocopyreloc",
1775 )
1776 }
Colin Cross0af4b842015-04-30 16:36:18 -07001777 } else if ctx.Darwin() {
1778 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001779 }
1780
Colin Cross97ba0732015-03-23 17:50:24 -07001781 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001782}
1783
Colin Crossca860ac2016-01-04 14:34:37 -08001784func (binary *binaryLinker) link(ctx ModuleContext,
1785 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001786
Colin Crossca860ac2016-01-04 14:34:37 -08001787 outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
1788 if ctx.HostOrDevice().Host() {
1789 binary.hostToolPath = common.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001790 }
Colin Crossca860ac2016-01-04 14:34:37 -08001791 ret := outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001792
Colin Crossca860ac2016-01-04 14:34:37 -08001793 if binary.Properties.Prefix_symbols != "" {
Colin Crossbfae8852015-03-26 14:44:11 -07001794 afterPrefixSymbols := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001795 outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate")
1796 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1797 flagsToBuilderFlags(flags), afterPrefixSymbols)
Colin Crossbfae8852015-03-26 14:44:11 -07001798 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001799
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001800 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001801
Colin Crossca860ac2016-01-04 14:34:37 -08001802 sharedLibs := deps.SharedLibs
1803 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1804
1805 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001806 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Crossca860ac2016-01-04 14:34:37 -08001807 flagsToBuilderFlags(flags), outputFile)
1808
1809 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001810}
Colin Cross3f40fa42015-01-30 17:27:36 -08001811
Colin Crossca860ac2016-01-04 14:34:37 -08001812func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1813 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001814}
1815
Colin Cross6362e272015-10-29 15:25:03 -07001816func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08001817 if m, ok := mctx.Module().(*Module); ok {
1818 if test, ok := m.linker.(*testLinker); ok {
1819 if Bool(test.Properties.Test_per_src) {
1820 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
1821 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1822 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
1823 }
1824 tests := mctx.CreateLocalVariations(testNames...)
1825 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1826 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
1827 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
1828 }
Colin Cross6002e052015-09-16 16:00:08 -07001829 }
1830 }
1831 }
Colin Cross7d5136f2015-05-11 13:39:40 -07001832}
1833
Colin Crossca860ac2016-01-04 14:34:37 -08001834type testLinker struct {
1835 binaryLinker
1836 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001837}
1838
Dan Willemsend30e6102016-03-30 17:35:50 -07001839func (test *testLinker) begin(ctx BaseModuleContext) {
1840 test.binaryLinker.begin(ctx)
1841
1842 runpath := "../../lib"
1843 if ctx.toolchain().Is64Bit() {
1844 runpath += "64"
1845 }
Colin Crossc99deeb2016-04-11 15:06:20 -07001846 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
Dan Willemsend30e6102016-03-30 17:35:50 -07001847}
1848
Colin Crossca860ac2016-01-04 14:34:37 -08001849func (test *testLinker) props() []interface{} {
1850 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07001851}
1852
Colin Crossca860ac2016-01-04 14:34:37 -08001853func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
1854 flags = test.binaryLinker.flags(ctx, flags)
1855
1856 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001857 return flags
1858 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001859
Colin Cross97ba0732015-03-23 17:50:24 -07001860 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001861 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001862 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001863
1864 if ctx.HostType() == common.Windows {
1865 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
1866 } else {
1867 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
1868 flags.LdFlags = append(flags.LdFlags, "-lpthread")
1869 }
1870 } else {
1871 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07001872 }
1873
1874 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross28344522015-04-22 13:07:53 -07001875 flags.CFlags = append(flags.CFlags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001876 "-I"+common.PathForSource(ctx, "external/gtest/include").String())
Dan Albertc403f7c2015-03-18 14:01:18 -07001877
Colin Cross21b9a242015-03-24 14:15:58 -07001878 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07001879}
1880
Colin Crossca860ac2016-01-04 14:34:37 -08001881func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1882 if test.Properties.Gtest {
1883 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001884 }
Colin Crossca860ac2016-01-04 14:34:37 -08001885 deps = test.binaryLinker.deps(ctx, deps)
1886 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07001887}
1888
Colin Crossca860ac2016-01-04 14:34:37 -08001889type testInstaller struct {
1890 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08001891}
1892
Colin Crossca860ac2016-01-04 14:34:37 -08001893func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
1894 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
1895 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
1896 installer.baseInstaller.install(ctx, file)
1897}
1898
1899func NewTest(hod common.HostOrDeviceSupported) *Module {
1900 module := newModule(hod, common.MultilibBoth)
1901 module.compiler = &baseCompiler{}
1902 linker := &testLinker{}
1903 linker.Properties.Gtest = true
1904 module.linker = linker
1905 module.installer = &testInstaller{
1906 baseInstaller: baseInstaller{
1907 dir: "nativetest",
1908 dir64: "nativetest64",
1909 data: true,
1910 },
Dan Albertc403f7c2015-03-18 14:01:18 -07001911 }
Colin Crossca860ac2016-01-04 14:34:37 -08001912 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001913}
1914
Colin Crossca860ac2016-01-04 14:34:37 -08001915func testFactory() (blueprint.Module, []interface{}) {
1916 module := NewTest(common.HostAndDeviceSupported)
1917 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001918}
1919
Colin Crossca860ac2016-01-04 14:34:37 -08001920type benchmarkLinker struct {
1921 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07001922}
1923
Colin Crossca860ac2016-01-04 14:34:37 -08001924func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1925 deps = benchmark.binaryLinker.deps(ctx, deps)
1926 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
1927 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07001928}
1929
Colin Crossca860ac2016-01-04 14:34:37 -08001930func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
1931 module := newModule(hod, common.MultilibFirst)
1932 module.compiler = &baseCompiler{}
1933 module.linker = &benchmarkLinker{}
1934 module.installer = &baseInstaller{
1935 dir: "nativetest",
1936 dir64: "nativetest64",
1937 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07001938 }
Colin Crossca860ac2016-01-04 14:34:37 -08001939 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07001940}
1941
Colin Crossca860ac2016-01-04 14:34:37 -08001942func benchmarkFactory() (blueprint.Module, []interface{}) {
1943 module := NewBenchmark(common.HostAndDeviceSupported)
1944 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07001945}
1946
Colin Cross3f40fa42015-01-30 17:27:36 -08001947//
1948// Static library
1949//
1950
Colin Crossca860ac2016-01-04 14:34:37 -08001951func libraryStaticFactory() (blueprint.Module, []interface{}) {
1952 module := NewLibrary(common.HostAndDeviceSupported, false, true)
1953 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001954}
1955
1956//
1957// Shared libraries
1958//
1959
Colin Crossca860ac2016-01-04 14:34:37 -08001960func librarySharedFactory() (blueprint.Module, []interface{}) {
1961 module := NewLibrary(common.HostAndDeviceSupported, true, false)
1962 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001963}
1964
1965//
1966// Host static library
1967//
1968
Colin Crossca860ac2016-01-04 14:34:37 -08001969func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
1970 module := NewLibrary(common.HostSupported, false, true)
1971 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001972}
1973
1974//
1975// Host Shared libraries
1976//
1977
Colin Crossca860ac2016-01-04 14:34:37 -08001978func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
1979 module := NewLibrary(common.HostSupported, true, false)
1980 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001981}
1982
1983//
1984// Host Binaries
1985//
1986
Colin Crossca860ac2016-01-04 14:34:37 -08001987func binaryHostFactory() (blueprint.Module, []interface{}) {
1988 module := NewBinary(common.HostSupported)
1989 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001990}
1991
1992//
Colin Cross1f8f2342015-03-26 16:09:47 -07001993// Host Tests
1994//
1995
Colin Crossca860ac2016-01-04 14:34:37 -08001996func testHostFactory() (blueprint.Module, []interface{}) {
1997 module := NewTest(common.HostSupported)
1998 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07001999}
2000
2001//
Colin Cross2ba19d92015-05-07 15:44:20 -07002002// Host Benchmarks
2003//
2004
Colin Crossca860ac2016-01-04 14:34:37 -08002005func benchmarkHostFactory() (blueprint.Module, []interface{}) {
2006 module := NewBenchmark(common.HostSupported)
2007 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002008}
2009
2010//
Colin Crosscfad1192015-11-02 16:43:11 -08002011// Defaults
2012//
Colin Crossca860ac2016-01-04 14:34:37 -08002013type Defaults struct {
Colin Crosscfad1192015-11-02 16:43:11 -08002014 common.AndroidModuleBase
2015 common.DefaultsModule
2016}
2017
Colin Crossca860ac2016-01-04 14:34:37 -08002018func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002019}
2020
Colin Crossca860ac2016-01-04 14:34:37 -08002021func defaultsFactory() (blueprint.Module, []interface{}) {
2022 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002023
2024 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002025 &BaseProperties{},
2026 &BaseCompilerProperties{},
2027 &BaseLinkerProperties{},
2028 &LibraryCompilerProperties{},
2029 &LibraryLinkerProperties{},
2030 &BinaryLinkerProperties{},
2031 &TestLinkerProperties{},
2032 &UnusedProperties{},
2033 &StlProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002034 }
2035
Dan Willemsen218f6562015-07-08 18:13:11 -07002036 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
2037 common.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002038
2039 return common.InitDefaultsModule(module, module, propertyStructs...)
2040}
2041
2042//
Colin Cross3f40fa42015-01-30 17:27:36 -08002043// Device libraries shipped with gcc
2044//
2045
Colin Crossca860ac2016-01-04 14:34:37 -08002046type toolchainLibraryLinker struct {
2047 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002048}
2049
Colin Crossca860ac2016-01-04 14:34:37 -08002050var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2051
2052func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002053 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002054 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002055}
2056
Colin Crossca860ac2016-01-04 14:34:37 -08002057func (*toolchainLibraryLinker) buildStatic() bool {
2058 return true
2059}
Colin Cross3f40fa42015-01-30 17:27:36 -08002060
Colin Crossca860ac2016-01-04 14:34:37 -08002061func (*toolchainLibraryLinker) buildShared() bool {
2062 return false
2063}
2064
2065func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
2066 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2067 module.compiler = &baseCompiler{}
2068 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002069 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002070 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002071}
2072
Colin Crossca860ac2016-01-04 14:34:37 -08002073func (library *toolchainLibraryLinker) link(ctx ModuleContext,
2074 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002075
2076 libName := ctx.ModuleName() + staticLibraryExtension
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002077 outputFile := common.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002078
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002079 if flags.Clang {
2080 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2081 }
2082
Colin Crossca860ac2016-01-04 14:34:37 -08002083 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002084
2085 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002086
Colin Crossca860ac2016-01-04 14:34:37 -08002087 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002088}
2089
Colin Crossc99deeb2016-04-11 15:06:20 -07002090func (*toolchainLibraryLinker) installable() bool {
2091 return false
2092}
2093
Dan Albertbe961682015-03-18 23:38:50 -07002094// NDK prebuilt libraries.
2095//
2096// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2097// either (with the exception of the shared STLs, which are installed to the app's directory rather
2098// than to the system image).
2099
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002100func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2101 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2102 version, toolchain.Name()))
Dan Albertbe961682015-03-18 23:38:50 -07002103}
2104
Dan Albertc3144b12015-04-28 18:17:56 -07002105func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002106 ext string, version string) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002107
2108 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2109 // We want to translate to just NAME.EXT
2110 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2111 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002112 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002113}
2114
Colin Crossca860ac2016-01-04 14:34:37 -08002115type ndkPrebuiltObjectLinker struct {
2116 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002117}
2118
Colin Crossca860ac2016-01-04 14:34:37 -08002119func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002120 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002121 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002122}
2123
Colin Crossca860ac2016-01-04 14:34:37 -08002124func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2125 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2126 module.linker = &ndkPrebuiltObjectLinker{}
2127 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002128}
2129
Colin Crossca860ac2016-01-04 14:34:37 -08002130func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2131 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002132 // A null build step, but it sets up the output path.
2133 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2134 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2135 }
2136
Colin Crossca860ac2016-01-04 14:34:37 -08002137 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002138}
2139
Colin Crossca860ac2016-01-04 14:34:37 -08002140type ndkPrebuiltLibraryLinker struct {
2141 libraryLinker
2142 Properties struct {
2143 Export_include_dirs []string `android:"arch_variant"`
2144 }
Dan Albertc3144b12015-04-28 18:17:56 -07002145}
2146
Colin Crossca860ac2016-01-04 14:34:37 -08002147var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2148var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002149
Colin Crossca860ac2016-01-04 14:34:37 -08002150func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Crossc99deeb2016-04-11 15:06:20 -07002151 return append(ndk.libraryLinker.props(), &ndk.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002152}
2153
Colin Crossca860ac2016-01-04 14:34:37 -08002154func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002155 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002156 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002157}
2158
Colin Crossca860ac2016-01-04 14:34:37 -08002159func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2160 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2161 linker := &ndkPrebuiltLibraryLinker{}
2162 linker.dynamicProperties.BuildShared = true
2163 module.linker = linker
2164 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002165}
2166
Colin Crossca860ac2016-01-04 14:34:37 -08002167func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2168 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002169 // A null build step, but it sets up the output path.
2170 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2171 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2172 }
2173
Colin Crossca860ac2016-01-04 14:34:37 -08002174 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2175 ndk.exportFlags = []string{common.JoinWithPrefix(includeDirs.Strings(), "-isystem ")}
Dan Albertbe961682015-03-18 23:38:50 -07002176
Colin Crossca860ac2016-01-04 14:34:37 -08002177 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2178 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002179}
2180
2181// The NDK STLs are slightly different from the prebuilt system libraries:
2182// * Are not specific to each platform version.
2183// * The libraries are not in a predictable location for each STL.
2184
Colin Crossca860ac2016-01-04 14:34:37 -08002185type ndkPrebuiltStlLinker struct {
2186 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002187}
2188
Colin Crossca860ac2016-01-04 14:34:37 -08002189func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2190 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2191 linker := &ndkPrebuiltStlLinker{}
2192 linker.dynamicProperties.BuildShared = true
2193 module.linker = linker
2194 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002195}
2196
Colin Crossca860ac2016-01-04 14:34:37 -08002197func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2198 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2199 linker := &ndkPrebuiltStlLinker{}
2200 linker.dynamicProperties.BuildStatic = true
2201 module.linker = linker
2202 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002203}
2204
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002205func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002206 gccVersion := toolchain.GccVersion()
2207 var libDir string
2208 switch stl {
2209 case "libstlport":
2210 libDir = "cxx-stl/stlport/libs"
2211 case "libc++":
2212 libDir = "cxx-stl/llvm-libc++/libs"
2213 case "libgnustl":
2214 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2215 }
2216
2217 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002218 ndkSrcRoot := "prebuilts/ndk/current/sources"
2219 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002220 }
2221
2222 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002223 return common.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002224}
2225
Colin Crossca860ac2016-01-04 14:34:37 -08002226func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2227 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002228 // A null build step, but it sets up the output path.
2229 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2230 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2231 }
2232
Colin Crossca860ac2016-01-04 14:34:37 -08002233 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2234 ndk.exportFlags = []string{includeDirsToFlags(includeDirs)}
Dan Albertbe961682015-03-18 23:38:50 -07002235
2236 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002237 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002238 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002239 libExt = staticLibraryExtension
2240 }
2241
2242 stlName := strings.TrimSuffix(libName, "_shared")
2243 stlName = strings.TrimSuffix(stlName, "_static")
2244 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002245 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002246}
2247
Colin Cross6362e272015-10-29 15:25:03 -07002248func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002249 if m, ok := mctx.Module().(*Module); ok {
2250 if m.linker != nil {
2251 if linker, ok := m.linker.(baseLinkerInterface); ok {
2252 var modules []blueprint.Module
2253 if linker.buildStatic() && linker.buildShared() {
2254 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002255 static := modules[0].(*Module)
2256 shared := modules[1].(*Module)
2257
2258 static.linker.(baseLinkerInterface).setStatic(true)
2259 shared.linker.(baseLinkerInterface).setStatic(false)
2260
2261 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2262 sharedCompiler := shared.compiler.(*libraryCompiler)
2263 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2264 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2265 // Optimize out compiling common .o files twice for static+shared libraries
2266 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2267 sharedCompiler.baseCompiler.Properties.Srcs = nil
2268 }
2269 }
Colin Crossca860ac2016-01-04 14:34:37 -08002270 } else if linker.buildStatic() {
2271 modules = mctx.CreateLocalVariations("static")
2272 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2273 } else if linker.buildShared() {
2274 modules = mctx.CreateLocalVariations("shared")
2275 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2276 } else {
2277 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2278 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002279 }
2280 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002281 }
2282}
Colin Cross74d1ec02015-04-28 13:30:13 -07002283
2284// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2285// modifies the slice contents in place, and returns a subslice of the original slice
2286func lastUniqueElements(list []string) []string {
2287 totalSkip := 0
2288 for i := len(list) - 1; i >= totalSkip; i-- {
2289 skip := 0
2290 for j := i - 1; j >= totalSkip; j-- {
2291 if list[i] == list[j] {
2292 skip++
2293 } else {
2294 list[j+skip] = list[j]
2295 }
2296 }
2297 totalSkip += skip
2298 }
2299 return list[totalSkip:]
2300}
Colin Cross06a931b2015-10-28 17:23:31 -07002301
2302var Bool = proptools.Bool