blob: 9f39588f772d551c29b55607bcb1b16a5f489c58 [file] [log] [blame]
Colin Cross5049f022015-03-18 13:28:46 -07001// Copyright 2015 Google Inc. All rights reserved.
Colin Cross3f40fa42015-01-30 17:27:36 -08002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17// This file contains the module types for compiling C/C++ for Android, and converts the properties
18// into the flags and filenames necessary to pass to the compiler. The final creation of the rules
19// is handled in builder.go
20
21import (
Colin Cross3f40fa42015-01-30 17:27:36 -080022 "fmt"
23 "path/filepath"
24 "strings"
25
Colin Cross97ba0732015-03-23 17:50:24 -070026 "github.com/google/blueprint"
Colin Cross06a931b2015-10-28 17:23:31 -070027 "github.com/google/blueprint/proptools"
Colin Cross97ba0732015-03-23 17:50:24 -070028
Colin Cross463a90e2015-06-17 14:20:06 -070029 "android/soong"
Colin Cross3f40fa42015-01-30 17:27:36 -080030 "android/soong/common"
Colin Cross5049f022015-03-18 13:28:46 -070031 "android/soong/genrule"
Colin Cross3f40fa42015-01-30 17:27:36 -080032)
33
Colin Cross463a90e2015-06-17 14:20:06 -070034func init() {
Colin Crossca860ac2016-01-04 14:34:37 -080035 soong.RegisterModuleType("cc_library_static", libraryStaticFactory)
36 soong.RegisterModuleType("cc_library_shared", librarySharedFactory)
37 soong.RegisterModuleType("cc_library", libraryFactory)
38 soong.RegisterModuleType("cc_object", objectFactory)
39 soong.RegisterModuleType("cc_binary", binaryFactory)
40 soong.RegisterModuleType("cc_test", testFactory)
41 soong.RegisterModuleType("cc_benchmark", benchmarkFactory)
42 soong.RegisterModuleType("cc_defaults", defaultsFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070043
Colin Crossca860ac2016-01-04 14:34:37 -080044 soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
45 soong.RegisterModuleType("ndk_prebuilt_library", ndkPrebuiltLibraryFactory)
46 soong.RegisterModuleType("ndk_prebuilt_object", ndkPrebuiltObjectFactory)
47 soong.RegisterModuleType("ndk_prebuilt_static_stl", ndkPrebuiltStaticStlFactory)
48 soong.RegisterModuleType("ndk_prebuilt_shared_stl", ndkPrebuiltSharedStlFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070049
Colin Crossca860ac2016-01-04 14:34:37 -080050 soong.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory)
51 soong.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory)
52 soong.RegisterModuleType("cc_binary_host", binaryHostFactory)
53 soong.RegisterModuleType("cc_test_host", testHostFactory)
54 soong.RegisterModuleType("cc_benchmark_host", benchmarkHostFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070055
56 // LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
57 // the Go initialization order because this package depends on common, so common's init
58 // functions will run first.
Colin Cross6362e272015-10-29 15:25:03 -070059 common.RegisterBottomUpMutator("link", linkageMutator)
60 common.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
61 common.RegisterBottomUpMutator("deps", depsMutator)
Colin Cross463a90e2015-06-17 14:20:06 -070062}
63
Colin Cross3f40fa42015-01-30 17:27:36 -080064var (
Colin Cross1332b002015-04-07 17:11:30 -070065 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
Colin Cross3f40fa42015-01-30 17:27:36 -080066
Dan Willemsen34cc69e2015-09-23 15:26:20 -070067 LibcRoot = pctx.SourcePathVariable("LibcRoot", "bionic/libc")
Colin Cross3f40fa42015-01-30 17:27:36 -080068)
69
70// Flags used by lots of devices. Putting them in package static variables will save bytes in
71// build.ninja so they aren't repeated for every file
72var (
73 commonGlobalCflags = []string{
74 "-DANDROID",
75 "-fmessage-length=0",
76 "-W",
77 "-Wall",
78 "-Wno-unused",
79 "-Winit-self",
80 "-Wpointer-arith",
81
82 // COMMON_RELEASE_CFLAGS
83 "-DNDEBUG",
84 "-UDEBUG",
85 }
86
87 deviceGlobalCflags = []string{
Dan Willemsen490fd492015-11-24 17:53:15 -080088 "-fdiagnostics-color",
89
Colin Cross3f40fa42015-01-30 17:27:36 -080090 // TARGET_ERROR_FLAGS
91 "-Werror=return-type",
92 "-Werror=non-virtual-dtor",
93 "-Werror=address",
94 "-Werror=sequence-point",
Dan Willemsena6084a32016-03-01 15:16:50 -080095 "-Werror=date-time",
Colin Cross3f40fa42015-01-30 17:27:36 -080096 }
97
98 hostGlobalCflags = []string{}
99
100 commonGlobalCppflags = []string{
101 "-Wsign-promo",
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700102 }
103
Dan Willemsenbe03f342016-03-03 17:21:04 -0800104 noOverrideGlobalCflags = []string{
105 "-Werror=int-to-pointer-cast",
106 "-Werror=pointer-to-int-cast",
107 }
108
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700109 illegalFlags = []string{
110 "-w",
Colin Cross3f40fa42015-01-30 17:27:36 -0800111 }
112)
113
114func init() {
Dan Willemsen0c38c5e2016-03-29 17:31:57 -0700115 if common.CurrentHostType() == common.Linux {
116 commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
117 }
118
Colin Cross3f40fa42015-01-30 17:27:36 -0800119 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
120 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
121 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800122 pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800123
124 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
125
126 pctx.StaticVariable("commonClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800127 strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800128 pctx.StaticVariable("deviceClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800129 strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800130 pctx.StaticVariable("hostClangGlobalCflags",
131 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800132 pctx.StaticVariable("noOverrideClangGlobalCflags",
133 strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
134
Tim Kilbournf2948142015-03-11 12:03:03 -0700135 pctx.StaticVariable("commonClangGlobalCppflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800136 strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800137
138 // Everything in this list is a crime against abstraction and dependency tracking.
139 // Do not add anything to this list.
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800140 pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700141 []string{
142 "system/core/include",
Dan Willemsen98f93c72016-03-01 15:27:03 -0800143 "system/media/audio/include",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700144 "hardware/libhardware/include",
145 "hardware/libhardware_legacy/include",
146 "hardware/ril/include",
147 "libnativehelper/include",
148 "frameworks/native/include",
149 "frameworks/native/opengl/include",
150 "frameworks/av/include",
151 "frameworks/base/include",
152 })
Dan Willemsene0378dd2016-01-07 17:42:34 -0800153 // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
154 // with this, since there is no associated library.
155 pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
156 []string{"libnativehelper/include/nativehelper"})
Colin Cross3f40fa42015-01-30 17:27:36 -0800157
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700158 pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
159 pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
160 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
161 return override, nil
162 }
163 return "${clangDefaultBase}", nil
164 })
165 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
166 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
167 return override, nil
168 }
Colin Cross7253e0b2016-03-21 15:12:34 -0700169 return "clang-2690385", nil
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700170 })
171 pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}/bin")
Colin Cross3f40fa42015-01-30 17:27:36 -0800172}
173
Colin Crossca860ac2016-01-04 14:34:37 -0800174type Deps struct {
175 SharedLibs, LateSharedLibs []string
176 StaticLibs, LateStaticLibs, WholeStaticLibs []string
Colin Crossc472d572015-03-17 15:06:21 -0700177
Colin Cross81413472016-04-11 14:37:39 -0700178 ObjFiles []string
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700179
180 Cflags, ReexportedCflags []string
Colin Cross21b9a242015-03-24 14:15:58 -0700181
Colin Cross97ba0732015-03-23 17:50:24 -0700182 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700183}
184
Colin Crossca860ac2016-01-04 14:34:37 -0800185type PathDeps struct {
186 SharedLibs, LateSharedLibs common.Paths
187 StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700188
189 ObjFiles common.Paths
190 WholeStaticLibObjFiles common.Paths
191
192 Cflags, ReexportedCflags []string
193
194 CrtBegin, CrtEnd common.OptionalPath
195}
196
Colin Crossca860ac2016-01-04 14:34:37 -0800197type Flags struct {
Colin Cross28344522015-04-22 13:07:53 -0700198 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
199 AsFlags []string // Flags that apply to assembly source files
200 CFlags []string // Flags that apply to C and C++ source files
201 ConlyFlags []string // Flags that apply to C source files
202 CppFlags []string // Flags that apply to C++ source files
203 YaccFlags []string // Flags that apply to Yacc source files
204 LdFlags []string // Flags that apply to linker command lines
205
206 Nocrt bool
207 Toolchain Toolchain
208 Clang bool
Colin Crossca860ac2016-01-04 14:34:37 -0800209
210 RequiredInstructionSet string
Colin Crossc472d572015-03-17 15:06:21 -0700211}
212
Colin Crossca860ac2016-01-04 14:34:37 -0800213type BaseCompilerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700214 // list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700215 Srcs []string `android:"arch_variant"`
216
217 // list of source files that should not be used to build the C/C++ module.
218 // This is most useful in the arch/multilib variants to remove non-common files
219 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700220
221 // list of module-specific flags that will be used for C and C++ compiles.
222 Cflags []string `android:"arch_variant"`
223
224 // list of module-specific flags that will be used for C++ compiles
225 Cppflags []string `android:"arch_variant"`
226
227 // list of module-specific flags that will be used for C compiles
228 Conlyflags []string `android:"arch_variant"`
229
230 // list of module-specific flags that will be used for .S compiles
231 Asflags []string `android:"arch_variant"`
232
Colin Crossca860ac2016-01-04 14:34:37 -0800233 // list of module-specific flags that will be used for C and C++ compiles when
234 // compiling with clang
235 Clang_cflags []string `android:"arch_variant"`
236
237 // list of module-specific flags that will be used for .S compiles when
238 // compiling with clang
239 Clang_asflags []string `android:"arch_variant"`
240
Colin Cross7d5136f2015-05-11 13:39:40 -0700241 // list of module-specific flags that will be used for .y and .yy compiles
242 Yaccflags []string
243
Colin Cross7d5136f2015-05-11 13:39:40 -0700244 // the instruction set architecture to use to compile the C/C++
245 // module.
246 Instruction_set string `android:"arch_variant"`
247
248 // list of directories relative to the root of the source tree that will
249 // be added to the include path using -I.
250 // If possible, don't use this. If adding paths from the current directory use
251 // local_include_dirs, if adding paths from other modules use export_include_dirs in
252 // that module.
253 Include_dirs []string `android:"arch_variant"`
254
Colin Cross39d97f22015-09-14 12:30:50 -0700255 // list of files relative to the root of the source tree that will be included
256 // using -include.
257 // If possible, don't use this.
258 Include_files []string `android:"arch_variant"`
259
Colin Cross7d5136f2015-05-11 13:39:40 -0700260 // list of directories relative to the Blueprints file that will
261 // be added to the include path using -I
262 Local_include_dirs []string `android:"arch_variant"`
263
Colin Cross39d97f22015-09-14 12:30:50 -0700264 // list of files relative to the Blueprints file that will be included
265 // using -include.
266 // If possible, don't use this.
267 Local_include_files []string `android:"arch_variant"`
268
Colin Crossca860ac2016-01-04 14:34:37 -0800269 // pass -frtti instead of -fno-rtti
270 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700271
Colin Crossca860ac2016-01-04 14:34:37 -0800272 Debug, Release struct {
273 // list of module-specific flags that will be used for C and C++ compiles in debug or
274 // release builds
275 Cflags []string `android:"arch_variant"`
276 } `android:"arch_variant"`
277}
Colin Cross7d5136f2015-05-11 13:39:40 -0700278
Colin Crossca860ac2016-01-04 14:34:37 -0800279type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700280 // list of modules whose object files should be linked into this module
281 // in their entirety. For static library modules, all of the .o files from the intermediate
282 // directory of the dependency will be linked into this modules .a file. For a shared library,
283 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
284 Whole_static_libs []string `android:"arch_variant"`
285
286 // list of modules that should be statically linked into this module.
287 Static_libs []string `android:"arch_variant"`
288
289 // list of modules that should be dynamically linked into this module.
290 Shared_libs []string `android:"arch_variant"`
291
Colin Crossca860ac2016-01-04 14:34:37 -0800292 // list of module-specific flags that will be used for all link steps
293 Ldflags []string `android:"arch_variant"`
294
295 // don't insert default compiler flags into asflags, cflags,
296 // cppflags, conlyflags, ldflags, or include_dirs
297 No_default_compiler_flags *bool
298
299 // list of system libraries that will be dynamically linked to
300 // shared library and executable modules. If unset, generally defaults to libc
301 // and libm. Set to [] to prevent linking against libc and libm.
302 System_shared_libs []string
303
Colin Cross7d5136f2015-05-11 13:39:40 -0700304 // allow the module to contain undefined symbols. By default,
305 // modules cannot contain undefined symbols that are not satisified by their immediate
306 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
307 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700308 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700309
Dan Willemsend67be222015-09-16 15:19:33 -0700310 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700311 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700312
Colin Cross7d5136f2015-05-11 13:39:40 -0700313 // -l arguments to pass to linker for host-provided shared libraries
314 Host_ldlibs []string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800315}
Colin Cross7d5136f2015-05-11 13:39:40 -0700316
Colin Crossca860ac2016-01-04 14:34:37 -0800317type LibraryCompilerProperties struct {
318 Static struct {
319 Srcs []string `android:"arch_variant"`
320 Exclude_srcs []string `android:"arch_variant"`
321 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700322 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800323 Shared struct {
324 Srcs []string `android:"arch_variant"`
325 Exclude_srcs []string `android:"arch_variant"`
326 Cflags []string `android:"arch_variant"`
327 } `android:"arch_variant"`
328}
329
330type LibraryLinkerProperties struct {
331 Static struct {
332 Whole_static_libs []string `android:"arch_variant"`
333 Static_libs []string `android:"arch_variant"`
334 Shared_libs []string `android:"arch_variant"`
335 } `android:"arch_variant"`
336 Shared struct {
337 Whole_static_libs []string `android:"arch_variant"`
338 Static_libs []string `android:"arch_variant"`
339 Shared_libs []string `android:"arch_variant"`
340 } `android:"arch_variant"`
341
342 // local file name to pass to the linker as --version_script
343 Version_script *string `android:"arch_variant"`
344 // local file name to pass to the linker as -unexported_symbols_list
345 Unexported_symbols_list *string `android:"arch_variant"`
346 // local file name to pass to the linker as -force_symbols_not_weak_list
347 Force_symbols_not_weak_list *string `android:"arch_variant"`
348 // local file name to pass to the linker as -force_symbols_weak_list
349 Force_symbols_weak_list *string `android:"arch_variant"`
350
351 // list of directories relative to the Blueprints file that will
352 // be added to the include path using -I for any module that links against this module
353 Export_include_dirs []string `android:"arch_variant"`
354
355 // don't link in crt_begin and crt_end. This flag should only be necessary for
356 // compiling crt or libc.
357 Nocrt *bool `android:"arch_variant"`
358}
359
360type BinaryLinkerProperties struct {
361 // compile executable with -static
362 Static_executable *bool
363
364 // set the name of the output
365 Stem string `android:"arch_variant"`
366
367 // append to the name of the output
368 Suffix string `android:"arch_variant"`
369
370 // if set, add an extra objcopy --prefix-symbols= step
371 Prefix_symbols string
372}
373
374type TestLinkerProperties struct {
375 // if set, build against the gtest library. Defaults to true.
376 Gtest bool
377
378 // Create a separate binary for each source file. Useful when there is
379 // global state that can not be torn down and reset between each test suite.
380 Test_per_src *bool
381}
382
Colin Cross81413472016-04-11 14:37:39 -0700383type ObjectLinkerProperties struct {
384 // names of other cc_object modules to link into this module using partial linking
385 Objs []string `android:"arch_variant"`
386}
387
Colin Crossca860ac2016-01-04 14:34:37 -0800388// Properties used to compile all C or C++ modules
389type BaseProperties struct {
390 // compile module with clang instead of gcc
391 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700392
393 // Minimum sdk version supported when compiling against the ndk
394 Sdk_version string
395
Colin Crossca860ac2016-01-04 14:34:37 -0800396 // don't insert default compiler flags into asflags, cflags,
397 // cppflags, conlyflags, ldflags, or include_dirs
398 No_default_compiler_flags *bool
399}
400
401type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700402 // install to a subdirectory of the default install path for the module
403 Relative_install_path string
404}
405
Colin Crossca860ac2016-01-04 14:34:37 -0800406type UnusedProperties struct {
Colin Crosscfad1192015-11-02 16:43:11 -0800407 Native_coverage *bool
408 Required []string
409 Sanitize []string `android:"arch_variant"`
410 Sanitize_recover []string
411 Strip string
412 Tags []string
413}
414
Colin Crossca860ac2016-01-04 14:34:37 -0800415type ModuleContextIntf interface {
416 module() *Module
417 static() bool
418 staticBinary() bool
419 clang() bool
420 toolchain() Toolchain
421 noDefaultCompilerFlags() bool
422 sdk() bool
423 sdkVersion() string
424}
425
426type ModuleContext interface {
427 common.AndroidModuleContext
428 ModuleContextIntf
429}
430
431type BaseModuleContext interface {
432 common.AndroidBaseContext
433 ModuleContextIntf
434}
435
436type Customizer interface {
437 CustomizeProperties(BaseModuleContext)
438 Properties() []interface{}
439}
440
441type feature interface {
442 begin(ctx BaseModuleContext)
443 deps(ctx BaseModuleContext, deps Deps) Deps
444 flags(ctx ModuleContext, flags Flags) Flags
445 props() []interface{}
446}
447
448type compiler interface {
449 feature
450 compile(ctx ModuleContext, flags Flags) common.Paths
451}
452
453type linker interface {
454 feature
455 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
456}
457
458type installer interface {
459 props() []interface{}
460 install(ctx ModuleContext, path common.Path)
461 inData() bool
462}
463
464// Module contains the properties and members used by all C/C++ module types, and implements
465// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
466// to construct the output file. Behavior can be customized with a Customizer interface
467type Module struct {
Colin Crossc472d572015-03-17 15:06:21 -0700468 common.AndroidModuleBase
Colin Crosscfad1192015-11-02 16:43:11 -0800469 common.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700470
Colin Crossca860ac2016-01-04 14:34:37 -0800471 Properties BaseProperties
472 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700473
Colin Crossca860ac2016-01-04 14:34:37 -0800474 // initialize before calling Init
475 hod common.HostOrDeviceSupported
476 multilib common.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700477
Colin Crossca860ac2016-01-04 14:34:37 -0800478 // delegates, initialize before calling Init
479 customizer Customizer
480 features []feature
481 compiler compiler
482 linker linker
483 installer installer
Colin Cross74d1ec02015-04-28 13:30:13 -0700484
Colin Crossca860ac2016-01-04 14:34:37 -0800485 deps Deps
486 outputFile common.OptionalPath
487
488 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700489}
490
Colin Crossca860ac2016-01-04 14:34:37 -0800491func (c *Module) Init() (blueprint.Module, []interface{}) {
492 props := []interface{}{&c.Properties, &c.unused}
493 if c.customizer != nil {
494 props = append(props, c.customizer.Properties()...)
495 }
496 if c.compiler != nil {
497 props = append(props, c.compiler.props()...)
498 }
499 if c.linker != nil {
500 props = append(props, c.linker.props()...)
501 }
502 if c.installer != nil {
503 props = append(props, c.installer.props()...)
504 }
505 for _, feature := range c.features {
506 props = append(props, feature.props()...)
507 }
Colin Crossc472d572015-03-17 15:06:21 -0700508
Colin Crossca860ac2016-01-04 14:34:37 -0800509 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700510
Colin Crossca860ac2016-01-04 14:34:37 -0800511 return common.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700512}
513
Colin Crossca860ac2016-01-04 14:34:37 -0800514type baseModuleContext struct {
515 common.AndroidBaseContext
516 moduleContextImpl
517}
518
519type moduleContext struct {
520 common.AndroidModuleContext
521 moduleContextImpl
522}
523
524type moduleContextImpl struct {
525 mod *Module
526 ctx BaseModuleContext
527}
528
529func (ctx *moduleContextImpl) module() *Module {
530 return ctx.mod
531}
532
533func (ctx *moduleContextImpl) clang() bool {
534 return ctx.mod.clang(ctx.ctx)
535}
536
537func (ctx *moduleContextImpl) toolchain() Toolchain {
538 return ctx.mod.toolchain(ctx.ctx)
539}
540
541func (ctx *moduleContextImpl) static() bool {
542 if ctx.mod.linker == nil {
543 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
544 }
545 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
546 return linker.static()
547 } else {
548 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
549 }
550}
551
552func (ctx *moduleContextImpl) staticBinary() bool {
553 if ctx.mod.linker == nil {
554 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
555 }
556 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
557 return linker.staticBinary()
558 } else {
559 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
560 }
561}
562
563func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
564 return Bool(ctx.mod.Properties.No_default_compiler_flags)
565}
566
567func (ctx *moduleContextImpl) sdk() bool {
568 return ctx.mod.Properties.Sdk_version != ""
569}
570
571func (ctx *moduleContextImpl) sdkVersion() string {
572 return ctx.mod.Properties.Sdk_version
573}
574
575func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
576 return &Module{
577 hod: hod,
578 multilib: multilib,
579 }
580}
581
582func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
583 module := newBaseModule(hod, multilib)
584 module.features = []feature{
585 &stlFeature{},
586 }
587 return module
588}
589
590func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
591 ctx := &moduleContext{
592 AndroidModuleContext: actx,
593 moduleContextImpl: moduleContextImpl{
594 mod: c,
595 },
596 }
597 ctx.ctx = ctx
598
599 flags := Flags{
600 Toolchain: c.toolchain(ctx),
601 Clang: c.clang(ctx),
602 }
603
604 if c.compiler != nil {
605 flags = c.compiler.flags(ctx, flags)
606 }
607 if c.linker != nil {
608 flags = c.linker.flags(ctx, flags)
609 }
610 for _, feature := range c.features {
611 flags = feature.flags(ctx, flags)
612 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800613 if ctx.Failed() {
614 return
615 }
616
Colin Crossca860ac2016-01-04 14:34:37 -0800617 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
618 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
619 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800620
Colin Crossca860ac2016-01-04 14:34:37 -0800621 // Optimization to reduce size of build.ninja
622 // Replace the long list of flags for each file with a module-local variable
623 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
624 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
625 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
626 flags.CFlags = []string{"$cflags"}
627 flags.CppFlags = []string{"$cppflags"}
628 flags.AsFlags = []string{"$asflags"}
629
630 deps := c.depsToPaths(actx, c.deps)
Colin Cross3f40fa42015-01-30 17:27:36 -0800631 if ctx.Failed() {
632 return
633 }
634
Colin Cross28344522015-04-22 13:07:53 -0700635 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700636
Colin Crossca860ac2016-01-04 14:34:37 -0800637 var objFiles common.Paths
638 if c.compiler != nil {
639 objFiles = c.compiler.compile(ctx, flags)
640 if ctx.Failed() {
641 return
642 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800643 }
644
Colin Crossca860ac2016-01-04 14:34:37 -0800645 if c.linker != nil {
646 outputFile := c.linker.link(ctx, flags, deps, objFiles)
647 if ctx.Failed() {
648 return
649 }
650 c.outputFile = common.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700651
Colin Crossca860ac2016-01-04 14:34:37 -0800652 if c.installer != nil {
653 c.installer.install(ctx, outputFile)
654 if ctx.Failed() {
655 return
656 }
657 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700658 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800659}
660
Colin Crossca860ac2016-01-04 14:34:37 -0800661func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
662 if c.cachedToolchain == nil {
663 arch := ctx.Arch()
664 hod := ctx.HostOrDevice()
665 ht := ctx.HostType()
666 factory := toolchainFactories[hod][ht][arch.ArchType]
667 if factory == nil {
668 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
669 return nil
670 }
671 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800672 }
Colin Crossca860ac2016-01-04 14:34:37 -0800673 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800674}
675
Colin Crossca860ac2016-01-04 14:34:37 -0800676func (c *Module) begin(ctx BaseModuleContext) {
677 if c.compiler != nil {
678 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700679 }
Colin Crossca860ac2016-01-04 14:34:37 -0800680 if c.linker != nil {
681 c.linker.begin(ctx)
682 }
683 for _, feature := range c.features {
684 feature.begin(ctx)
685 }
686}
687
688func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
689 ctx := &baseModuleContext{
690 AndroidBaseContext: actx,
691 moduleContextImpl: moduleContextImpl{
692 mod: c,
693 },
694 }
695 ctx.ctx = ctx
696
697 if c.customizer != nil {
698 c.customizer.CustomizeProperties(ctx)
699 }
700
701 c.begin(ctx)
702
703 c.deps = Deps{}
704
705 if c.compiler != nil {
706 c.deps = c.compiler.deps(ctx, c.deps)
707 }
708 if c.linker != nil {
709 c.deps = c.linker.deps(ctx, c.deps)
710 }
711 for _, feature := range c.features {
712 c.deps = feature.deps(ctx, c.deps)
713 }
714
715 c.deps.WholeStaticLibs = lastUniqueElements(c.deps.WholeStaticLibs)
716 c.deps.StaticLibs = lastUniqueElements(c.deps.StaticLibs)
717 c.deps.LateStaticLibs = lastUniqueElements(c.deps.LateStaticLibs)
718 c.deps.SharedLibs = lastUniqueElements(c.deps.SharedLibs)
719 c.deps.LateSharedLibs = lastUniqueElements(c.deps.LateSharedLibs)
720
721 staticLibs := c.deps.WholeStaticLibs
722 staticLibs = append(staticLibs, c.deps.StaticLibs...)
723 staticLibs = append(staticLibs, c.deps.LateStaticLibs...)
724 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticLibs...)
725
726 sharedLibs := c.deps.SharedLibs
727 sharedLibs = append(sharedLibs, c.deps.LateSharedLibs...)
728 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedLibs...)
729
Colin Cross81413472016-04-11 14:37:39 -0700730 actx.AddDependency(ctx.module(), c.deps.ObjFiles...)
731
Colin Crossca860ac2016-01-04 14:34:37 -0800732 if c.deps.CrtBegin != "" {
733 actx.AddDependency(ctx.module(), c.deps.CrtBegin)
734 }
735 if c.deps.CrtEnd != "" {
736 actx.AddDependency(ctx.module(), c.deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700737 }
Colin Cross6362e272015-10-29 15:25:03 -0700738}
Colin Cross21b9a242015-03-24 14:15:58 -0700739
Colin Cross6362e272015-10-29 15:25:03 -0700740func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800741 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700742 c.depsMutator(ctx)
743 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800744}
745
Colin Crossca860ac2016-01-04 14:34:37 -0800746func (c *Module) clang(ctx BaseModuleContext) bool {
747 clang := Bool(c.Properties.Clang)
748
749 if c.Properties.Clang == nil {
750 if ctx.Host() {
751 clang = true
752 }
753
754 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
755 clang = true
756 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800757 }
Colin Cross28344522015-04-22 13:07:53 -0700758
Colin Crossca860ac2016-01-04 14:34:37 -0800759 if !c.toolchain(ctx).ClangSupported() {
760 clang = false
761 }
762
763 return clang
764}
765
766func (c *Module) depsToPathsFromList(ctx common.AndroidModuleContext,
767 names []string) (modules []common.AndroidModule,
768 outputFiles common.Paths, exportedFlags []string) {
769
770 for _, n := range names {
771 found := false
772 ctx.VisitDirectDeps(func(m blueprint.Module) {
773 otherName := ctx.OtherModuleName(m)
774 if otherName != n {
775 return
776 }
777
778 if a, ok := m.(*Module); ok {
779 if !a.Enabled() {
780 ctx.ModuleErrorf("depends on disabled module %q", otherName)
781 return
782 }
783 if a.HostOrDevice() != ctx.HostOrDevice() {
784 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
785 otherName)
786 return
787 }
788
789 if outputFile := a.outputFile; outputFile.Valid() {
790 if found {
791 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
792 return
793 }
794 outputFiles = append(outputFiles, outputFile.Path())
795 modules = append(modules, a)
796 if i, ok := a.linker.(exportedFlagsProducer); ok {
797 exportedFlags = append(exportedFlags, i.exportedFlags()...)
798 }
799 found = true
800 } else {
801 ctx.ModuleErrorf("module %q missing output file", otherName)
802 return
803 }
804 } else {
805 ctx.ModuleErrorf("module %q not an android module", otherName)
806 return
807 }
808 })
809 if !found && !inList(n, ctx.GetMissingDependencies()) {
810 ctx.ModuleErrorf("unsatisified dependency on %q", n)
811 }
812 }
813
814 return modules, outputFiles, exportedFlags
815}
816
817// Convert dependency names to paths. Takes a Deps containing names and returns a PathDeps
818// containing paths
819func (c *Module) depsToPaths(ctx common.AndroidModuleContext, deps Deps) PathDeps {
820 var depPaths PathDeps
821 var newCflags []string
822
823 var wholeStaticLibModules []common.AndroidModule
824
825 wholeStaticLibModules, depPaths.WholeStaticLibs, newCflags =
826 c.depsToPathsFromList(ctx, deps.WholeStaticLibs)
827 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
828 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, newCflags...)
829
830 for _, am := range wholeStaticLibModules {
831 if m, ok := am.(*Module); ok {
832 if staticLib, ok := m.linker.(*libraryLinker); ok && staticLib.static() {
833 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
834 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
835 for i := range missingDeps {
836 missingDeps[i] += postfix
837 }
838 ctx.AddMissingDependencies(missingDeps)
839 }
840 depPaths.WholeStaticLibObjFiles =
841 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
842 } else {
843 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
844 }
845 } else {
846 ctx.ModuleErrorf("module %q not an android module", ctx.OtherModuleName(m))
847 }
848 }
849
850 _, depPaths.StaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.StaticLibs)
851 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
852
853 _, depPaths.LateStaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateStaticLibs)
854 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
855
856 _, depPaths.SharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.SharedLibs)
857 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
858
859 _, depPaths.LateSharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateSharedLibs)
860 depPaths.Cflags = append(depPaths.Cflags, newCflags...)
861
862 ctx.VisitDirectDeps(func(bm blueprint.Module) {
863 if m, ok := bm.(*Module); ok {
864 otherName := ctx.OtherModuleName(m)
865 if otherName == deps.CrtBegin {
866 depPaths.CrtBegin = m.outputFile
867 } else if otherName == deps.CrtEnd {
868 depPaths.CrtEnd = m.outputFile
869 } else {
870 output := m.outputFile
871 if output.Valid() {
872 depPaths.ObjFiles = append(depPaths.ObjFiles, output.Path())
873 } else {
874 ctx.ModuleErrorf("module %s did not provide an output file", otherName)
875 }
876 }
877 }
878 })
879
880 return depPaths
881}
882
883func (c *Module) InstallInData() bool {
884 if c.installer == nil {
885 return false
886 }
887 return c.installer.inData()
888}
889
890// Compiler
891
892type baseCompiler struct {
893 Properties BaseCompilerProperties
894}
895
896var _ compiler = (*baseCompiler)(nil)
897
898func (compiler *baseCompiler) props() []interface{} {
899 return []interface{}{&compiler.Properties}
900}
901
902func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
903func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps { return deps }
904
905// Create a Flags struct that collects the compile flags from global values,
906// per-target values, module type values, and per-module Blueprints properties
907func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
908 toolchain := ctx.toolchain()
909
910 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
911 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
912 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
913 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
914 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
915
Colin Cross28344522015-04-22 13:07:53 -0700916 // Include dir cflags
Colin Crossca860ac2016-01-04 14:34:37 -0800917 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
918 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -0700919 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -0700920 includeDirsToFlags(localIncludeDirs),
921 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -0700922
Colin Crossca860ac2016-01-04 14:34:37 -0800923 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
924 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -0700925
926 flags.GlobalFlags = append(flags.GlobalFlags,
927 includeFilesToFlags(rootIncludeFiles),
928 includeFilesToFlags(localIncludeFiles))
929
Colin Crossca860ac2016-01-04 14:34:37 -0800930 if !ctx.noDefaultCompilerFlags() {
931 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -0700932 flags.GlobalFlags = append(flags.GlobalFlags,
933 "${commonGlobalIncludes}",
934 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -0800935 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -0700936 }
937
938 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700939 "-I" + common.PathForModuleSrc(ctx).String(),
940 "-I" + common.PathForModuleOut(ctx).String(),
941 "-I" + common.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -0700942 }...)
943 }
944
Colin Crossca860ac2016-01-04 14:34:37 -0800945 instructionSet := compiler.Properties.Instruction_set
946 if flags.RequiredInstructionSet != "" {
947 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -0800948 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -0800949 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
950 if flags.Clang {
951 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
952 }
953 if err != nil {
954 ctx.ModuleErrorf("%s", err)
955 }
956
957 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -0800958 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -0800959
Colin Cross97ba0732015-03-23 17:50:24 -0700960 if flags.Clang {
961 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -0800962 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
963 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -0700964 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
965 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
966 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800967
968 target := "-target " + toolchain.ClangTriple()
969 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
970
Colin Cross97ba0732015-03-23 17:50:24 -0700971 flags.CFlags = append(flags.CFlags, target, gccPrefix)
972 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
973 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800974 }
975
Colin Crossca860ac2016-01-04 14:34:37 -0800976 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -0700977 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
978
Colin Cross97ba0732015-03-23 17:50:24 -0700979 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -0800980 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -0700981 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -0700982 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800983 toolchain.ClangCflags(),
984 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -0700985 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800986
987 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -0800988 } else {
Colin Cross97ba0732015-03-23 17:50:24 -0700989 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -0700990 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800991 toolchain.Cflags(),
992 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -0700993 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800994 }
995
Colin Cross7b66f152015-12-15 16:07:43 -0800996 if Bool(ctx.AConfig().ProductVariables.Brillo) {
997 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
998 }
999
Colin Crossf6566ed2015-03-24 11:13:38 -07001000 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001001 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001002 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001003 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001004 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001005 }
1006 }
1007
Colin Cross97ba0732015-03-23 17:50:24 -07001008 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001009
Colin Cross97ba0732015-03-23 17:50:24 -07001010 if flags.Clang {
1011 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001012 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001013 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001014 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001015 }
1016
Colin Crossc4bde762015-11-23 16:11:30 -08001017 if flags.Clang {
1018 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1019 } else {
1020 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001021 }
1022
Colin Crossca860ac2016-01-04 14:34:37 -08001023 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001024 if ctx.Host() && !flags.Clang {
1025 // The host GCC doesn't support C++14 (and is deprecated, so likely
1026 // never will). Build these modules with C++11.
1027 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1028 } else {
1029 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1030 }
1031 }
1032
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001033 // We can enforce some rules more strictly in the code we own. strict
1034 // indicates if this is code that we can be stricter with. If we have
1035 // rules that we want to apply to *our* code (but maybe can't for
1036 // vendor/device specific things), we could extend this to be a ternary
1037 // value.
1038 strict := true
1039 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1040 strict = false
1041 }
1042
1043 // Can be used to make some annotations stricter for code we can fix
1044 // (such as when we mark functions as deprecated).
1045 if strict {
1046 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1047 }
1048
Colin Cross3f40fa42015-01-30 17:27:36 -08001049 return flags
1050}
1051
Colin Crossca860ac2016-01-04 14:34:37 -08001052func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1053 // Compile files listed in c.Properties.Srcs into objects
1054 objFiles := compiler.compileObjs(ctx, flags, "", compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
1055 if ctx.Failed() {
1056 return nil
1057 }
1058
1059 var genSrcs common.Paths
1060 ctx.VisitDirectDeps(func(module blueprint.Module) {
1061 if gen, ok := module.(genrule.SourceFileGenerator); ok {
1062 genSrcs = append(genSrcs, gen.GeneratedSourceFiles()...)
1063 }
1064 })
1065
1066 if len(genSrcs) != 0 {
1067 genObjs := TransformSourceToObj(ctx, "", genSrcs, flagsToBuilderFlags(flags), nil)
1068 objFiles = append(objFiles, genObjs...)
1069 }
1070
1071 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001072}
1073
1074// Compile a list of source files into objects a specified subdirectory
Colin Crossca860ac2016-01-04 14:34:37 -08001075func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001076 subdir string, srcFiles, excludes []string) common.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001077
Colin Crossca860ac2016-01-04 14:34:37 -08001078 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001079
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001080 inputFiles := ctx.ExpandSources(srcFiles, excludes)
1081 srcPaths, deps := genSources(ctx, inputFiles, buildFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001082
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001083 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001084}
1085
Colin Crossca860ac2016-01-04 14:34:37 -08001086// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1087type baseLinker struct {
1088 Properties BaseLinkerProperties
1089 dynamicProperties struct {
1090 VariantIsShared bool `blueprint:"mutated"`
1091 VariantIsStatic bool `blueprint:"mutated"`
1092 VariantIsStaticBinary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001093 }
Dan Willemsend30e6102016-03-30 17:35:50 -07001094
1095 runPaths []string
Colin Cross3f40fa42015-01-30 17:27:36 -08001096}
1097
Dan Willemsend30e6102016-03-30 17:35:50 -07001098func (linker *baseLinker) begin(ctx BaseModuleContext) {
1099 if ctx.toolchain().Is64Bit() {
1100 linker.runPaths = []string{"../lib64", "lib64"}
1101 } else {
1102 linker.runPaths = []string{"../lib", "lib"}
1103 }
1104}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001105
Colin Crossca860ac2016-01-04 14:34:37 -08001106func (linker *baseLinker) props() []interface{} {
1107 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001108}
1109
Colin Crossca860ac2016-01-04 14:34:37 -08001110func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1111 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1112 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1113 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001114
Colin Cross74d1ec02015-04-28 13:30:13 -07001115 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001116 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001117 }
1118
Colin Crossf6566ed2015-03-24 11:13:38 -07001119 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001120 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001121 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1122 if !Bool(linker.Properties.No_libgcc) {
1123 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001124 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001125
Colin Crossca860ac2016-01-04 14:34:37 -08001126 if !linker.static() {
1127 if linker.Properties.System_shared_libs != nil {
1128 deps.LateSharedLibs = append(deps.LateSharedLibs,
1129 linker.Properties.System_shared_libs...)
1130 } else if !ctx.sdk() {
1131 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1132 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001133 }
Colin Cross577f6e42015-03-27 18:23:34 -07001134
Colin Crossca860ac2016-01-04 14:34:37 -08001135 if ctx.sdk() {
1136 version := ctx.sdkVersion()
1137 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001138 "ndk_libc."+version,
1139 "ndk_libm."+version,
1140 )
1141 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001142 }
1143
Colin Crossca860ac2016-01-04 14:34:37 -08001144 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001145}
1146
Colin Crossca860ac2016-01-04 14:34:37 -08001147func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1148 toolchain := ctx.toolchain()
1149
1150 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1151
1152 if !ctx.noDefaultCompilerFlags() {
1153 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1154 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1155 }
1156
1157 if flags.Clang {
1158 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1159 } else {
1160 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1161 }
1162
1163 if ctx.Host() {
1164 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1165 }
1166 }
1167
Dan Willemsend30e6102016-03-30 17:35:50 -07001168 if ctx.Host() && !linker.static() {
1169 rpath_prefix := `\$$ORIGIN/`
1170 if ctx.Darwin() {
1171 rpath_prefix = "@loader_path/"
1172 }
1173
1174 for _, rpath := range linker.runPaths {
1175 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1176 }
1177 }
1178
Dan Willemsene7174922016-03-30 17:33:52 -07001179 if flags.Clang {
1180 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1181 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001182 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1183 }
1184
1185 return flags
1186}
1187
1188func (linker *baseLinker) static() bool {
1189 return linker.dynamicProperties.VariantIsStatic
1190}
1191
1192func (linker *baseLinker) staticBinary() bool {
1193 return linker.dynamicProperties.VariantIsStaticBinary
1194}
1195
1196func (linker *baseLinker) setStatic(static bool) {
1197 linker.dynamicProperties.VariantIsStatic = static
1198}
1199
1200type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001201 // Returns true if the build options for the module have selected a static or shared build
1202 buildStatic() bool
1203 buildShared() bool
1204
1205 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001206 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001207
Colin Cross18b6dc52015-04-28 13:20:37 -07001208 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001209 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001210
1211 // Returns whether a module is a static binary
1212 staticBinary() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001213}
1214
Colin Crossca860ac2016-01-04 14:34:37 -08001215type exportedFlagsProducer interface {
Colin Cross28344522015-04-22 13:07:53 -07001216 exportedFlags() []string
Colin Cross3f40fa42015-01-30 17:27:36 -08001217}
1218
Colin Crossca860ac2016-01-04 14:34:37 -08001219type baseInstaller struct {
1220 Properties InstallerProperties
1221
1222 dir string
1223 dir64 string
1224 data bool
1225
Colin Crossa2344662016-03-24 13:14:12 -07001226 path common.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001227}
1228
1229var _ installer = (*baseInstaller)(nil)
1230
1231func (installer *baseInstaller) props() []interface{} {
1232 return []interface{}{&installer.Properties}
1233}
1234
1235func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1236 subDir := installer.dir
1237 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1238 subDir = installer.dir64
1239 }
1240 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1241 installer.path = ctx.InstallFile(dir, file)
1242}
1243
1244func (installer *baseInstaller) inData() bool {
1245 return installer.data
1246}
1247
Colin Cross3f40fa42015-01-30 17:27:36 -08001248//
1249// Combined static+shared libraries
1250//
1251
Colin Crossca860ac2016-01-04 14:34:37 -08001252type libraryCompiler struct {
1253 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001254
Colin Crossca860ac2016-01-04 14:34:37 -08001255 linker *libraryLinker
1256 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001257
Colin Crossca860ac2016-01-04 14:34:37 -08001258 // For reusing static library objects for shared library
1259 reuseFrom *libraryCompiler
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001260 reuseObjFiles common.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001261}
1262
Colin Crossca860ac2016-01-04 14:34:37 -08001263var _ compiler = (*libraryCompiler)(nil)
1264
1265func (library *libraryCompiler) props() []interface{} {
1266 props := library.baseCompiler.props()
1267 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001268}
1269
Colin Crossca860ac2016-01-04 14:34:37 -08001270func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1271 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001272
Dan Willemsen490fd492015-11-24 17:53:15 -08001273 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1274 // all code is position independent, and then those warnings get promoted to
1275 // errors.
1276 if ctx.HostType() != common.Windows {
1277 flags.CFlags = append(flags.CFlags, "-fPIC")
1278 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001279
Colin Crossca860ac2016-01-04 14:34:37 -08001280 if library.linker.static() {
1281 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001282 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001283 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001284 }
1285
Colin Crossca860ac2016-01-04 14:34:37 -08001286 return flags
1287}
1288
1289func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags) common.Paths {
1290 var objFiles common.Paths
1291
1292 if library.reuseFrom != library && library.reuseFrom.Properties.Static.Cflags == nil &&
1293 library.Properties.Shared.Cflags == nil {
1294 objFiles = append(common.Paths(nil), library.reuseFrom.reuseObjFiles...)
1295 } else {
1296 objFiles = library.baseCompiler.compile(ctx, flags)
1297 library.reuseObjFiles = objFiles
1298 }
1299
1300 if library.linker.static() {
1301 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
1302 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs)...)
1303 } else {
1304 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
1305 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs)...)
1306 }
1307
1308 return objFiles
1309}
1310
1311type libraryLinker struct {
1312 baseLinker
1313
1314 Properties LibraryLinkerProperties
1315
1316 dynamicProperties struct {
1317 BuildStatic bool `blueprint:"mutated"`
1318 BuildShared bool `blueprint:"mutated"`
1319 }
1320
1321 exportFlags []string
1322
1323 // If we're used as a whole_static_lib, our missing dependencies need
1324 // to be given
1325 wholeStaticMissingDeps []string
1326
1327 // For whole_static_libs
1328 objFiles common.Paths
1329}
1330
1331var _ linker = (*libraryLinker)(nil)
1332var _ exportedFlagsProducer = (*libraryLinker)(nil)
1333
1334func (library *libraryLinker) props() []interface{} {
1335 props := library.baseLinker.props()
1336 return append(props, &library.Properties, &library.dynamicProperties)
1337}
1338
1339func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1340 flags = library.baseLinker.flags(ctx, flags)
1341
1342 flags.Nocrt = Bool(library.Properties.Nocrt)
1343
1344 if !library.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001345 libName := ctx.ModuleName()
1346 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1347 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001348 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001349 sharedFlag = "-shared"
1350 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001351 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001352 flags.LdFlags = append(flags.LdFlags,
1353 "-nostdlib",
1354 "-Wl,--gc-sections",
1355 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001356 }
Colin Cross97ba0732015-03-23 17:50:24 -07001357
Colin Cross0af4b842015-04-30 16:36:18 -07001358 if ctx.Darwin() {
1359 flags.LdFlags = append(flags.LdFlags,
1360 "-dynamiclib",
1361 "-single_module",
1362 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001363 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001364 )
1365 } else {
1366 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001367 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001368 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001369 )
1370 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001371 }
Colin Cross97ba0732015-03-23 17:50:24 -07001372
1373 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001374}
1375
Colin Crossca860ac2016-01-04 14:34:37 -08001376func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1377 deps = library.baseLinker.deps(ctx, deps)
1378 if library.static() {
1379 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1380 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1381 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1382 } else {
1383 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1384 if !ctx.sdk() {
1385 deps.CrtBegin = "crtbegin_so"
1386 deps.CrtEnd = "crtend_so"
1387 } else {
1388 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1389 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1390 }
1391 }
1392 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1393 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1394 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1395 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001396
Colin Crossca860ac2016-01-04 14:34:37 -08001397 return deps
1398}
Colin Cross3f40fa42015-01-30 17:27:36 -08001399
Colin Crossca860ac2016-01-04 14:34:37 -08001400func (library *libraryLinker) exportedFlags() []string {
1401 return library.exportFlags
1402}
1403
1404func (library *libraryLinker) linkStatic(ctx ModuleContext,
1405 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1406
Colin Cross21b9a242015-03-24 14:15:58 -07001407 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Crossca860ac2016-01-04 14:34:37 -08001408 library.objFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001409
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001410 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001411
Colin Cross0af4b842015-04-30 16:36:18 -07001412 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001413 TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001414 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001415 TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001416 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001417
Colin Crossca860ac2016-01-04 14:34:37 -08001418 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001419
1420 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001421
1422 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001423}
1424
Colin Crossca860ac2016-01-04 14:34:37 -08001425func (library *libraryLinker) linkShared(ctx ModuleContext,
1426 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001427
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001428 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
Colin Cross3f40fa42015-01-30 17:27:36 -08001429
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001430 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001431
Colin Crossca860ac2016-01-04 14:34:37 -08001432 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1433 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1434 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1435 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001436 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001437 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001438 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001439 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001440 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001441 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001442 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1443 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001444 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001445 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1446 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001447 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001448 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1449 }
1450 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001451 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001452 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1453 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001454 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001455 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001456 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001457 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001458 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001459 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001460 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001461 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001462 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001463 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001464 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001465 }
Colin Crossaee540a2015-07-06 17:48:31 -07001466 }
1467
Colin Crossca860ac2016-01-04 14:34:37 -08001468 sharedLibs := deps.SharedLibs
1469 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001470
Colin Crossca860ac2016-01-04 14:34:37 -08001471 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1472 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1473 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile)
1474
1475 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001476}
1477
Colin Crossca860ac2016-01-04 14:34:37 -08001478func (library *libraryLinker) link(ctx ModuleContext,
1479 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001480
Colin Crossca860ac2016-01-04 14:34:37 -08001481 var out common.Path
1482 if library.static() {
1483 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001484 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001485 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001486 }
1487
Colin Crossca860ac2016-01-04 14:34:37 -08001488 includeDirs := common.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)
1489 library.exportFlags = []string{includeDirsToFlags(includeDirs)}
1490 library.exportFlags = append(library.exportFlags, deps.ReexportedCflags...)
1491
1492 return out
1493}
1494
1495func (library *libraryLinker) buildStatic() bool {
1496 return library.dynamicProperties.BuildStatic
1497}
1498
1499func (library *libraryLinker) buildShared() bool {
1500 return library.dynamicProperties.BuildShared
1501}
1502
1503func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1504 return library.wholeStaticMissingDeps
1505}
1506
1507type libraryInstaller struct {
1508 baseInstaller
1509
1510 linker *libraryLinker
1511}
1512
1513func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1514 if !library.linker.static() {
1515 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001516 }
1517}
1518
Colin Crossca860ac2016-01-04 14:34:37 -08001519func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1520 module := newModule(hod, common.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001521
Colin Crossca860ac2016-01-04 14:34:37 -08001522 linker := &libraryLinker{}
1523 linker.dynamicProperties.BuildShared = shared
1524 linker.dynamicProperties.BuildStatic = static
1525 module.linker = linker
1526
1527 module.compiler = &libraryCompiler{
1528 linker: linker,
1529 }
1530 module.installer = &libraryInstaller{
1531 baseInstaller: baseInstaller{
1532 dir: "lib",
1533 dir64: "lib64",
1534 },
1535 linker: linker,
Dan Albertc403f7c2015-03-18 14:01:18 -07001536 }
1537
Colin Crossca860ac2016-01-04 14:34:37 -08001538 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001539}
1540
Colin Crossca860ac2016-01-04 14:34:37 -08001541func libraryFactory() (blueprint.Module, []interface{}) {
1542 module := NewLibrary(common.HostAndDeviceSupported, true, true)
1543 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001544}
1545
Colin Cross3f40fa42015-01-30 17:27:36 -08001546//
1547// Objects (for crt*.o)
1548//
1549
Colin Crossca860ac2016-01-04 14:34:37 -08001550type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001551 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001552}
1553
Colin Crossca860ac2016-01-04 14:34:37 -08001554func objectFactory() (blueprint.Module, []interface{}) {
1555 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1556 module.compiler = &baseCompiler{}
1557 module.linker = &objectLinker{}
1558 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001559}
1560
Colin Cross81413472016-04-11 14:37:39 -07001561func (object *objectLinker) props() []interface{} {
1562 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001563}
1564
Colin Crossca860ac2016-01-04 14:34:37 -08001565func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001566
Colin Cross81413472016-04-11 14:37:39 -07001567func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1568 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001569 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001570}
1571
Colin Crossca860ac2016-01-04 14:34:37 -08001572func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001573 if flags.Clang {
1574 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1575 } else {
1576 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1577 }
1578
Colin Crossca860ac2016-01-04 14:34:37 -08001579 return flags
1580}
1581
1582func (object *objectLinker) link(ctx ModuleContext,
1583 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001584
Colin Cross97ba0732015-03-23 17:50:24 -07001585 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001586
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001587 var outputFile common.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001588 if len(objFiles) == 1 {
1589 outputFile = objFiles[0]
1590 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001591 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001592 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001593 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001594 }
1595
Colin Cross3f40fa42015-01-30 17:27:36 -08001596 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001597 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001598}
1599
Colin Cross3f40fa42015-01-30 17:27:36 -08001600//
1601// Executables
1602//
1603
Colin Crossca860ac2016-01-04 14:34:37 -08001604type binaryLinker struct {
1605 baseLinker
Colin Cross7d5136f2015-05-11 13:39:40 -07001606
Colin Crossca860ac2016-01-04 14:34:37 -08001607 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001608
Colin Crossca860ac2016-01-04 14:34:37 -08001609 hostToolPath common.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001610}
1611
Colin Crossca860ac2016-01-04 14:34:37 -08001612var _ linker = (*binaryLinker)(nil)
1613
1614func (binary *binaryLinker) props() []interface{} {
1615 return append(binary.baseLinker.props(), &binary.Properties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001616}
1617
Colin Crossca860ac2016-01-04 14:34:37 -08001618func (binary *binaryLinker) buildStatic() bool {
1619 return Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001620}
1621
Colin Crossca860ac2016-01-04 14:34:37 -08001622func (binary *binaryLinker) buildShared() bool {
1623 return !Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001624}
1625
Colin Crossca860ac2016-01-04 14:34:37 -08001626func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001627 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001628 if binary.Properties.Stem != "" {
1629 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001630 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001631
Colin Crossca860ac2016-01-04 14:34:37 -08001632 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001633}
1634
Colin Crossca860ac2016-01-04 14:34:37 -08001635func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1636 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001637 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001638 if !ctx.sdk() {
1639 if Bool(binary.Properties.Static_executable) {
1640 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001641 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001642 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001643 }
Colin Crossca860ac2016-01-04 14:34:37 -08001644 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001645 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001646 if Bool(binary.Properties.Static_executable) {
1647 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001648 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001649 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001650 }
Colin Crossca860ac2016-01-04 14:34:37 -08001651 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001652 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001653
Colin Crossca860ac2016-01-04 14:34:37 -08001654 if Bool(binary.Properties.Static_executable) {
1655 if inList("libc++_static", deps.StaticLibs) {
1656 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001657 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001658 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1659 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1660 // move them to the beginning of deps.LateStaticLibs
1661 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001662 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001663 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001664 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001665 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001666 }
Colin Crossca860ac2016-01-04 14:34:37 -08001667
1668 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1669 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1670 "from static libs or set static_executable: true")
1671 }
1672 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001673}
1674
Colin Crossca860ac2016-01-04 14:34:37 -08001675func NewBinary(hod common.HostOrDeviceSupported) *Module {
1676 module := newModule(hod, common.MultilibFirst)
1677 module.compiler = &baseCompiler{}
1678 module.linker = &binaryLinker{}
1679 module.installer = &baseInstaller{
1680 dir: "bin",
1681 }
1682 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001683}
1684
Colin Crossca860ac2016-01-04 14:34:37 -08001685func binaryFactory() (blueprint.Module, []interface{}) {
1686 module := NewBinary(common.HostAndDeviceSupported)
1687 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001688}
1689
Colin Crossca860ac2016-01-04 14:34:37 -08001690func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001691 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001692 binary.Properties.Static_executable = proptools.BoolPtr(false)
Colin Cross0af4b842015-04-30 16:36:18 -07001693 }
Colin Crossca860ac2016-01-04 14:34:37 -08001694 if Bool(binary.Properties.Static_executable) {
1695 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001696 }
1697}
1698
Colin Crossca860ac2016-01-04 14:34:37 -08001699func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1700 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001701
Dan Willemsen490fd492015-11-24 17:53:15 -08001702 if ctx.Host() {
1703 flags.LdFlags = append(flags.LdFlags, "-pie")
1704 if ctx.HostType() == common.Windows {
1705 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1706 }
1707 }
1708
1709 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1710 // all code is position independent, and then those warnings get promoted to
1711 // errors.
1712 if ctx.HostType() != common.Windows {
1713 flags.CFlags = append(flags.CFlags, "-fpie")
1714 }
Colin Cross97ba0732015-03-23 17:50:24 -07001715
Colin Crossf6566ed2015-03-24 11:13:38 -07001716 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001717 if Bool(binary.Properties.Static_executable) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001718 // Clang driver needs -static to create static executable.
1719 // However, bionic/linker uses -shared to overwrite.
1720 // Linker for x86 targets does not allow coexistance of -static and -shared,
1721 // so we add -static only if -shared is not used.
1722 if !inList("-shared", flags.LdFlags) {
1723 flags.LdFlags = append(flags.LdFlags, "-static")
1724 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001725
Colin Crossed4cf0b2015-03-26 14:43:45 -07001726 flags.LdFlags = append(flags.LdFlags,
1727 "-nostdlib",
1728 "-Bstatic",
1729 "-Wl,--gc-sections",
1730 )
1731
1732 } else {
1733 linker := "/system/bin/linker"
1734 if flags.Toolchain.Is64Bit() {
Colin Crossca860ac2016-01-04 14:34:37 -08001735 linker += "64"
Colin Crossed4cf0b2015-03-26 14:43:45 -07001736 }
1737
1738 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001739 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001740 "-nostdlib",
1741 "-Bdynamic",
1742 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1743 "-Wl,--gc-sections",
1744 "-Wl,-z,nocopyreloc",
1745 )
1746 }
Colin Cross0af4b842015-04-30 16:36:18 -07001747 } else if ctx.Darwin() {
1748 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001749 }
1750
Colin Cross97ba0732015-03-23 17:50:24 -07001751 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001752}
1753
Colin Crossca860ac2016-01-04 14:34:37 -08001754func (binary *binaryLinker) link(ctx ModuleContext,
1755 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001756
Colin Crossca860ac2016-01-04 14:34:37 -08001757 outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
1758 if ctx.HostOrDevice().Host() {
1759 binary.hostToolPath = common.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001760 }
Colin Crossca860ac2016-01-04 14:34:37 -08001761 ret := outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001762
Colin Crossca860ac2016-01-04 14:34:37 -08001763 if binary.Properties.Prefix_symbols != "" {
Colin Crossbfae8852015-03-26 14:44:11 -07001764 afterPrefixSymbols := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001765 outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate")
1766 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1767 flagsToBuilderFlags(flags), afterPrefixSymbols)
Colin Crossbfae8852015-03-26 14:44:11 -07001768 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001769
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001770 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001771
Colin Crossca860ac2016-01-04 14:34:37 -08001772 sharedLibs := deps.SharedLibs
1773 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1774
1775 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001776 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Crossca860ac2016-01-04 14:34:37 -08001777 flagsToBuilderFlags(flags), outputFile)
1778
1779 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001780}
Colin Cross3f40fa42015-01-30 17:27:36 -08001781
Colin Crossca860ac2016-01-04 14:34:37 -08001782func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1783 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001784}
1785
Colin Cross6362e272015-10-29 15:25:03 -07001786func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08001787 if m, ok := mctx.Module().(*Module); ok {
1788 if test, ok := m.linker.(*testLinker); ok {
1789 if Bool(test.Properties.Test_per_src) {
1790 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
1791 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1792 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
1793 }
1794 tests := mctx.CreateLocalVariations(testNames...)
1795 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1796 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
1797 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
1798 }
Colin Cross6002e052015-09-16 16:00:08 -07001799 }
1800 }
1801 }
Colin Cross7d5136f2015-05-11 13:39:40 -07001802}
1803
Colin Crossca860ac2016-01-04 14:34:37 -08001804type testLinker struct {
1805 binaryLinker
1806 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001807}
1808
Dan Willemsend30e6102016-03-30 17:35:50 -07001809func (test *testLinker) begin(ctx BaseModuleContext) {
1810 test.binaryLinker.begin(ctx)
1811
1812 runpath := "../../lib"
1813 if ctx.toolchain().Is64Bit() {
1814 runpath += "64"
1815 }
1816 test.runPaths = append([]string{runpath}, test.runPaths...)
1817}
1818
Colin Crossca860ac2016-01-04 14:34:37 -08001819func (test *testLinker) props() []interface{} {
1820 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07001821}
1822
Colin Crossca860ac2016-01-04 14:34:37 -08001823func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
1824 flags = test.binaryLinker.flags(ctx, flags)
1825
1826 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001827 return flags
1828 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001829
Colin Cross97ba0732015-03-23 17:50:24 -07001830 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001831 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001832 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001833
1834 if ctx.HostType() == common.Windows {
1835 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
1836 } else {
1837 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
1838 flags.LdFlags = append(flags.LdFlags, "-lpthread")
1839 }
1840 } else {
1841 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07001842 }
1843
1844 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross28344522015-04-22 13:07:53 -07001845 flags.CFlags = append(flags.CFlags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001846 "-I"+common.PathForSource(ctx, "external/gtest/include").String())
Dan Albertc403f7c2015-03-18 14:01:18 -07001847
Colin Cross21b9a242015-03-24 14:15:58 -07001848 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07001849}
1850
Colin Crossca860ac2016-01-04 14:34:37 -08001851func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1852 if test.Properties.Gtest {
1853 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001854 }
Colin Crossca860ac2016-01-04 14:34:37 -08001855 deps = test.binaryLinker.deps(ctx, deps)
1856 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07001857}
1858
Colin Crossca860ac2016-01-04 14:34:37 -08001859type testInstaller struct {
1860 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08001861}
1862
Colin Crossca860ac2016-01-04 14:34:37 -08001863func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
1864 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
1865 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
1866 installer.baseInstaller.install(ctx, file)
1867}
1868
1869func NewTest(hod common.HostOrDeviceSupported) *Module {
1870 module := newModule(hod, common.MultilibBoth)
1871 module.compiler = &baseCompiler{}
1872 linker := &testLinker{}
1873 linker.Properties.Gtest = true
1874 module.linker = linker
1875 module.installer = &testInstaller{
1876 baseInstaller: baseInstaller{
1877 dir: "nativetest",
1878 dir64: "nativetest64",
1879 data: true,
1880 },
Dan Albertc403f7c2015-03-18 14:01:18 -07001881 }
Colin Crossca860ac2016-01-04 14:34:37 -08001882 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001883}
1884
Colin Crossca860ac2016-01-04 14:34:37 -08001885func testFactory() (blueprint.Module, []interface{}) {
1886 module := NewTest(common.HostAndDeviceSupported)
1887 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001888}
1889
Colin Crossca860ac2016-01-04 14:34:37 -08001890type benchmarkLinker struct {
1891 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07001892}
1893
Colin Crossca860ac2016-01-04 14:34:37 -08001894func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1895 deps = benchmark.binaryLinker.deps(ctx, deps)
1896 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
1897 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07001898}
1899
Colin Crossca860ac2016-01-04 14:34:37 -08001900func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
1901 module := newModule(hod, common.MultilibFirst)
1902 module.compiler = &baseCompiler{}
1903 module.linker = &benchmarkLinker{}
1904 module.installer = &baseInstaller{
1905 dir: "nativetest",
1906 dir64: "nativetest64",
1907 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07001908 }
Colin Crossca860ac2016-01-04 14:34:37 -08001909 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07001910}
1911
Colin Crossca860ac2016-01-04 14:34:37 -08001912func benchmarkFactory() (blueprint.Module, []interface{}) {
1913 module := NewBenchmark(common.HostAndDeviceSupported)
1914 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07001915}
1916
Colin Cross3f40fa42015-01-30 17:27:36 -08001917//
1918// Static library
1919//
1920
Colin Crossca860ac2016-01-04 14:34:37 -08001921func libraryStaticFactory() (blueprint.Module, []interface{}) {
1922 module := NewLibrary(common.HostAndDeviceSupported, false, true)
1923 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001924}
1925
1926//
1927// Shared libraries
1928//
1929
Colin Crossca860ac2016-01-04 14:34:37 -08001930func librarySharedFactory() (blueprint.Module, []interface{}) {
1931 module := NewLibrary(common.HostAndDeviceSupported, true, false)
1932 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001933}
1934
1935//
1936// Host static library
1937//
1938
Colin Crossca860ac2016-01-04 14:34:37 -08001939func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
1940 module := NewLibrary(common.HostSupported, false, true)
1941 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001942}
1943
1944//
1945// Host Shared libraries
1946//
1947
Colin Crossca860ac2016-01-04 14:34:37 -08001948func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
1949 module := NewLibrary(common.HostSupported, true, false)
1950 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001951}
1952
1953//
1954// Host Binaries
1955//
1956
Colin Crossca860ac2016-01-04 14:34:37 -08001957func binaryHostFactory() (blueprint.Module, []interface{}) {
1958 module := NewBinary(common.HostSupported)
1959 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001960}
1961
1962//
Colin Cross1f8f2342015-03-26 16:09:47 -07001963// Host Tests
1964//
1965
Colin Crossca860ac2016-01-04 14:34:37 -08001966func testHostFactory() (blueprint.Module, []interface{}) {
1967 module := NewTest(common.HostSupported)
1968 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07001969}
1970
1971//
Colin Cross2ba19d92015-05-07 15:44:20 -07001972// Host Benchmarks
1973//
1974
Colin Crossca860ac2016-01-04 14:34:37 -08001975func benchmarkHostFactory() (blueprint.Module, []interface{}) {
1976 module := NewBenchmark(common.HostSupported)
1977 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07001978}
1979
1980//
Colin Crosscfad1192015-11-02 16:43:11 -08001981// Defaults
1982//
Colin Crossca860ac2016-01-04 14:34:37 -08001983type Defaults struct {
Colin Crosscfad1192015-11-02 16:43:11 -08001984 common.AndroidModuleBase
1985 common.DefaultsModule
1986}
1987
Colin Crossca860ac2016-01-04 14:34:37 -08001988func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08001989}
1990
Colin Crossca860ac2016-01-04 14:34:37 -08001991func defaultsFactory() (blueprint.Module, []interface{}) {
1992 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08001993
1994 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08001995 &BaseProperties{},
1996 &BaseCompilerProperties{},
1997 &BaseLinkerProperties{},
1998 &LibraryCompilerProperties{},
1999 &LibraryLinkerProperties{},
2000 &BinaryLinkerProperties{},
2001 &TestLinkerProperties{},
2002 &UnusedProperties{},
2003 &StlProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002004 }
2005
Dan Willemsen218f6562015-07-08 18:13:11 -07002006 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
2007 common.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002008
2009 return common.InitDefaultsModule(module, module, propertyStructs...)
2010}
2011
2012//
Colin Cross3f40fa42015-01-30 17:27:36 -08002013// Device libraries shipped with gcc
2014//
2015
Colin Crossca860ac2016-01-04 14:34:37 -08002016type toolchainLibraryLinker struct {
2017 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002018}
2019
Colin Crossca860ac2016-01-04 14:34:37 -08002020var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2021
2022func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002023 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002024 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002025}
2026
Colin Crossca860ac2016-01-04 14:34:37 -08002027func (*toolchainLibraryLinker) buildStatic() bool {
2028 return true
2029}
Colin Cross3f40fa42015-01-30 17:27:36 -08002030
Colin Crossca860ac2016-01-04 14:34:37 -08002031func (*toolchainLibraryLinker) buildShared() bool {
2032 return false
2033}
2034
2035func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
2036 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2037 module.compiler = &baseCompiler{}
2038 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002039 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002040 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002041}
2042
Colin Crossca860ac2016-01-04 14:34:37 -08002043func (library *toolchainLibraryLinker) link(ctx ModuleContext,
2044 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002045
2046 libName := ctx.ModuleName() + staticLibraryExtension
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002047 outputFile := common.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002048
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002049 if flags.Clang {
2050 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2051 }
2052
Colin Crossca860ac2016-01-04 14:34:37 -08002053 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002054
2055 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002056
Colin Crossca860ac2016-01-04 14:34:37 -08002057 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002058}
2059
Dan Albertbe961682015-03-18 23:38:50 -07002060// NDK prebuilt libraries.
2061//
2062// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2063// either (with the exception of the shared STLs, which are installed to the app's directory rather
2064// than to the system image).
2065
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002066func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2067 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2068 version, toolchain.Name()))
Dan Albertbe961682015-03-18 23:38:50 -07002069}
2070
Dan Albertc3144b12015-04-28 18:17:56 -07002071func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002072 ext string, version string) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002073
2074 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2075 // We want to translate to just NAME.EXT
2076 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2077 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002078 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002079}
2080
Colin Crossca860ac2016-01-04 14:34:37 -08002081type ndkPrebuiltObjectLinker struct {
2082 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002083}
2084
Colin Crossca860ac2016-01-04 14:34:37 -08002085func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002086 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002087 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002088}
2089
Colin Crossca860ac2016-01-04 14:34:37 -08002090func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2091 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2092 module.linker = &ndkPrebuiltObjectLinker{}
2093 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002094}
2095
Colin Crossca860ac2016-01-04 14:34:37 -08002096func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2097 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002098 // A null build step, but it sets up the output path.
2099 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2100 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2101 }
2102
Colin Crossca860ac2016-01-04 14:34:37 -08002103 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002104}
2105
Colin Crossca860ac2016-01-04 14:34:37 -08002106type ndkPrebuiltLibraryLinker struct {
2107 libraryLinker
2108 Properties struct {
2109 Export_include_dirs []string `android:"arch_variant"`
2110 }
Dan Albertc3144b12015-04-28 18:17:56 -07002111}
2112
Colin Crossca860ac2016-01-04 14:34:37 -08002113var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2114var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002115
Colin Crossca860ac2016-01-04 14:34:37 -08002116func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
2117 return []interface{}{&ndk.Properties}
Dan Albertbe961682015-03-18 23:38:50 -07002118}
2119
Colin Crossca860ac2016-01-04 14:34:37 -08002120func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002121 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002122 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002123}
2124
Colin Crossca860ac2016-01-04 14:34:37 -08002125func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2126 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2127 linker := &ndkPrebuiltLibraryLinker{}
2128 linker.dynamicProperties.BuildShared = true
2129 module.linker = linker
2130 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002131}
2132
Colin Crossca860ac2016-01-04 14:34:37 -08002133func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2134 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002135 // A null build step, but it sets up the output path.
2136 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2137 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2138 }
2139
Colin Crossca860ac2016-01-04 14:34:37 -08002140 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2141 ndk.exportFlags = []string{common.JoinWithPrefix(includeDirs.Strings(), "-isystem ")}
Dan Albertbe961682015-03-18 23:38:50 -07002142
Colin Crossca860ac2016-01-04 14:34:37 -08002143 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2144 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002145}
2146
2147// The NDK STLs are slightly different from the prebuilt system libraries:
2148// * Are not specific to each platform version.
2149// * The libraries are not in a predictable location for each STL.
2150
Colin Crossca860ac2016-01-04 14:34:37 -08002151type ndkPrebuiltStlLinker struct {
2152 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002153}
2154
Colin Crossca860ac2016-01-04 14:34:37 -08002155func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2156 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2157 linker := &ndkPrebuiltStlLinker{}
2158 linker.dynamicProperties.BuildShared = true
2159 module.linker = linker
2160 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002161}
2162
Colin Crossca860ac2016-01-04 14:34:37 -08002163func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2164 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2165 linker := &ndkPrebuiltStlLinker{}
2166 linker.dynamicProperties.BuildStatic = true
2167 module.linker = linker
2168 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002169}
2170
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002171func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002172 gccVersion := toolchain.GccVersion()
2173 var libDir string
2174 switch stl {
2175 case "libstlport":
2176 libDir = "cxx-stl/stlport/libs"
2177 case "libc++":
2178 libDir = "cxx-stl/llvm-libc++/libs"
2179 case "libgnustl":
2180 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2181 }
2182
2183 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002184 ndkSrcRoot := "prebuilts/ndk/current/sources"
2185 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002186 }
2187
2188 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002189 return common.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002190}
2191
Colin Crossca860ac2016-01-04 14:34:37 -08002192func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2193 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002194 // A null build step, but it sets up the output path.
2195 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2196 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2197 }
2198
Colin Crossca860ac2016-01-04 14:34:37 -08002199 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs)
2200 ndk.exportFlags = []string{includeDirsToFlags(includeDirs)}
Dan Albertbe961682015-03-18 23:38:50 -07002201
2202 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002203 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002204 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002205 libExt = staticLibraryExtension
2206 }
2207
2208 stlName := strings.TrimSuffix(libName, "_shared")
2209 stlName = strings.TrimSuffix(stlName, "_static")
2210 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002211 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002212}
2213
Colin Cross6362e272015-10-29 15:25:03 -07002214func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002215 if m, ok := mctx.Module().(*Module); ok {
2216 if m.linker != nil {
2217 if linker, ok := m.linker.(baseLinkerInterface); ok {
2218 var modules []blueprint.Module
2219 if linker.buildStatic() && linker.buildShared() {
2220 modules = mctx.CreateLocalVariations("static", "shared")
2221 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
Colin Cross7b106e42016-03-25 17:31:43 -07002222 modules[0].(*Module).installer = nil
Colin Crossca860ac2016-01-04 14:34:37 -08002223 modules[1].(*Module).linker.(baseLinkerInterface).setStatic(false)
2224 } else if linker.buildStatic() {
2225 modules = mctx.CreateLocalVariations("static")
2226 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
Colin Cross7b106e42016-03-25 17:31:43 -07002227 modules[0].(*Module).installer = nil
Colin Crossca860ac2016-01-04 14:34:37 -08002228 } else if linker.buildShared() {
2229 modules = mctx.CreateLocalVariations("shared")
2230 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2231 } else {
2232 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2233 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07002234
Colin Crossca860ac2016-01-04 14:34:37 -08002235 if _, ok := m.compiler.(*libraryCompiler); ok {
2236 reuseFrom := modules[0].(*Module).compiler.(*libraryCompiler)
2237 for _, m := range modules {
2238 m.(*Module).compiler.(*libraryCompiler).reuseFrom = reuseFrom
2239 }
2240 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002241 }
2242 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002243 }
2244}
Colin Cross74d1ec02015-04-28 13:30:13 -07002245
2246// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2247// modifies the slice contents in place, and returns a subslice of the original slice
2248func lastUniqueElements(list []string) []string {
2249 totalSkip := 0
2250 for i := len(list) - 1; i >= totalSkip; i-- {
2251 skip := 0
2252 for j := i - 1; j >= totalSkip; j-- {
2253 if list[i] == list[j] {
2254 skip++
2255 } else {
2256 list[j+skip] = list[j]
2257 }
2258 }
2259 totalSkip += skip
2260 }
2261 return list[totalSkip:]
2262}
Colin Cross06a931b2015-10-28 17:23:31 -07002263
2264var Bool = proptools.Bool