blob: ec26f7435e89b84b868c10462a552be354325598 [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")
68 LibmRoot = pctx.SourcePathVariable("LibmRoot", "bionic/libm")
Colin Cross3f40fa42015-01-30 17:27:36 -080069)
70
71// Flags used by lots of devices. Putting them in package static variables will save bytes in
72// build.ninja so they aren't repeated for every file
73var (
74 commonGlobalCflags = []string{
75 "-DANDROID",
76 "-fmessage-length=0",
77 "-W",
78 "-Wall",
79 "-Wno-unused",
80 "-Winit-self",
81 "-Wpointer-arith",
Dan Willemsene6540452015-10-20 15:21:33 -070082 "-fdebug-prefix-map=/proc/self/cwd=",
Colin Cross3f40fa42015-01-30 17:27:36 -080083
84 // COMMON_RELEASE_CFLAGS
85 "-DNDEBUG",
86 "-UDEBUG",
87 }
88
89 deviceGlobalCflags = []string{
Dan Willemsen490fd492015-11-24 17:53:15 -080090 "-fdiagnostics-color",
91
Colin Cross3f40fa42015-01-30 17:27:36 -080092 // TARGET_ERROR_FLAGS
93 "-Werror=return-type",
94 "-Werror=non-virtual-dtor",
95 "-Werror=address",
96 "-Werror=sequence-point",
Dan Willemsena6084a32016-03-01 15:16:50 -080097 "-Werror=date-time",
Colin Cross3f40fa42015-01-30 17:27:36 -080098 }
99
100 hostGlobalCflags = []string{}
101
102 commonGlobalCppflags = []string{
103 "-Wsign-promo",
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700104 }
105
Dan Willemsenbe03f342016-03-03 17:21:04 -0800106 noOverrideGlobalCflags = []string{
107 "-Werror=int-to-pointer-cast",
108 "-Werror=pointer-to-int-cast",
109 }
110
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700111 illegalFlags = []string{
112 "-w",
Colin Cross3f40fa42015-01-30 17:27:36 -0800113 }
114)
115
116func init() {
117 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
118 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
119 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800120 pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800121
122 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
123
124 pctx.StaticVariable("commonClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800125 strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800126 pctx.StaticVariable("deviceClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800127 strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800128 pctx.StaticVariable("hostClangGlobalCflags",
129 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800130 pctx.StaticVariable("noOverrideClangGlobalCflags",
131 strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
132
Tim Kilbournf2948142015-03-11 12:03:03 -0700133 pctx.StaticVariable("commonClangGlobalCppflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800134 strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800135
136 // Everything in this list is a crime against abstraction and dependency tracking.
137 // Do not add anything to this list.
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800138 pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700139 []string{
140 "system/core/include",
Dan Willemsen98f93c72016-03-01 15:27:03 -0800141 "system/media/audio/include",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700142 "hardware/libhardware/include",
143 "hardware/libhardware_legacy/include",
144 "hardware/ril/include",
145 "libnativehelper/include",
146 "frameworks/native/include",
147 "frameworks/native/opengl/include",
148 "frameworks/av/include",
149 "frameworks/base/include",
150 })
Dan Willemsene0378dd2016-01-07 17:42:34 -0800151 // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
152 // with this, since there is no associated library.
153 pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
154 []string{"libnativehelper/include/nativehelper"})
Colin Cross3f40fa42015-01-30 17:27:36 -0800155
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700156 pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
157 pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
158 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
159 return override, nil
160 }
161 return "${clangDefaultBase}", nil
162 })
163 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
164 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
165 return override, nil
166 }
Colin Cross7253e0b2016-03-21 15:12:34 -0700167 return "clang-2690385", nil
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700168 })
169 pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}/bin")
Colin Cross3f40fa42015-01-30 17:27:36 -0800170}
171
Colin Crossca860ac2016-01-04 14:34:37 -0800172type Deps struct {
173 SharedLibs, LateSharedLibs []string
174 StaticLibs, LateStaticLibs, WholeStaticLibs []string
Colin Crossc472d572015-03-17 15:06:21 -0700175
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700176 ObjFiles common.Paths
177
178 Cflags, ReexportedCflags []string
Colin Cross21b9a242015-03-24 14:15:58 -0700179
Colin Cross97ba0732015-03-23 17:50:24 -0700180 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700181}
182
Colin Crossca860ac2016-01-04 14:34:37 -0800183type PathDeps struct {
184 SharedLibs, LateSharedLibs common.Paths
185 StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700186
187 ObjFiles common.Paths
188 WholeStaticLibObjFiles common.Paths
189
190 Cflags, ReexportedCflags []string
191
192 CrtBegin, CrtEnd common.OptionalPath
193}
194
Colin Crossca860ac2016-01-04 14:34:37 -0800195type Flags struct {
Colin Cross28344522015-04-22 13:07:53 -0700196 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
197 AsFlags []string // Flags that apply to assembly source files
198 CFlags []string // Flags that apply to C and C++ source files
199 ConlyFlags []string // Flags that apply to C source files
200 CppFlags []string // Flags that apply to C++ source files
201 YaccFlags []string // Flags that apply to Yacc source files
202 LdFlags []string // Flags that apply to linker command lines
203
204 Nocrt bool
205 Toolchain Toolchain
206 Clang bool
Colin Crossca860ac2016-01-04 14:34:37 -0800207
208 RequiredInstructionSet string
Colin Crossc472d572015-03-17 15:06:21 -0700209}
210
Colin Crossca860ac2016-01-04 14:34:37 -0800211type BaseCompilerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700212 // 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 -0700213 Srcs []string `android:"arch_variant"`
214
215 // list of source files that should not be used to build the C/C++ module.
216 // This is most useful in the arch/multilib variants to remove non-common files
217 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700218
219 // list of module-specific flags that will be used for C and C++ compiles.
220 Cflags []string `android:"arch_variant"`
221
222 // list of module-specific flags that will be used for C++ compiles
223 Cppflags []string `android:"arch_variant"`
224
225 // list of module-specific flags that will be used for C compiles
226 Conlyflags []string `android:"arch_variant"`
227
228 // list of module-specific flags that will be used for .S compiles
229 Asflags []string `android:"arch_variant"`
230
Colin Crossca860ac2016-01-04 14:34:37 -0800231 // list of module-specific flags that will be used for C and C++ compiles when
232 // compiling with clang
233 Clang_cflags []string `android:"arch_variant"`
234
235 // list of module-specific flags that will be used for .S compiles when
236 // compiling with clang
237 Clang_asflags []string `android:"arch_variant"`
238
Colin Cross7d5136f2015-05-11 13:39:40 -0700239 // list of module-specific flags that will be used for .y and .yy compiles
240 Yaccflags []string
241
Colin Cross7d5136f2015-05-11 13:39:40 -0700242 // the instruction set architecture to use to compile the C/C++
243 // module.
244 Instruction_set string `android:"arch_variant"`
245
246 // list of directories relative to the root of the source tree that will
247 // be added to the include path using -I.
248 // If possible, don't use this. If adding paths from the current directory use
249 // local_include_dirs, if adding paths from other modules use export_include_dirs in
250 // that module.
251 Include_dirs []string `android:"arch_variant"`
252
Colin Cross39d97f22015-09-14 12:30:50 -0700253 // list of files relative to the root of the source tree that will be included
254 // using -include.
255 // If possible, don't use this.
256 Include_files []string `android:"arch_variant"`
257
Colin Cross7d5136f2015-05-11 13:39:40 -0700258 // list of directories relative to the Blueprints file that will
259 // be added to the include path using -I
260 Local_include_dirs []string `android:"arch_variant"`
261
Colin Cross39d97f22015-09-14 12:30:50 -0700262 // list of files relative to the Blueprints file that will be included
263 // using -include.
264 // If possible, don't use this.
265 Local_include_files []string `android:"arch_variant"`
266
Colin Crossca860ac2016-01-04 14:34:37 -0800267 // pass -frtti instead of -fno-rtti
268 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700269
Colin Crossca860ac2016-01-04 14:34:37 -0800270 Debug, Release struct {
271 // list of module-specific flags that will be used for C and C++ compiles in debug or
272 // release builds
273 Cflags []string `android:"arch_variant"`
274 } `android:"arch_variant"`
275}
Colin Cross7d5136f2015-05-11 13:39:40 -0700276
Colin Crossca860ac2016-01-04 14:34:37 -0800277type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700278 // list of modules whose object files should be linked into this module
279 // in their entirety. For static library modules, all of the .o files from the intermediate
280 // directory of the dependency will be linked into this modules .a file. For a shared library,
281 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
282 Whole_static_libs []string `android:"arch_variant"`
283
284 // list of modules that should be statically linked into this module.
285 Static_libs []string `android:"arch_variant"`
286
287 // list of modules that should be dynamically linked into this module.
288 Shared_libs []string `android:"arch_variant"`
289
Colin Crossca860ac2016-01-04 14:34:37 -0800290 // list of module-specific flags that will be used for all link steps
291 Ldflags []string `android:"arch_variant"`
292
293 // don't insert default compiler flags into asflags, cflags,
294 // cppflags, conlyflags, ldflags, or include_dirs
295 No_default_compiler_flags *bool
296
297 // list of system libraries that will be dynamically linked to
298 // shared library and executable modules. If unset, generally defaults to libc
299 // and libm. Set to [] to prevent linking against libc and libm.
300 System_shared_libs []string
301
Colin Cross7d5136f2015-05-11 13:39:40 -0700302 // allow the module to contain undefined symbols. By default,
303 // modules cannot contain undefined symbols that are not satisified by their immediate
304 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
305 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700306 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700307
Dan Willemsend67be222015-09-16 15:19:33 -0700308 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700309 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700310
Colin Cross7d5136f2015-05-11 13:39:40 -0700311 // -l arguments to pass to linker for host-provided shared libraries
312 Host_ldlibs []string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800313}
Colin Cross7d5136f2015-05-11 13:39:40 -0700314
Colin Crossca860ac2016-01-04 14:34:37 -0800315type LibraryCompilerProperties struct {
316 Static struct {
317 Srcs []string `android:"arch_variant"`
318 Exclude_srcs []string `android:"arch_variant"`
319 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700320 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800321 Shared struct {
322 Srcs []string `android:"arch_variant"`
323 Exclude_srcs []string `android:"arch_variant"`
324 Cflags []string `android:"arch_variant"`
325 } `android:"arch_variant"`
326}
327
328type LibraryLinkerProperties struct {
329 Static struct {
330 Whole_static_libs []string `android:"arch_variant"`
331 Static_libs []string `android:"arch_variant"`
332 Shared_libs []string `android:"arch_variant"`
333 } `android:"arch_variant"`
334 Shared struct {
335 Whole_static_libs []string `android:"arch_variant"`
336 Static_libs []string `android:"arch_variant"`
337 Shared_libs []string `android:"arch_variant"`
338 } `android:"arch_variant"`
339
340 // local file name to pass to the linker as --version_script
341 Version_script *string `android:"arch_variant"`
342 // local file name to pass to the linker as -unexported_symbols_list
343 Unexported_symbols_list *string `android:"arch_variant"`
344 // local file name to pass to the linker as -force_symbols_not_weak_list
345 Force_symbols_not_weak_list *string `android:"arch_variant"`
346 // local file name to pass to the linker as -force_symbols_weak_list
347 Force_symbols_weak_list *string `android:"arch_variant"`
348
349 // list of directories relative to the Blueprints file that will
350 // be added to the include path using -I for any module that links against this module
351 Export_include_dirs []string `android:"arch_variant"`
352
353 // don't link in crt_begin and crt_end. This flag should only be necessary for
354 // compiling crt or libc.
355 Nocrt *bool `android:"arch_variant"`
356}
357
358type BinaryLinkerProperties struct {
359 // compile executable with -static
360 Static_executable *bool
361
362 // set the name of the output
363 Stem string `android:"arch_variant"`
364
365 // append to the name of the output
366 Suffix string `android:"arch_variant"`
367
368 // if set, add an extra objcopy --prefix-symbols= step
369 Prefix_symbols string
370}
371
372type TestLinkerProperties struct {
373 // if set, build against the gtest library. Defaults to true.
374 Gtest bool
375
376 // Create a separate binary for each source file. Useful when there is
377 // global state that can not be torn down and reset between each test suite.
378 Test_per_src *bool
379}
380
381// Properties used to compile all C or C++ modules
382type BaseProperties struct {
383 // compile module with clang instead of gcc
384 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700385
386 // Minimum sdk version supported when compiling against the ndk
387 Sdk_version string
388
Colin Crossca860ac2016-01-04 14:34:37 -0800389 // don't insert default compiler flags into asflags, cflags,
390 // cppflags, conlyflags, ldflags, or include_dirs
391 No_default_compiler_flags *bool
392}
393
394type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700395 // install to a subdirectory of the default install path for the module
396 Relative_install_path string
397}
398
Colin Crossca860ac2016-01-04 14:34:37 -0800399type UnusedProperties struct {
Colin Crosscfad1192015-11-02 16:43:11 -0800400 Native_coverage *bool
401 Required []string
402 Sanitize []string `android:"arch_variant"`
403 Sanitize_recover []string
404 Strip string
405 Tags []string
406}
407
Colin Crossca860ac2016-01-04 14:34:37 -0800408type ModuleContextIntf interface {
409 module() *Module
410 static() bool
411 staticBinary() bool
412 clang() bool
413 toolchain() Toolchain
414 noDefaultCompilerFlags() bool
415 sdk() bool
416 sdkVersion() string
417}
418
419type ModuleContext interface {
420 common.AndroidModuleContext
421 ModuleContextIntf
422}
423
424type BaseModuleContext interface {
425 common.AndroidBaseContext
426 ModuleContextIntf
427}
428
429type Customizer interface {
430 CustomizeProperties(BaseModuleContext)
431 Properties() []interface{}
432}
433
434type feature interface {
435 begin(ctx BaseModuleContext)
436 deps(ctx BaseModuleContext, deps Deps) Deps
437 flags(ctx ModuleContext, flags Flags) Flags
438 props() []interface{}
439}
440
441type compiler interface {
442 feature
443 compile(ctx ModuleContext, flags Flags) common.Paths
444}
445
446type linker interface {
447 feature
448 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
449}
450
451type installer interface {
452 props() []interface{}
453 install(ctx ModuleContext, path common.Path)
454 inData() bool
455}
456
457// Module contains the properties and members used by all C/C++ module types, and implements
458// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
459// to construct the output file. Behavior can be customized with a Customizer interface
460type Module struct {
Colin Crossc472d572015-03-17 15:06:21 -0700461 common.AndroidModuleBase
Colin Crosscfad1192015-11-02 16:43:11 -0800462 common.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700463
Colin Crossca860ac2016-01-04 14:34:37 -0800464 Properties BaseProperties
465 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700466
Colin Crossca860ac2016-01-04 14:34:37 -0800467 // initialize before calling Init
468 hod common.HostOrDeviceSupported
469 multilib common.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700470
Colin Crossca860ac2016-01-04 14:34:37 -0800471 // delegates, initialize before calling Init
472 customizer Customizer
473 features []feature
474 compiler compiler
475 linker linker
476 installer installer
Colin Cross74d1ec02015-04-28 13:30:13 -0700477
Colin Crossca860ac2016-01-04 14:34:37 -0800478 deps Deps
479 outputFile common.OptionalPath
480
481 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700482}
483
Colin Crossca860ac2016-01-04 14:34:37 -0800484func (c *Module) Init() (blueprint.Module, []interface{}) {
485 props := []interface{}{&c.Properties, &c.unused}
486 if c.customizer != nil {
487 props = append(props, c.customizer.Properties()...)
488 }
489 if c.compiler != nil {
490 props = append(props, c.compiler.props()...)
491 }
492 if c.linker != nil {
493 props = append(props, c.linker.props()...)
494 }
495 if c.installer != nil {
496 props = append(props, c.installer.props()...)
497 }
498 for _, feature := range c.features {
499 props = append(props, feature.props()...)
500 }
Colin Crossc472d572015-03-17 15:06:21 -0700501
Colin Crossca860ac2016-01-04 14:34:37 -0800502 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700503
Colin Crossca860ac2016-01-04 14:34:37 -0800504 return common.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700505}
506
Colin Crossca860ac2016-01-04 14:34:37 -0800507type baseModuleContext struct {
508 common.AndroidBaseContext
509 moduleContextImpl
510}
511
512type moduleContext struct {
513 common.AndroidModuleContext
514 moduleContextImpl
515}
516
517type moduleContextImpl struct {
518 mod *Module
519 ctx BaseModuleContext
520}
521
522func (ctx *moduleContextImpl) module() *Module {
523 return ctx.mod
524}
525
526func (ctx *moduleContextImpl) clang() bool {
527 return ctx.mod.clang(ctx.ctx)
528}
529
530func (ctx *moduleContextImpl) toolchain() Toolchain {
531 return ctx.mod.toolchain(ctx.ctx)
532}
533
534func (ctx *moduleContextImpl) static() bool {
535 if ctx.mod.linker == nil {
536 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
537 }
538 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
539 return linker.static()
540 } else {
541 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
542 }
543}
544
545func (ctx *moduleContextImpl) staticBinary() bool {
546 if ctx.mod.linker == nil {
547 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
548 }
549 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
550 return linker.staticBinary()
551 } else {
552 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
553 }
554}
555
556func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
557 return Bool(ctx.mod.Properties.No_default_compiler_flags)
558}
559
560func (ctx *moduleContextImpl) sdk() bool {
561 return ctx.mod.Properties.Sdk_version != ""
562}
563
564func (ctx *moduleContextImpl) sdkVersion() string {
565 return ctx.mod.Properties.Sdk_version
566}
567
568func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
569 return &Module{
570 hod: hod,
571 multilib: multilib,
572 }
573}
574
575func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
576 module := newBaseModule(hod, multilib)
577 module.features = []feature{
578 &stlFeature{},
579 }
580 return module
581}
582
583func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
584 ctx := &moduleContext{
585 AndroidModuleContext: actx,
586 moduleContextImpl: moduleContextImpl{
587 mod: c,
588 },
589 }
590 ctx.ctx = ctx
591
592 flags := Flags{
593 Toolchain: c.toolchain(ctx),
594 Clang: c.clang(ctx),
595 }
596
597 if c.compiler != nil {
598 flags = c.compiler.flags(ctx, flags)
599 }
600 if c.linker != nil {
601 flags = c.linker.flags(ctx, flags)
602 }
603 for _, feature := range c.features {
604 flags = feature.flags(ctx, flags)
605 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800606 if ctx.Failed() {
607 return
608 }
609
Colin Crossca860ac2016-01-04 14:34:37 -0800610 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
611 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
612 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800613
Colin Crossca860ac2016-01-04 14:34:37 -0800614 // Optimization to reduce size of build.ninja
615 // Replace the long list of flags for each file with a module-local variable
616 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
617 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
618 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
619 flags.CFlags = []string{"$cflags"}
620 flags.CppFlags = []string{"$cppflags"}
621 flags.AsFlags = []string{"$asflags"}
622
623 deps := c.depsToPaths(actx, c.deps)
Colin Cross3f40fa42015-01-30 17:27:36 -0800624 if ctx.Failed() {
625 return
626 }
627
Colin Cross28344522015-04-22 13:07:53 -0700628 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700629
Colin Crossca860ac2016-01-04 14:34:37 -0800630 var objFiles common.Paths
631 if c.compiler != nil {
632 objFiles = c.compiler.compile(ctx, flags)
633 if ctx.Failed() {
634 return
635 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800636 }
637
Colin Crossca860ac2016-01-04 14:34:37 -0800638 if c.linker != nil {
639 outputFile := c.linker.link(ctx, flags, deps, objFiles)
640 if ctx.Failed() {
641 return
642 }
643 c.outputFile = common.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700644
Colin Crossca860ac2016-01-04 14:34:37 -0800645 if c.installer != nil {
646 c.installer.install(ctx, outputFile)
647 if ctx.Failed() {
648 return
649 }
650 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700651 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800652}
653
Colin Crossca860ac2016-01-04 14:34:37 -0800654func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
655 if c.cachedToolchain == nil {
656 arch := ctx.Arch()
657 hod := ctx.HostOrDevice()
658 ht := ctx.HostType()
659 factory := toolchainFactories[hod][ht][arch.ArchType]
660 if factory == nil {
661 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
662 return nil
663 }
664 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800665 }
Colin Crossca860ac2016-01-04 14:34:37 -0800666 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800667}
668
Colin Crossca860ac2016-01-04 14:34:37 -0800669func (c *Module) begin(ctx BaseModuleContext) {
670 if c.compiler != nil {
671 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700672 }
Colin Crossca860ac2016-01-04 14:34:37 -0800673 if c.linker != nil {
674 c.linker.begin(ctx)
675 }
676 for _, feature := range c.features {
677 feature.begin(ctx)
678 }
679}
680
681func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
682 ctx := &baseModuleContext{
683 AndroidBaseContext: actx,
684 moduleContextImpl: moduleContextImpl{
685 mod: c,
686 },
687 }
688 ctx.ctx = ctx
689
690 if c.customizer != nil {
691 c.customizer.CustomizeProperties(ctx)
692 }
693
694 c.begin(ctx)
695
696 c.deps = Deps{}
697
698 if c.compiler != nil {
699 c.deps = c.compiler.deps(ctx, c.deps)
700 }
701 if c.linker != nil {
702 c.deps = c.linker.deps(ctx, c.deps)
703 }
704 for _, feature := range c.features {
705 c.deps = feature.deps(ctx, c.deps)
706 }
707
708 c.deps.WholeStaticLibs = lastUniqueElements(c.deps.WholeStaticLibs)
709 c.deps.StaticLibs = lastUniqueElements(c.deps.StaticLibs)
710 c.deps.LateStaticLibs = lastUniqueElements(c.deps.LateStaticLibs)
711 c.deps.SharedLibs = lastUniqueElements(c.deps.SharedLibs)
712 c.deps.LateSharedLibs = lastUniqueElements(c.deps.LateSharedLibs)
713
714 staticLibs := c.deps.WholeStaticLibs
715 staticLibs = append(staticLibs, c.deps.StaticLibs...)
716 staticLibs = append(staticLibs, c.deps.LateStaticLibs...)
717 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticLibs...)
718
719 sharedLibs := c.deps.SharedLibs
720 sharedLibs = append(sharedLibs, c.deps.LateSharedLibs...)
721 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedLibs...)
722
723 actx.AddDependency(ctx.module(), c.deps.ObjFiles.Strings()...)
724 if c.deps.CrtBegin != "" {
725 actx.AddDependency(ctx.module(), c.deps.CrtBegin)
726 }
727 if c.deps.CrtEnd != "" {
728 actx.AddDependency(ctx.module(), c.deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700729 }
Colin Cross6362e272015-10-29 15:25:03 -0700730}
Colin Cross21b9a242015-03-24 14:15:58 -0700731
Colin Cross6362e272015-10-29 15:25:03 -0700732func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800733 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700734 c.depsMutator(ctx)
735 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800736}
737
Colin Crossca860ac2016-01-04 14:34:37 -0800738func (c *Module) clang(ctx BaseModuleContext) bool {
739 clang := Bool(c.Properties.Clang)
740
741 if c.Properties.Clang == nil {
742 if ctx.Host() {
743 clang = true
744 }
745
746 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
747 clang = true
748 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800749 }
Colin Cross28344522015-04-22 13:07:53 -0700750
Colin Crossca860ac2016-01-04 14:34:37 -0800751 if !c.toolchain(ctx).ClangSupported() {
752 clang = false
753 }
754
755 return clang
756}
757
758func (c *Module) depsToPathsFromList(ctx common.AndroidModuleContext,
759 names []string) (modules []common.AndroidModule,
760 outputFiles common.Paths, exportedFlags []string) {
761
762 for _, n := range names {
763 found := false
764 ctx.VisitDirectDeps(func(m blueprint.Module) {
765 otherName := ctx.OtherModuleName(m)
766 if otherName != n {
767 return
768 }
769
770 if a, ok := m.(*Module); ok {
771 if !a.Enabled() {
772 ctx.ModuleErrorf("depends on disabled module %q", otherName)
773 return
774 }
775 if a.HostOrDevice() != ctx.HostOrDevice() {
776 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
777 otherName)
778 return
779 }
780
781 if outputFile := a.outputFile; outputFile.Valid() {
782 if found {
783 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
784 return
785 }
786 outputFiles = append(outputFiles, outputFile.Path())
787 modules = append(modules, a)
788 if i, ok := a.linker.(exportedFlagsProducer); ok {
789 exportedFlags = append(exportedFlags, i.exportedFlags()...)
790 }
791 found = true
792 } else {
793 ctx.ModuleErrorf("module %q missing output file", otherName)
794 return
795 }
796 } else {
797 ctx.ModuleErrorf("module %q not an android module", otherName)
798 return
799 }
800 })
801 if !found && !inList(n, ctx.GetMissingDependencies()) {
802 ctx.ModuleErrorf("unsatisified dependency on %q", n)
803 }
804 }
805
806 return modules, outputFiles, exportedFlags
807}
808
809// Convert dependency names to paths. Takes a Deps containing names and returns a PathDeps
810// containing paths
811func (c *Module) depsToPaths(ctx common.AndroidModuleContext, deps Deps) PathDeps {
812 var depPaths PathDeps
813 var newCflags []string
814
815 var wholeStaticLibModules []common.AndroidModule
816
817 wholeStaticLibModules, depPaths.WholeStaticLibs, newCflags =
818 c.depsToPathsFromList(ctx, deps.WholeStaticLibs)
819 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
820 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, newCflags...)
821
822 for _, am := range wholeStaticLibModules {
823 if m, ok := am.(*Module); ok {
824 if staticLib, ok := m.linker.(*libraryLinker); ok && staticLib.static() {
825 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
826 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
827 for i := range missingDeps {
828 missingDeps[i] += postfix
829 }
830 ctx.AddMissingDependencies(missingDeps)
831 }
832 depPaths.WholeStaticLibObjFiles =
833 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
834 } else {
835 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
836 }
837 } else {
838 ctx.ModuleErrorf("module %q not an android module", ctx.OtherModuleName(m))
839 }
840 }
841
842 _, depPaths.StaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.StaticLibs)
843 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
844
845 _, depPaths.LateStaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateStaticLibs)
846 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
847
848 _, depPaths.SharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.SharedLibs)
849 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
850
851 _, depPaths.LateSharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateSharedLibs)
852 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
853
854 ctx.VisitDirectDeps(func(bm blueprint.Module) {
855 if m, ok := bm.(*Module); ok {
856 otherName := ctx.OtherModuleName(m)
857 if otherName == deps.CrtBegin {
858 depPaths.CrtBegin = m.outputFile
859 } else if otherName == deps.CrtEnd {
860 depPaths.CrtEnd = m.outputFile
861 } else {
862 output := m.outputFile
863 if output.Valid() {
864 depPaths.ObjFiles = append(depPaths.ObjFiles, output.Path())
865 } else {
866 ctx.ModuleErrorf("module %s did not provide an output file", otherName)
867 }
868 }
869 }
870 })
871
872 return depPaths
873}
874
875func (c *Module) InstallInData() bool {
876 if c.installer == nil {
877 return false
878 }
879 return c.installer.inData()
880}
881
882// Compiler
883
884type baseCompiler struct {
885 Properties BaseCompilerProperties
886}
887
888var _ compiler = (*baseCompiler)(nil)
889
890func (compiler *baseCompiler) props() []interface{} {
891 return []interface{}{&compiler.Properties}
892}
893
894func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
895func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps { return deps }
896
897// Create a Flags struct that collects the compile flags from global values,
898// per-target values, module type values, and per-module Blueprints properties
899func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
900 toolchain := ctx.toolchain()
901
902 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
903 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
904 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
905 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
906 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
907
Colin Cross28344522015-04-22 13:07:53 -0700908 // Include dir cflags
Colin Crossca860ac2016-01-04 14:34:37 -0800909 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
910 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -0700911 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -0700912 includeDirsToFlags(localIncludeDirs),
913 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -0700914
Colin Crossca860ac2016-01-04 14:34:37 -0800915 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
916 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -0700917
918 flags.GlobalFlags = append(flags.GlobalFlags,
919 includeFilesToFlags(rootIncludeFiles),
920 includeFilesToFlags(localIncludeFiles))
921
Colin Crossca860ac2016-01-04 14:34:37 -0800922 if !ctx.noDefaultCompilerFlags() {
923 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -0700924 flags.GlobalFlags = append(flags.GlobalFlags,
925 "${commonGlobalIncludes}",
926 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -0800927 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -0700928 }
929
930 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700931 "-I" + common.PathForModuleSrc(ctx).String(),
932 "-I" + common.PathForModuleOut(ctx).String(),
933 "-I" + common.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -0700934 }...)
935 }
936
Colin Crossca860ac2016-01-04 14:34:37 -0800937 instructionSet := compiler.Properties.Instruction_set
938 if flags.RequiredInstructionSet != "" {
939 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -0800940 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -0800941 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
942 if flags.Clang {
943 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
944 }
945 if err != nil {
946 ctx.ModuleErrorf("%s", err)
947 }
948
949 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -0800950 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -0800951
Colin Cross97ba0732015-03-23 17:50:24 -0700952 if flags.Clang {
953 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -0800954 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
955 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -0700956 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
957 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
958 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800959
960 target := "-target " + toolchain.ClangTriple()
961 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
962
Colin Cross97ba0732015-03-23 17:50:24 -0700963 flags.CFlags = append(flags.CFlags, target, gccPrefix)
964 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
965 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800966 }
967
Colin Crossca860ac2016-01-04 14:34:37 -0800968 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -0700969 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
970
Colin Cross97ba0732015-03-23 17:50:24 -0700971 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -0800972 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -0700973 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -0700974 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800975 toolchain.ClangCflags(),
976 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -0700977 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800978
979 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800980 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700981 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -0700982 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800983 toolchain.Cflags(),
984 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -0700985 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800986 }
987
Colin Cross7b66f152015-12-15 16:07:43 -0800988 if Bool(ctx.AConfig().ProductVariables.Brillo) {
989 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
990 }
991
Colin Crossf6566ed2015-03-24 11:13:38 -0700992 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -0800993 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -0700994 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800995 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700996 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -0800997 }
998 }
999
Colin Cross97ba0732015-03-23 17:50:24 -07001000 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001001
Colin Cross97ba0732015-03-23 17:50:24 -07001002 if flags.Clang {
1003 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001004 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001005 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001006 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001007 }
1008
Colin Crossc4bde762015-11-23 16:11:30 -08001009 if flags.Clang {
1010 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1011 } else {
1012 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001013 }
Dan Willemsen6dd06602016-01-12 21:51:11 -08001014 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001015
Colin Crossca860ac2016-01-04 14:34:37 -08001016 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001017 if ctx.Host() && !flags.Clang {
1018 // The host GCC doesn't support C++14 (and is deprecated, so likely
1019 // never will). Build these modules with C++11.
1020 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1021 } else {
1022 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1023 }
1024 }
1025
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001026 // We can enforce some rules more strictly in the code we own. strict
1027 // indicates if this is code that we can be stricter with. If we have
1028 // rules that we want to apply to *our* code (but maybe can't for
1029 // vendor/device specific things), we could extend this to be a ternary
1030 // value.
1031 strict := true
1032 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1033 strict = false
1034 }
1035
1036 // Can be used to make some annotations stricter for code we can fix
1037 // (such as when we mark functions as deprecated).
1038 if strict {
1039 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1040 }
1041
Colin Cross3f40fa42015-01-30 17:27:36 -08001042 return flags
1043}
1044
Colin Crossca860ac2016-01-04 14:34:37 -08001045func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1046 // Compile files listed in c.Properties.Srcs into objects
1047 objFiles := compiler.compileObjs(ctx, flags, "", compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
1048 if ctx.Failed() {
1049 return nil
1050 }
1051
1052 var genSrcs common.Paths
1053 ctx.VisitDirectDeps(func(module blueprint.Module) {
1054 if gen, ok := module.(genrule.SourceFileGenerator); ok {
1055 genSrcs = append(genSrcs, gen.GeneratedSourceFiles()...)
1056 }
1057 })
1058
1059 if len(genSrcs) != 0 {
1060 genObjs := TransformSourceToObj(ctx, "", genSrcs, flagsToBuilderFlags(flags), nil)
1061 objFiles = append(objFiles, genObjs...)
1062 }
1063
1064 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001065}
1066
1067// Compile a list of source files into objects a specified subdirectory
Colin Crossca860ac2016-01-04 14:34:37 -08001068func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001069 subdir string, srcFiles, excludes []string) common.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001070
Colin Crossca860ac2016-01-04 14:34:37 -08001071 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001072
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001073 inputFiles := ctx.ExpandSources(srcFiles, excludes)
1074 srcPaths, deps := genSources(ctx, inputFiles, buildFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001075
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001076 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001077}
1078
Colin Crossca860ac2016-01-04 14:34:37 -08001079// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1080type baseLinker struct {
1081 Properties BaseLinkerProperties
1082 dynamicProperties struct {
1083 VariantIsShared bool `blueprint:"mutated"`
1084 VariantIsStatic bool `blueprint:"mutated"`
1085 VariantIsStaticBinary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001086 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001087}
1088
Colin Crossca860ac2016-01-04 14:34:37 -08001089func (linker *baseLinker) begin(ctx BaseModuleContext) {}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001090
Colin Crossca860ac2016-01-04 14:34:37 -08001091func (linker *baseLinker) props() []interface{} {
1092 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001093}
1094
Colin Crossca860ac2016-01-04 14:34:37 -08001095func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1096 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1097 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1098 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001099
Colin Cross74d1ec02015-04-28 13:30:13 -07001100 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001101 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001102 }
1103
Colin Crossf6566ed2015-03-24 11:13:38 -07001104 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001105 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001106 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1107 if !Bool(linker.Properties.No_libgcc) {
1108 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001109 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001110
Colin Crossca860ac2016-01-04 14:34:37 -08001111 if !linker.static() {
1112 if linker.Properties.System_shared_libs != nil {
1113 deps.LateSharedLibs = append(deps.LateSharedLibs,
1114 linker.Properties.System_shared_libs...)
1115 } else if !ctx.sdk() {
1116 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1117 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001118 }
Colin Cross577f6e42015-03-27 18:23:34 -07001119
Colin Crossca860ac2016-01-04 14:34:37 -08001120 if ctx.sdk() {
1121 version := ctx.sdkVersion()
1122 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001123 "ndk_libc."+version,
1124 "ndk_libm."+version,
1125 )
1126 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001127 }
1128
Colin Crossca860ac2016-01-04 14:34:37 -08001129 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001130}
1131
Colin Crossca860ac2016-01-04 14:34:37 -08001132func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1133 toolchain := ctx.toolchain()
1134
1135 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1136
1137 if !ctx.noDefaultCompilerFlags() {
1138 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1139 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1140 }
1141
1142 if flags.Clang {
1143 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1144 } else {
1145 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1146 }
1147
1148 if ctx.Host() {
1149 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1150 }
1151 }
1152
1153 if !flags.Clang {
1154 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1155 }
1156
1157 return flags
1158}
1159
1160func (linker *baseLinker) static() bool {
1161 return linker.dynamicProperties.VariantIsStatic
1162}
1163
1164func (linker *baseLinker) staticBinary() bool {
1165 return linker.dynamicProperties.VariantIsStaticBinary
1166}
1167
1168func (linker *baseLinker) setStatic(static bool) {
1169 linker.dynamicProperties.VariantIsStatic = static
1170}
1171
1172type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001173 // Returns true if the build options for the module have selected a static or shared build
1174 buildStatic() bool
1175 buildShared() bool
1176
1177 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001178 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001179
Colin Cross18b6dc52015-04-28 13:20:37 -07001180 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001181 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001182
1183 // Returns whether a module is a static binary
1184 staticBinary() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001185}
1186
Colin Crossca860ac2016-01-04 14:34:37 -08001187type exportedFlagsProducer interface {
Colin Cross28344522015-04-22 13:07:53 -07001188 exportedFlags() []string
Colin Cross3f40fa42015-01-30 17:27:36 -08001189}
1190
Colin Crossca860ac2016-01-04 14:34:37 -08001191type baseInstaller struct {
1192 Properties InstallerProperties
1193
1194 dir string
1195 dir64 string
1196 data bool
1197
Colin Crossa2344662016-03-24 13:14:12 -07001198 path common.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001199}
1200
1201var _ installer = (*baseInstaller)(nil)
1202
1203func (installer *baseInstaller) props() []interface{} {
1204 return []interface{}{&installer.Properties}
1205}
1206
1207func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1208 subDir := installer.dir
1209 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1210 subDir = installer.dir64
1211 }
1212 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1213 installer.path = ctx.InstallFile(dir, file)
1214}
1215
1216func (installer *baseInstaller) inData() bool {
1217 return installer.data
1218}
1219
Colin Cross3f40fa42015-01-30 17:27:36 -08001220//
1221// Combined static+shared libraries
1222//
1223
Colin Crossca860ac2016-01-04 14:34:37 -08001224type libraryCompiler struct {
1225 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001226
Colin Crossca860ac2016-01-04 14:34:37 -08001227 linker *libraryLinker
1228 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001229
Colin Crossca860ac2016-01-04 14:34:37 -08001230 // For reusing static library objects for shared library
1231 reuseFrom *libraryCompiler
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001232 reuseObjFiles common.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001233}
1234
Colin Crossca860ac2016-01-04 14:34:37 -08001235var _ compiler = (*libraryCompiler)(nil)
1236
1237func (library *libraryCompiler) props() []interface{} {
1238 props := library.baseCompiler.props()
1239 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001240}
1241
Colin Crossca860ac2016-01-04 14:34:37 -08001242func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1243 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001244
Dan Willemsen490fd492015-11-24 17:53:15 -08001245 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1246 // all code is position independent, and then those warnings get promoted to
1247 // errors.
1248 if ctx.HostType() != common.Windows {
1249 flags.CFlags = append(flags.CFlags, "-fPIC")
1250 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001251
Colin Crossca860ac2016-01-04 14:34:37 -08001252 if library.linker.static() {
1253 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001254 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001255 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001256 }
1257
Colin Crossca860ac2016-01-04 14:34:37 -08001258 return flags
1259}
1260
1261func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1262 var objFiles common.Paths
1263
1264 if library.reuseFrom != library && library.reuseFrom.Properties.Static.Cflags == nil &&
1265 library.Properties.Shared.Cflags == nil {
1266 objFiles = append(common.Paths(nil), library.reuseFrom.reuseObjFiles...)
1267 } else {
1268 objFiles = library.baseCompiler.compile(ctx, flags)
1269 library.reuseObjFiles = objFiles
1270 }
1271
1272 if library.linker.static() {
1273 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
1274 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs)...)
1275 } else {
1276 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
1277 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs)...)
1278 }
1279
1280 return objFiles
1281}
1282
1283type libraryLinker struct {
1284 baseLinker
1285
1286 Properties LibraryLinkerProperties
1287
1288 dynamicProperties struct {
1289 BuildStatic bool `blueprint:"mutated"`
1290 BuildShared bool `blueprint:"mutated"`
1291 }
1292
1293 exportFlags []string
1294
1295 // If we're used as a whole_static_lib, our missing dependencies need
1296 // to be given
1297 wholeStaticMissingDeps []string
1298
1299 // For whole_static_libs
1300 objFiles common.Paths
1301}
1302
1303var _ linker = (*libraryLinker)(nil)
1304var _ exportedFlagsProducer = (*libraryLinker)(nil)
1305
1306func (library *libraryLinker) props() []interface{} {
1307 props := library.baseLinker.props()
1308 return append(props, &library.Properties, &library.dynamicProperties)
1309}
1310
1311func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1312 flags = library.baseLinker.flags(ctx, flags)
1313
1314 flags.Nocrt = Bool(library.Properties.Nocrt)
1315
1316 if !library.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001317 libName := ctx.ModuleName()
1318 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1319 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001320 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001321 sharedFlag = "-shared"
1322 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001323 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001324 flags.LdFlags = append(flags.LdFlags,
1325 "-nostdlib",
1326 "-Wl,--gc-sections",
1327 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001328 }
Colin Cross97ba0732015-03-23 17:50:24 -07001329
Colin Cross0af4b842015-04-30 16:36:18 -07001330 if ctx.Darwin() {
1331 flags.LdFlags = append(flags.LdFlags,
1332 "-dynamiclib",
1333 "-single_module",
1334 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001335 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001336 )
1337 } else {
1338 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001339 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001340 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001341 )
1342 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001343 }
Colin Cross97ba0732015-03-23 17:50:24 -07001344
1345 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001346}
1347
Colin Crossca860ac2016-01-04 14:34:37 -08001348func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1349 deps = library.baseLinker.deps(ctx, deps)
1350 if library.static() {
1351 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1352 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1353 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1354 } else {
1355 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1356 if !ctx.sdk() {
1357 deps.CrtBegin = "crtbegin_so"
1358 deps.CrtEnd = "crtend_so"
1359 } else {
1360 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1361 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1362 }
1363 }
1364 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1365 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1366 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1367 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001368
Colin Crossca860ac2016-01-04 14:34:37 -08001369 return deps
1370}
Colin Cross3f40fa42015-01-30 17:27:36 -08001371
Colin Crossca860ac2016-01-04 14:34:37 -08001372func (library *libraryLinker) exportedFlags() []string {
1373 return library.exportFlags
1374}
1375
1376func (library *libraryLinker) linkStatic(ctx ModuleContext,
1377 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1378
Colin Cross21b9a242015-03-24 14:15:58 -07001379 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Crossca860ac2016-01-04 14:34:37 -08001380 library.objFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001381
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001382 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001383
Colin Cross0af4b842015-04-30 16:36:18 -07001384 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001385 TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001386 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001387 TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001388 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001389
Colin Crossca860ac2016-01-04 14:34:37 -08001390 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001391
1392 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001393
1394 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001395}
1396
Colin Crossca860ac2016-01-04 14:34:37 -08001397func (library *libraryLinker) linkShared(ctx ModuleContext,
1398 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001399
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001400 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
Colin Cross3f40fa42015-01-30 17:27:36 -08001401
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001402 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001403
Colin Crossca860ac2016-01-04 14:34:37 -08001404 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1405 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1406 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1407 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001408 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001409 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001410 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001411 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001412 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001413 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001414 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1415 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001416 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001417 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1418 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001419 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001420 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1421 }
1422 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001423 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001424 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1425 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001426 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001427 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001428 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001429 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001430 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001431 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001432 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001433 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001434 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001435 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001436 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001437 }
Colin Crossaee540a2015-07-06 17:48:31 -07001438 }
1439
Colin Crossca860ac2016-01-04 14:34:37 -08001440 sharedLibs := deps.SharedLibs
1441 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001442
Colin Crossca860ac2016-01-04 14:34:37 -08001443 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1444 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1445 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile)
1446
1447 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001448}
1449
Colin Crossca860ac2016-01-04 14:34:37 -08001450func (library *libraryLinker) link(ctx ModuleContext,
1451 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001452
Colin Crossca860ac2016-01-04 14:34:37 -08001453 var out common.Path
1454 if library.static() {
1455 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001456 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001457 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001458 }
1459
Colin Crossca860ac2016-01-04 14:34:37 -08001460 includeDirs := common.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)
1461 library.exportFlags = []string{includeDirsToFlags(includeDirs)}
1462 library.exportFlags = append(library.exportFlags, deps.ReexportedCflags...)
1463
1464 return out
1465}
1466
1467func (library *libraryLinker) buildStatic() bool {
1468 return library.dynamicProperties.BuildStatic
1469}
1470
1471func (library *libraryLinker) buildShared() bool {
1472 return library.dynamicProperties.BuildShared
1473}
1474
1475func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1476 return library.wholeStaticMissingDeps
1477}
1478
1479type libraryInstaller struct {
1480 baseInstaller
1481
1482 linker *libraryLinker
1483}
1484
1485func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1486 if !library.linker.static() {
1487 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001488 }
1489}
1490
Colin Crossca860ac2016-01-04 14:34:37 -08001491func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1492 module := newModule(hod, common.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001493
Colin Crossca860ac2016-01-04 14:34:37 -08001494 linker := &libraryLinker{}
1495 linker.dynamicProperties.BuildShared = shared
1496 linker.dynamicProperties.BuildStatic = static
1497 module.linker = linker
1498
1499 module.compiler = &libraryCompiler{
1500 linker: linker,
1501 }
1502 module.installer = &libraryInstaller{
1503 baseInstaller: baseInstaller{
1504 dir: "lib",
1505 dir64: "lib64",
1506 },
1507 linker: linker,
Dan Albertc403f7c2015-03-18 14:01:18 -07001508 }
1509
Colin Crossca860ac2016-01-04 14:34:37 -08001510 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001511}
1512
Colin Crossca860ac2016-01-04 14:34:37 -08001513func libraryFactory() (blueprint.Module, []interface{}) {
1514 module := NewLibrary(common.HostAndDeviceSupported, true, true)
1515 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001516}
1517
Colin Cross3f40fa42015-01-30 17:27:36 -08001518//
1519// Objects (for crt*.o)
1520//
1521
Colin Crossca860ac2016-01-04 14:34:37 -08001522type objectLinker struct {
Dan Albertc3144b12015-04-28 18:17:56 -07001523}
1524
Colin Crossca860ac2016-01-04 14:34:37 -08001525func objectFactory() (blueprint.Module, []interface{}) {
1526 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1527 module.compiler = &baseCompiler{}
1528 module.linker = &objectLinker{}
1529 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001530}
1531
Colin Crossca860ac2016-01-04 14:34:37 -08001532func (*objectLinker) props() []interface{} {
1533 return nil
Dan Albertc3144b12015-04-28 18:17:56 -07001534}
1535
Colin Crossca860ac2016-01-04 14:34:37 -08001536func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001537
Colin Crossca860ac2016-01-04 14:34:37 -08001538func (*objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross21b9a242015-03-24 14:15:58 -07001539 // object files can't have any dynamic dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08001540 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001541}
1542
Colin Crossca860ac2016-01-04 14:34:37 -08001543func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
1544 return flags
1545}
1546
1547func (object *objectLinker) link(ctx ModuleContext,
1548 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001549
Colin Cross97ba0732015-03-23 17:50:24 -07001550 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001551
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001552 var outputFile common.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001553 if len(objFiles) == 1 {
1554 outputFile = objFiles[0]
1555 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001556 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001557 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001558 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001559 }
1560
Colin Cross3f40fa42015-01-30 17:27:36 -08001561 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001562 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001563}
1564
Colin Cross3f40fa42015-01-30 17:27:36 -08001565//
1566// Executables
1567//
1568
Colin Crossca860ac2016-01-04 14:34:37 -08001569type binaryLinker struct {
1570 baseLinker
Colin Cross7d5136f2015-05-11 13:39:40 -07001571
Colin Crossca860ac2016-01-04 14:34:37 -08001572 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001573
Colin Crossca860ac2016-01-04 14:34:37 -08001574 hostToolPath common.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001575}
1576
Colin Crossca860ac2016-01-04 14:34:37 -08001577var _ linker = (*binaryLinker)(nil)
1578
1579func (binary *binaryLinker) props() []interface{} {
1580 return append(binary.baseLinker.props(), &binary.Properties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001581}
1582
Colin Crossca860ac2016-01-04 14:34:37 -08001583func (binary *binaryLinker) buildStatic() bool {
1584 return Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001585}
1586
Colin Crossca860ac2016-01-04 14:34:37 -08001587func (binary *binaryLinker) buildShared() bool {
1588 return !Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001589}
1590
Colin Crossca860ac2016-01-04 14:34:37 -08001591func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001592 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001593 if binary.Properties.Stem != "" {
1594 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001595 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001596
Colin Crossca860ac2016-01-04 14:34:37 -08001597 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001598}
1599
Colin Crossca860ac2016-01-04 14:34:37 -08001600func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1601 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001602 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001603 if !ctx.sdk() {
1604 if Bool(binary.Properties.Static_executable) {
1605 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001606 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001607 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001608 }
Colin Crossca860ac2016-01-04 14:34:37 -08001609 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001610 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001611 if Bool(binary.Properties.Static_executable) {
1612 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001613 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001614 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001615 }
Colin Crossca860ac2016-01-04 14:34:37 -08001616 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001617 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001618
Colin Crossca860ac2016-01-04 14:34:37 -08001619 if Bool(binary.Properties.Static_executable) {
1620 if inList("libc++_static", deps.StaticLibs) {
1621 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001622 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001623 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1624 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1625 // move them to the beginning of deps.LateStaticLibs
1626 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001627 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001628 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001629 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001630 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001631 }
Colin Crossca860ac2016-01-04 14:34:37 -08001632
1633 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1634 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1635 "from static libs or set static_executable: true")
1636 }
1637 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001638}
1639
Colin Crossca860ac2016-01-04 14:34:37 -08001640func NewBinary(hod common.HostOrDeviceSupported) *Module {
1641 module := newModule(hod, common.MultilibFirst)
1642 module.compiler = &baseCompiler{}
1643 module.linker = &binaryLinker{}
1644 module.installer = &baseInstaller{
1645 dir: "bin",
1646 }
1647 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001648}
1649
Colin Crossca860ac2016-01-04 14:34:37 -08001650func binaryFactory() (blueprint.Module, []interface{}) {
1651 module := NewBinary(common.HostAndDeviceSupported)
1652 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001653}
1654
Colin Crossca860ac2016-01-04 14:34:37 -08001655func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001656 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001657 binary.Properties.Static_executable = proptools.BoolPtr(false)
Colin Cross0af4b842015-04-30 16:36:18 -07001658 }
Colin Crossca860ac2016-01-04 14:34:37 -08001659 if Bool(binary.Properties.Static_executable) {
1660 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001661 }
1662}
1663
Colin Crossca860ac2016-01-04 14:34:37 -08001664func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1665 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001666
Dan Willemsen490fd492015-11-24 17:53:15 -08001667 if ctx.Host() {
1668 flags.LdFlags = append(flags.LdFlags, "-pie")
1669 if ctx.HostType() == common.Windows {
1670 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1671 }
1672 }
1673
1674 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1675 // all code is position independent, and then those warnings get promoted to
1676 // errors.
1677 if ctx.HostType() != common.Windows {
1678 flags.CFlags = append(flags.CFlags, "-fpie")
1679 }
Colin Cross97ba0732015-03-23 17:50:24 -07001680
Colin Crossf6566ed2015-03-24 11:13:38 -07001681 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001682 if Bool(binary.Properties.Static_executable) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001683 // Clang driver needs -static to create static executable.
1684 // However, bionic/linker uses -shared to overwrite.
1685 // Linker for x86 targets does not allow coexistance of -static and -shared,
1686 // so we add -static only if -shared is not used.
1687 if !inList("-shared", flags.LdFlags) {
1688 flags.LdFlags = append(flags.LdFlags, "-static")
1689 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001690
Colin Crossed4cf0b2015-03-26 14:43:45 -07001691 flags.LdFlags = append(flags.LdFlags,
1692 "-nostdlib",
1693 "-Bstatic",
1694 "-Wl,--gc-sections",
1695 )
1696
1697 } else {
1698 linker := "/system/bin/linker"
1699 if flags.Toolchain.Is64Bit() {
Colin Crossca860ac2016-01-04 14:34:37 -08001700 linker += "64"
Colin Crossed4cf0b2015-03-26 14:43:45 -07001701 }
1702
1703 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001704 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001705 "-nostdlib",
1706 "-Bdynamic",
1707 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1708 "-Wl,--gc-sections",
1709 "-Wl,-z,nocopyreloc",
1710 )
1711 }
Colin Cross0af4b842015-04-30 16:36:18 -07001712 } else if ctx.Darwin() {
1713 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001714 }
1715
Colin Cross97ba0732015-03-23 17:50:24 -07001716 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001717}
1718
Colin Crossca860ac2016-01-04 14:34:37 -08001719func (binary *binaryLinker) link(ctx ModuleContext,
1720 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001721
Colin Crossca860ac2016-01-04 14:34:37 -08001722 outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
1723 if ctx.HostOrDevice().Host() {
1724 binary.hostToolPath = common.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001725 }
Colin Crossca860ac2016-01-04 14:34:37 -08001726 ret := outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001727
Colin Crossca860ac2016-01-04 14:34:37 -08001728 if binary.Properties.Prefix_symbols != "" {
Colin Crossbfae8852015-03-26 14:44:11 -07001729 afterPrefixSymbols := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001730 outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate")
1731 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1732 flagsToBuilderFlags(flags), afterPrefixSymbols)
Colin Crossbfae8852015-03-26 14:44:11 -07001733 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001734
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001735 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001736
Colin Crossca860ac2016-01-04 14:34:37 -08001737 sharedLibs := deps.SharedLibs
1738 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1739
1740 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001741 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Crossca860ac2016-01-04 14:34:37 -08001742 flagsToBuilderFlags(flags), outputFile)
1743
1744 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001745}
Colin Cross3f40fa42015-01-30 17:27:36 -08001746
Colin Crossca860ac2016-01-04 14:34:37 -08001747func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1748 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001749}
1750
Colin Cross6362e272015-10-29 15:25:03 -07001751func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08001752 if m, ok := mctx.Module().(*Module); ok {
1753 if test, ok := m.linker.(*testLinker); ok {
1754 if Bool(test.Properties.Test_per_src) {
1755 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
1756 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1757 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
1758 }
1759 tests := mctx.CreateLocalVariations(testNames...)
1760 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1761 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
1762 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
1763 }
Colin Cross6002e052015-09-16 16:00:08 -07001764 }
1765 }
1766 }
Colin Cross7d5136f2015-05-11 13:39:40 -07001767}
1768
Colin Crossca860ac2016-01-04 14:34:37 -08001769type testLinker struct {
1770 binaryLinker
1771 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001772}
1773
Colin Crossca860ac2016-01-04 14:34:37 -08001774func (test *testLinker) props() []interface{} {
1775 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07001776}
1777
Colin Crossca860ac2016-01-04 14:34:37 -08001778func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
1779 flags = test.binaryLinker.flags(ctx, flags)
1780
1781 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001782 return flags
1783 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001784
Colin Cross97ba0732015-03-23 17:50:24 -07001785 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001786 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001787 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001788
1789 if ctx.HostType() == common.Windows {
1790 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
1791 } else {
1792 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
1793 flags.LdFlags = append(flags.LdFlags, "-lpthread")
1794 }
1795 } else {
1796 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07001797 }
1798
1799 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross28344522015-04-22 13:07:53 -07001800 flags.CFlags = append(flags.CFlags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001801 "-I"+common.PathForSource(ctx, "external/gtest/include").String())
Dan Albertc403f7c2015-03-18 14:01:18 -07001802
Colin Cross21b9a242015-03-24 14:15:58 -07001803 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07001804}
1805
Colin Crossca860ac2016-01-04 14:34:37 -08001806func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1807 if test.Properties.Gtest {
1808 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001809 }
Colin Crossca860ac2016-01-04 14:34:37 -08001810 deps = test.binaryLinker.deps(ctx, deps)
1811 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07001812}
1813
Colin Crossca860ac2016-01-04 14:34:37 -08001814type testInstaller struct {
1815 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08001816}
1817
Colin Crossca860ac2016-01-04 14:34:37 -08001818func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
1819 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
1820 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
1821 installer.baseInstaller.install(ctx, file)
1822}
1823
1824func NewTest(hod common.HostOrDeviceSupported) *Module {
1825 module := newModule(hod, common.MultilibBoth)
1826 module.compiler = &baseCompiler{}
1827 linker := &testLinker{}
1828 linker.Properties.Gtest = true
1829 module.linker = linker
1830 module.installer = &testInstaller{
1831 baseInstaller: baseInstaller{
1832 dir: "nativetest",
1833 dir64: "nativetest64",
1834 data: true,
1835 },
Dan Albertc403f7c2015-03-18 14:01:18 -07001836 }
Colin Crossca860ac2016-01-04 14:34:37 -08001837 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001838}
1839
Colin Crossca860ac2016-01-04 14:34:37 -08001840func testFactory() (blueprint.Module, []interface{}) {
1841 module := NewTest(common.HostAndDeviceSupported)
1842 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001843}
1844
Colin Crossca860ac2016-01-04 14:34:37 -08001845type benchmarkLinker struct {
1846 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07001847}
1848
Colin Crossca860ac2016-01-04 14:34:37 -08001849func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1850 deps = benchmark.binaryLinker.deps(ctx, deps)
1851 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
1852 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07001853}
1854
Colin Crossca860ac2016-01-04 14:34:37 -08001855func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
1856 module := newModule(hod, common.MultilibFirst)
1857 module.compiler = &baseCompiler{}
1858 module.linker = &benchmarkLinker{}
1859 module.installer = &baseInstaller{
1860 dir: "nativetest",
1861 dir64: "nativetest64",
1862 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07001863 }
Colin Crossca860ac2016-01-04 14:34:37 -08001864 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07001865}
1866
Colin Crossca860ac2016-01-04 14:34:37 -08001867func benchmarkFactory() (blueprint.Module, []interface{}) {
1868 module := NewBenchmark(common.HostAndDeviceSupported)
1869 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07001870}
1871
Colin Cross3f40fa42015-01-30 17:27:36 -08001872//
1873// Static library
1874//
1875
Colin Crossca860ac2016-01-04 14:34:37 -08001876func libraryStaticFactory() (blueprint.Module, []interface{}) {
1877 module := NewLibrary(common.HostAndDeviceSupported, false, true)
1878 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001879}
1880
1881//
1882// Shared libraries
1883//
1884
Colin Crossca860ac2016-01-04 14:34:37 -08001885func librarySharedFactory() (blueprint.Module, []interface{}) {
1886 module := NewLibrary(common.HostAndDeviceSupported, true, false)
1887 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001888}
1889
1890//
1891// Host static library
1892//
1893
Colin Crossca860ac2016-01-04 14:34:37 -08001894func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
1895 module := NewLibrary(common.HostSupported, false, true)
1896 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001897}
1898
1899//
1900// Host Shared libraries
1901//
1902
Colin Crossca860ac2016-01-04 14:34:37 -08001903func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
1904 module := NewLibrary(common.HostSupported, true, false)
1905 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001906}
1907
1908//
1909// Host Binaries
1910//
1911
Colin Crossca860ac2016-01-04 14:34:37 -08001912func binaryHostFactory() (blueprint.Module, []interface{}) {
1913 module := NewBinary(common.HostSupported)
1914 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001915}
1916
1917//
Colin Cross1f8f2342015-03-26 16:09:47 -07001918// Host Tests
1919//
1920
Colin Crossca860ac2016-01-04 14:34:37 -08001921func testHostFactory() (blueprint.Module, []interface{}) {
1922 module := NewTest(common.HostSupported)
1923 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07001924}
1925
1926//
Colin Cross2ba19d92015-05-07 15:44:20 -07001927// Host Benchmarks
1928//
1929
Colin Crossca860ac2016-01-04 14:34:37 -08001930func benchmarkHostFactory() (blueprint.Module, []interface{}) {
1931 module := NewBenchmark(common.HostSupported)
1932 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07001933}
1934
1935//
Colin Crosscfad1192015-11-02 16:43:11 -08001936// Defaults
1937//
Colin Crossca860ac2016-01-04 14:34:37 -08001938type Defaults struct {
Colin Crosscfad1192015-11-02 16:43:11 -08001939 common.AndroidModuleBase
1940 common.DefaultsModule
1941}
1942
Colin Crossca860ac2016-01-04 14:34:37 -08001943func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08001944}
1945
Colin Crossca860ac2016-01-04 14:34:37 -08001946func defaultsFactory() (blueprint.Module, []interface{}) {
1947 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08001948
1949 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08001950 &BaseProperties{},
1951 &BaseCompilerProperties{},
1952 &BaseLinkerProperties{},
1953 &LibraryCompilerProperties{},
1954 &LibraryLinkerProperties{},
1955 &BinaryLinkerProperties{},
1956 &TestLinkerProperties{},
1957 &UnusedProperties{},
1958 &StlProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08001959 }
1960
Dan Willemsen218f6562015-07-08 18:13:11 -07001961 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
1962 common.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08001963
1964 return common.InitDefaultsModule(module, module, propertyStructs...)
1965}
1966
1967//
Colin Cross3f40fa42015-01-30 17:27:36 -08001968// Device libraries shipped with gcc
1969//
1970
Colin Crossca860ac2016-01-04 14:34:37 -08001971type toolchainLibraryLinker struct {
1972 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08001973}
1974
Colin Crossca860ac2016-01-04 14:34:37 -08001975var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
1976
1977func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08001978 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08001979 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001980}
1981
Colin Crossca860ac2016-01-04 14:34:37 -08001982func (*toolchainLibraryLinker) buildStatic() bool {
1983 return true
1984}
Colin Cross3f40fa42015-01-30 17:27:36 -08001985
Colin Crossca860ac2016-01-04 14:34:37 -08001986func (*toolchainLibraryLinker) buildShared() bool {
1987 return false
1988}
1989
1990func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
1991 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1992 module.compiler = &baseCompiler{}
1993 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08001994 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08001995 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001996}
1997
Colin Crossca860ac2016-01-04 14:34:37 -08001998func (library *toolchainLibraryLinker) link(ctx ModuleContext,
1999 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002000
2001 libName := ctx.ModuleName() + staticLibraryExtension
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002002 outputFile := common.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002003
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002004 if flags.Clang {
2005 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2006 }
2007
Colin Crossca860ac2016-01-04 14:34:37 -08002008 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002009
2010 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002011
Colin Crossca860ac2016-01-04 14:34:37 -08002012 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002013}
2014
Dan Albertbe961682015-03-18 23:38:50 -07002015// NDK prebuilt libraries.
2016//
2017// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2018// either (with the exception of the shared STLs, which are installed to the app's directory rather
2019// than to the system image).
2020
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002021func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2022 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2023 version, toolchain.Name()))
Dan Albertbe961682015-03-18 23:38:50 -07002024}
2025
Dan Albertc3144b12015-04-28 18:17:56 -07002026func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002027 ext string, version string) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002028
2029 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2030 // We want to translate to just NAME.EXT
2031 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2032 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002033 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002034}
2035
Colin Crossca860ac2016-01-04 14:34:37 -08002036type ndkPrebuiltObjectLinker struct {
2037 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002038}
2039
Colin Crossca860ac2016-01-04 14:34:37 -08002040func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002041 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002042 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002043}
2044
Colin Crossca860ac2016-01-04 14:34:37 -08002045func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2046 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2047 module.linker = &ndkPrebuiltObjectLinker{}
2048 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002049}
2050
Colin Crossca860ac2016-01-04 14:34:37 -08002051func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2052 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002053 // A null build step, but it sets up the output path.
2054 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2055 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2056 }
2057
Colin Crossca860ac2016-01-04 14:34:37 -08002058 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002059}
2060
Colin Crossca860ac2016-01-04 14:34:37 -08002061type ndkPrebuiltLibraryLinker struct {
2062 libraryLinker
2063 Properties struct {
2064 Export_include_dirs []string `android:"arch_variant"`
2065 }
Dan Albertc3144b12015-04-28 18:17:56 -07002066}
2067
Colin Crossca860ac2016-01-04 14:34:37 -08002068var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2069var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002070
Colin Crossca860ac2016-01-04 14:34:37 -08002071func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
2072 return []interface{}{&ndk.Properties}
Dan Albertbe961682015-03-18 23:38:50 -07002073}
2074
Colin Crossca860ac2016-01-04 14:34:37 -08002075func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002076 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002077 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002078}
2079
Colin Crossca860ac2016-01-04 14:34:37 -08002080func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2081 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2082 linker := &ndkPrebuiltLibraryLinker{}
2083 linker.dynamicProperties.BuildShared = true
2084 module.linker = linker
2085 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002086}
2087
Colin Crossca860ac2016-01-04 14:34:37 -08002088func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2089 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002090 // A null build step, but it sets up the output path.
2091 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2092 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2093 }
2094
Colin Crossca860ac2016-01-04 14:34:37 -08002095 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2096 ndk.exportFlags = []string{common.JoinWithPrefix(includeDirs.Strings(), "-isystem ")}
Dan Albertbe961682015-03-18 23:38:50 -07002097
Colin Crossca860ac2016-01-04 14:34:37 -08002098 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2099 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002100}
2101
2102// The NDK STLs are slightly different from the prebuilt system libraries:
2103// * Are not specific to each platform version.
2104// * The libraries are not in a predictable location for each STL.
2105
Colin Crossca860ac2016-01-04 14:34:37 -08002106type ndkPrebuiltStlLinker struct {
2107 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002108}
2109
Colin Crossca860ac2016-01-04 14:34:37 -08002110func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2111 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2112 linker := &ndkPrebuiltStlLinker{}
2113 linker.dynamicProperties.BuildShared = true
2114 module.linker = linker
2115 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002116}
2117
Colin Crossca860ac2016-01-04 14:34:37 -08002118func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2119 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2120 linker := &ndkPrebuiltStlLinker{}
2121 linker.dynamicProperties.BuildStatic = true
2122 module.linker = linker
2123 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002124}
2125
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002126func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002127 gccVersion := toolchain.GccVersion()
2128 var libDir string
2129 switch stl {
2130 case "libstlport":
2131 libDir = "cxx-stl/stlport/libs"
2132 case "libc++":
2133 libDir = "cxx-stl/llvm-libc++/libs"
2134 case "libgnustl":
2135 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2136 }
2137
2138 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002139 ndkSrcRoot := "prebuilts/ndk/current/sources"
2140 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002141 }
2142
2143 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002144 return common.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002145}
2146
Colin Crossca860ac2016-01-04 14:34:37 -08002147func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2148 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002149 // A null build step, but it sets up the output path.
2150 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2151 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2152 }
2153
Colin Crossca860ac2016-01-04 14:34:37 -08002154 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2155 ndk.exportFlags = []string{includeDirsToFlags(includeDirs)}
Dan Albertbe961682015-03-18 23:38:50 -07002156
2157 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002158 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002159 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002160 libExt = staticLibraryExtension
2161 }
2162
2163 stlName := strings.TrimSuffix(libName, "_shared")
2164 stlName = strings.TrimSuffix(stlName, "_static")
2165 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002166 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002167}
2168
Colin Cross6362e272015-10-29 15:25:03 -07002169func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002170 if m, ok := mctx.Module().(*Module); ok {
2171 if m.linker != nil {
2172 if linker, ok := m.linker.(baseLinkerInterface); ok {
2173 var modules []blueprint.Module
2174 if linker.buildStatic() && linker.buildShared() {
2175 modules = mctx.CreateLocalVariations("static", "shared")
2176 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
Colin Cross7b106e42016-03-25 17:31:43 -07002177 modules[0].(*Module).installer = nil
Colin Crossca860ac2016-01-04 14:34:37 -08002178 modules[1].(*Module).linker.(baseLinkerInterface).setStatic(false)
2179 } else if linker.buildStatic() {
2180 modules = mctx.CreateLocalVariations("static")
2181 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
Colin Cross7b106e42016-03-25 17:31:43 -07002182 modules[0].(*Module).installer = nil
Colin Crossca860ac2016-01-04 14:34:37 -08002183 } else if linker.buildShared() {
2184 modules = mctx.CreateLocalVariations("shared")
2185 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2186 } else {
2187 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2188 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07002189
Colin Crossca860ac2016-01-04 14:34:37 -08002190 if _, ok := m.compiler.(*libraryCompiler); ok {
2191 reuseFrom := modules[0].(*Module).compiler.(*libraryCompiler)
2192 for _, m := range modules {
2193 m.(*Module).compiler.(*libraryCompiler).reuseFrom = reuseFrom
2194 }
2195 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002196 }
2197 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002198 }
2199}
Colin Cross74d1ec02015-04-28 13:30:13 -07002200
2201// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2202// modifies the slice contents in place, and returns a subslice of the original slice
2203func lastUniqueElements(list []string) []string {
2204 totalSkip := 0
2205 for i := len(list) - 1; i >= totalSkip; i-- {
2206 skip := 0
2207 for j := i - 1; j >= totalSkip; j-- {
2208 if list[i] == list[j] {
2209 skip++
2210 } else {
2211 list[j+skip] = list[j]
2212 }
2213 }
2214 totalSkip += skip
2215 }
2216 return list[totalSkip:]
2217}
Colin Cross06a931b2015-10-28 17:23:31 -07002218
2219var Bool = proptools.Bool