blob: 18dd09c74831eea4f9f8d180745890dc644057b8 [file] [log] [blame]
Colin Cross5049f022015-03-18 13:28:46 -07001// Copyright 2015 Google Inc. All rights reserved.
Colin Cross3f40fa42015-01-30 17:27:36 -08002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17// This file contains the module types for compiling C/C++ for Android, and converts the properties
18// into the flags and filenames necessary to pass to the compiler. The final creation of the rules
19// is handled in builder.go
20
21import (
Colin Cross3f40fa42015-01-30 17:27:36 -080022 "fmt"
23 "path/filepath"
24 "strings"
25
Colin Cross97ba0732015-03-23 17:50:24 -070026 "github.com/google/blueprint"
Colin Cross06a931b2015-10-28 17:23:31 -070027 "github.com/google/blueprint/proptools"
Colin Cross97ba0732015-03-23 17:50:24 -070028
Colin Cross463a90e2015-06-17 14:20:06 -070029 "android/soong"
Colin Cross3f40fa42015-01-30 17:27:36 -080030 "android/soong/common"
Colin Cross5049f022015-03-18 13:28:46 -070031 "android/soong/genrule"
Colin Cross3f40fa42015-01-30 17:27:36 -080032)
33
Colin Cross463a90e2015-06-17 14:20:06 -070034func init() {
Colin Crossca860ac2016-01-04 14:34:37 -080035 soong.RegisterModuleType("cc_library_static", libraryStaticFactory)
36 soong.RegisterModuleType("cc_library_shared", librarySharedFactory)
37 soong.RegisterModuleType("cc_library", libraryFactory)
38 soong.RegisterModuleType("cc_object", objectFactory)
39 soong.RegisterModuleType("cc_binary", binaryFactory)
40 soong.RegisterModuleType("cc_test", testFactory)
41 soong.RegisterModuleType("cc_benchmark", benchmarkFactory)
42 soong.RegisterModuleType("cc_defaults", defaultsFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070043
Colin Crossca860ac2016-01-04 14:34:37 -080044 soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
45 soong.RegisterModuleType("ndk_prebuilt_library", ndkPrebuiltLibraryFactory)
46 soong.RegisterModuleType("ndk_prebuilt_object", ndkPrebuiltObjectFactory)
47 soong.RegisterModuleType("ndk_prebuilt_static_stl", ndkPrebuiltStaticStlFactory)
48 soong.RegisterModuleType("ndk_prebuilt_shared_stl", ndkPrebuiltSharedStlFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070049
Colin Crossca860ac2016-01-04 14:34:37 -080050 soong.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory)
51 soong.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory)
52 soong.RegisterModuleType("cc_binary_host", binaryHostFactory)
53 soong.RegisterModuleType("cc_test_host", testHostFactory)
54 soong.RegisterModuleType("cc_benchmark_host", benchmarkHostFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070055
56 // LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
57 // the Go initialization order because this package depends on common, so common's init
58 // functions will run first.
Colin Cross6362e272015-10-29 15:25:03 -070059 common.RegisterBottomUpMutator("link", linkageMutator)
60 common.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
61 common.RegisterBottomUpMutator("deps", depsMutator)
Colin Cross463a90e2015-06-17 14:20:06 -070062}
63
Colin Cross3f40fa42015-01-30 17:27:36 -080064var (
Colin Cross1332b002015-04-07 17:11:30 -070065 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
Colin Cross3f40fa42015-01-30 17:27:36 -080066
Dan Willemsen34cc69e2015-09-23 15:26:20 -070067 LibcRoot = pctx.SourcePathVariable("LibcRoot", "bionic/libc")
Colin Cross3f40fa42015-01-30 17:27:36 -080068)
69
70// Flags used by lots of devices. Putting them in package static variables will save bytes in
71// build.ninja so they aren't repeated for every file
72var (
73 commonGlobalCflags = []string{
74 "-DANDROID",
75 "-fmessage-length=0",
76 "-W",
77 "-Wall",
78 "-Wno-unused",
79 "-Winit-self",
80 "-Wpointer-arith",
81
82 // COMMON_RELEASE_CFLAGS
83 "-DNDEBUG",
84 "-UDEBUG",
85 }
86
87 deviceGlobalCflags = []string{
Dan Willemsen490fd492015-11-24 17:53:15 -080088 "-fdiagnostics-color",
89
Colin Cross3f40fa42015-01-30 17:27:36 -080090 // TARGET_ERROR_FLAGS
91 "-Werror=return-type",
92 "-Werror=non-virtual-dtor",
93 "-Werror=address",
94 "-Werror=sequence-point",
Dan Willemsena6084a32016-03-01 15:16:50 -080095 "-Werror=date-time",
Colin Cross3f40fa42015-01-30 17:27:36 -080096 }
97
98 hostGlobalCflags = []string{}
99
100 commonGlobalCppflags = []string{
101 "-Wsign-promo",
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700102 }
103
Dan Willemsenbe03f342016-03-03 17:21:04 -0800104 noOverrideGlobalCflags = []string{
105 "-Werror=int-to-pointer-cast",
106 "-Werror=pointer-to-int-cast",
107 }
108
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700109 illegalFlags = []string{
110 "-w",
Colin Cross3f40fa42015-01-30 17:27:36 -0800111 }
112)
113
114func init() {
Dan Willemsen0c38c5e2016-03-29 17:31:57 -0700115 if common.CurrentHostType() == common.Linux {
116 commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
117 }
118
Colin Cross3f40fa42015-01-30 17:27:36 -0800119 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
120 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
121 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800122 pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800123
124 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
125
126 pctx.StaticVariable("commonClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800127 strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800128 pctx.StaticVariable("deviceClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800129 strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800130 pctx.StaticVariable("hostClangGlobalCflags",
131 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800132 pctx.StaticVariable("noOverrideClangGlobalCflags",
133 strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
134
Tim Kilbournf2948142015-03-11 12:03:03 -0700135 pctx.StaticVariable("commonClangGlobalCppflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800136 strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800137
138 // Everything in this list is a crime against abstraction and dependency tracking.
139 // Do not add anything to this list.
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800140 pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700141 []string{
142 "system/core/include",
Dan Willemsen98f93c72016-03-01 15:27:03 -0800143 "system/media/audio/include",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700144 "hardware/libhardware/include",
145 "hardware/libhardware_legacy/include",
146 "hardware/ril/include",
147 "libnativehelper/include",
148 "frameworks/native/include",
149 "frameworks/native/opengl/include",
150 "frameworks/av/include",
151 "frameworks/base/include",
152 })
Dan Willemsene0378dd2016-01-07 17:42:34 -0800153 // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
154 // with this, since there is no associated library.
155 pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
156 []string{"libnativehelper/include/nativehelper"})
Colin Cross3f40fa42015-01-30 17:27:36 -0800157
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700158 pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
159 pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
160 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
161 return override, nil
162 }
163 return "${clangDefaultBase}", nil
164 })
165 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
166 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
167 return override, nil
168 }
Colin Cross7253e0b2016-03-21 15:12:34 -0700169 return "clang-2690385", nil
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700170 })
171 pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}/bin")
Colin Cross3f40fa42015-01-30 17:27:36 -0800172}
173
Colin Crossca860ac2016-01-04 14:34:37 -0800174type Deps struct {
175 SharedLibs, LateSharedLibs []string
176 StaticLibs, LateStaticLibs, WholeStaticLibs []string
Colin Crossc472d572015-03-17 15:06:21 -0700177
Colin Cross81413472016-04-11 14:37:39 -0700178 ObjFiles []string
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700179
Dan Willemsenb40aab62016-04-20 14:21:14 -0700180 GeneratedSources []string
181 GeneratedHeaders []string
182
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700183 Cflags, ReexportedCflags []string
Colin Cross21b9a242015-03-24 14:15:58 -0700184
Colin Cross97ba0732015-03-23 17:50:24 -0700185 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700186}
187
Colin Crossca860ac2016-01-04 14:34:37 -0800188type PathDeps struct {
189 SharedLibs, LateSharedLibs common.Paths
190 StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700191
192 ObjFiles common.Paths
193 WholeStaticLibObjFiles common.Paths
194
Dan Willemsenb40aab62016-04-20 14:21:14 -0700195 GeneratedSources common.Paths
196 GeneratedHeaders common.Paths
197
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700198 Cflags, ReexportedCflags []string
199
200 CrtBegin, CrtEnd common.OptionalPath
201}
202
Colin Crossca860ac2016-01-04 14:34:37 -0800203type Flags struct {
Colin Cross28344522015-04-22 13:07:53 -0700204 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
205 AsFlags []string // Flags that apply to assembly source files
206 CFlags []string // Flags that apply to C and C++ source files
207 ConlyFlags []string // Flags that apply to C source files
208 CppFlags []string // Flags that apply to C++ source files
209 YaccFlags []string // Flags that apply to Yacc source files
210 LdFlags []string // Flags that apply to linker command lines
211
212 Nocrt bool
213 Toolchain Toolchain
214 Clang bool
Colin Crossca860ac2016-01-04 14:34:37 -0800215
216 RequiredInstructionSet string
Colin Crossc472d572015-03-17 15:06:21 -0700217}
218
Colin Crossca860ac2016-01-04 14:34:37 -0800219type BaseCompilerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700220 // list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700221 Srcs []string `android:"arch_variant"`
222
223 // list of source files that should not be used to build the C/C++ module.
224 // This is most useful in the arch/multilib variants to remove non-common files
225 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700226
227 // list of module-specific flags that will be used for C and C++ compiles.
228 Cflags []string `android:"arch_variant"`
229
230 // list of module-specific flags that will be used for C++ compiles
231 Cppflags []string `android:"arch_variant"`
232
233 // list of module-specific flags that will be used for C compiles
234 Conlyflags []string `android:"arch_variant"`
235
236 // list of module-specific flags that will be used for .S compiles
237 Asflags []string `android:"arch_variant"`
238
Colin Crossca860ac2016-01-04 14:34:37 -0800239 // list of module-specific flags that will be used for C and C++ compiles when
240 // compiling with clang
241 Clang_cflags []string `android:"arch_variant"`
242
243 // list of module-specific flags that will be used for .S compiles when
244 // compiling with clang
245 Clang_asflags []string `android:"arch_variant"`
246
Colin Cross7d5136f2015-05-11 13:39:40 -0700247 // list of module-specific flags that will be used for .y and .yy compiles
248 Yaccflags []string
249
Colin Cross7d5136f2015-05-11 13:39:40 -0700250 // the instruction set architecture to use to compile the C/C++
251 // module.
252 Instruction_set string `android:"arch_variant"`
253
254 // list of directories relative to the root of the source tree that will
255 // be added to the include path using -I.
256 // If possible, don't use this. If adding paths from the current directory use
257 // local_include_dirs, if adding paths from other modules use export_include_dirs in
258 // that module.
259 Include_dirs []string `android:"arch_variant"`
260
Colin Cross39d97f22015-09-14 12:30:50 -0700261 // list of files relative to the root of the source tree that will be included
262 // using -include.
263 // If possible, don't use this.
264 Include_files []string `android:"arch_variant"`
265
Colin Cross7d5136f2015-05-11 13:39:40 -0700266 // list of directories relative to the Blueprints file that will
267 // be added to the include path using -I
268 Local_include_dirs []string `android:"arch_variant"`
269
Colin Cross39d97f22015-09-14 12:30:50 -0700270 // list of files relative to the Blueprints file that will be included
271 // using -include.
272 // If possible, don't use this.
273 Local_include_files []string `android:"arch_variant"`
274
Dan Willemsenb40aab62016-04-20 14:21:14 -0700275 // list of generated sources to compile. These are the names of gensrcs or
276 // genrule modules.
277 Generated_sources []string `android:"arch_variant"`
278
279 // list of generated headers to add to the include path. These are the names
280 // of genrule modules.
281 Generated_headers []string `android:"arch_variant"`
282
Colin Crossca860ac2016-01-04 14:34:37 -0800283 // pass -frtti instead of -fno-rtti
284 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700285
Colin Crossca860ac2016-01-04 14:34:37 -0800286 Debug, Release struct {
287 // list of module-specific flags that will be used for C and C++ compiles in debug or
288 // release builds
289 Cflags []string `android:"arch_variant"`
290 } `android:"arch_variant"`
291}
Colin Cross7d5136f2015-05-11 13:39:40 -0700292
Colin Crossca860ac2016-01-04 14:34:37 -0800293type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700294 // list of modules whose object files should be linked into this module
295 // in their entirety. For static library modules, all of the .o files from the intermediate
296 // directory of the dependency will be linked into this modules .a file. For a shared library,
297 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
298 Whole_static_libs []string `android:"arch_variant"`
299
300 // list of modules that should be statically linked into this module.
301 Static_libs []string `android:"arch_variant"`
302
303 // list of modules that should be dynamically linked into this module.
304 Shared_libs []string `android:"arch_variant"`
305
Colin Crossca860ac2016-01-04 14:34:37 -0800306 // list of module-specific flags that will be used for all link steps
307 Ldflags []string `android:"arch_variant"`
308
309 // don't insert default compiler flags into asflags, cflags,
310 // cppflags, conlyflags, ldflags, or include_dirs
311 No_default_compiler_flags *bool
312
313 // list of system libraries that will be dynamically linked to
314 // shared library and executable modules. If unset, generally defaults to libc
315 // and libm. Set to [] to prevent linking against libc and libm.
316 System_shared_libs []string
317
Colin Cross7d5136f2015-05-11 13:39:40 -0700318 // allow the module to contain undefined symbols. By default,
319 // modules cannot contain undefined symbols that are not satisified by their immediate
320 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
321 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700322 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700323
Dan Willemsend67be222015-09-16 15:19:33 -0700324 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700325 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700326
Colin Cross7d5136f2015-05-11 13:39:40 -0700327 // -l arguments to pass to linker for host-provided shared libraries
328 Host_ldlibs []string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800329}
Colin Cross7d5136f2015-05-11 13:39:40 -0700330
Colin Crossca860ac2016-01-04 14:34:37 -0800331type LibraryCompilerProperties struct {
332 Static struct {
333 Srcs []string `android:"arch_variant"`
334 Exclude_srcs []string `android:"arch_variant"`
335 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700336 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800337 Shared struct {
338 Srcs []string `android:"arch_variant"`
339 Exclude_srcs []string `android:"arch_variant"`
340 Cflags []string `android:"arch_variant"`
341 } `android:"arch_variant"`
342}
343
Colin Cross919281a2016-04-05 16:42:05 -0700344type FlagExporterProperties struct {
345 // list of directories relative to the Blueprints file that will
346 // be added to the include path using -I for any module that links against this module
347 Export_include_dirs []string `android:"arch_variant"`
348}
349
Colin Crossca860ac2016-01-04 14:34:37 -0800350type LibraryLinkerProperties struct {
351 Static struct {
352 Whole_static_libs []string `android:"arch_variant"`
353 Static_libs []string `android:"arch_variant"`
354 Shared_libs []string `android:"arch_variant"`
355 } `android:"arch_variant"`
356 Shared struct {
357 Whole_static_libs []string `android:"arch_variant"`
358 Static_libs []string `android:"arch_variant"`
359 Shared_libs []string `android:"arch_variant"`
360 } `android:"arch_variant"`
361
362 // local file name to pass to the linker as --version_script
363 Version_script *string `android:"arch_variant"`
364 // local file name to pass to the linker as -unexported_symbols_list
365 Unexported_symbols_list *string `android:"arch_variant"`
366 // local file name to pass to the linker as -force_symbols_not_weak_list
367 Force_symbols_not_weak_list *string `android:"arch_variant"`
368 // local file name to pass to the linker as -force_symbols_weak_list
369 Force_symbols_weak_list *string `android:"arch_variant"`
370
Colin Crossca860ac2016-01-04 14:34:37 -0800371 // don't link in crt_begin and crt_end. This flag should only be necessary for
372 // compiling crt or libc.
373 Nocrt *bool `android:"arch_variant"`
374}
375
376type BinaryLinkerProperties struct {
377 // compile executable with -static
378 Static_executable *bool
379
380 // set the name of the output
381 Stem string `android:"arch_variant"`
382
383 // append to the name of the output
384 Suffix string `android:"arch_variant"`
385
386 // if set, add an extra objcopy --prefix-symbols= step
387 Prefix_symbols string
388}
389
390type TestLinkerProperties struct {
391 // if set, build against the gtest library. Defaults to true.
392 Gtest bool
393
394 // Create a separate binary for each source file. Useful when there is
395 // global state that can not be torn down and reset between each test suite.
396 Test_per_src *bool
397}
398
Colin Cross81413472016-04-11 14:37:39 -0700399type ObjectLinkerProperties struct {
400 // names of other cc_object modules to link into this module using partial linking
401 Objs []string `android:"arch_variant"`
402}
403
Colin Crossca860ac2016-01-04 14:34:37 -0800404// Properties used to compile all C or C++ modules
405type BaseProperties struct {
406 // compile module with clang instead of gcc
407 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700408
409 // Minimum sdk version supported when compiling against the ndk
410 Sdk_version string
411
Colin Crossca860ac2016-01-04 14:34:37 -0800412 // don't insert default compiler flags into asflags, cflags,
413 // cppflags, conlyflags, ldflags, or include_dirs
414 No_default_compiler_flags *bool
Colin Crossc99deeb2016-04-11 15:06:20 -0700415
416 AndroidMkSharedLibs []string `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800417}
418
419type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700420 // install to a subdirectory of the default install path for the module
421 Relative_install_path string
422}
423
Colin Crossca860ac2016-01-04 14:34:37 -0800424type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700425 Native_coverage *bool
426 Required []string
427 Strip string
428 Tags []string
429 Sanitize struct {
430 Never bool `android:"arch_variant"`
431 Address bool `android:"arch_variant"`
432 Thread bool `android:"arch_variant"`
433 Undefined bool `android:"arch_variant"`
434 All_undefined bool `android:"arch_variant"`
435 Misc_undefined []string `android:"arch_variant"`
436 Coverage bool `android:"arch_variant"`
437 Recover []string
438 } `android:"arch_variant"`
Colin Crosscfad1192015-11-02 16:43:11 -0800439}
440
Colin Crossca860ac2016-01-04 14:34:37 -0800441type ModuleContextIntf interface {
442 module() *Module
443 static() bool
444 staticBinary() bool
445 clang() bool
446 toolchain() Toolchain
447 noDefaultCompilerFlags() bool
448 sdk() bool
449 sdkVersion() string
450}
451
452type ModuleContext interface {
453 common.AndroidModuleContext
454 ModuleContextIntf
455}
456
457type BaseModuleContext interface {
458 common.AndroidBaseContext
459 ModuleContextIntf
460}
461
462type Customizer interface {
463 CustomizeProperties(BaseModuleContext)
464 Properties() []interface{}
465}
466
467type feature interface {
468 begin(ctx BaseModuleContext)
469 deps(ctx BaseModuleContext, deps Deps) Deps
470 flags(ctx ModuleContext, flags Flags) Flags
471 props() []interface{}
472}
473
474type compiler interface {
475 feature
Dan Willemsenb40aab62016-04-20 14:21:14 -0700476 compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800477}
478
479type linker interface {
480 feature
481 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
Colin Crossc99deeb2016-04-11 15:06:20 -0700482 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800483}
484
485type installer interface {
486 props() []interface{}
487 install(ctx ModuleContext, path common.Path)
488 inData() bool
489}
490
Colin Crossc99deeb2016-04-11 15:06:20 -0700491type dependencyTag struct {
492 blueprint.BaseDependencyTag
493 name string
494 library bool
495}
496
497var (
498 sharedDepTag = dependencyTag{name: "shared", library: true}
499 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
500 staticDepTag = dependencyTag{name: "static", library: true}
501 lateStaticDepTag = dependencyTag{name: "late static", library: true}
502 wholeStaticDepTag = dependencyTag{name: "whole static", library: true}
Dan Willemsenb40aab62016-04-20 14:21:14 -0700503 genSourceDepTag = dependencyTag{name: "gen source"}
504 genHeaderDepTag = dependencyTag{name: "gen header"}
Colin Crossc99deeb2016-04-11 15:06:20 -0700505 objDepTag = dependencyTag{name: "obj"}
506 crtBeginDepTag = dependencyTag{name: "crtbegin"}
507 crtEndDepTag = dependencyTag{name: "crtend"}
508 reuseObjTag = dependencyTag{name: "reuse objects"}
509)
510
Colin Crossca860ac2016-01-04 14:34:37 -0800511// Module contains the properties and members used by all C/C++ module types, and implements
512// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
513// to construct the output file. Behavior can be customized with a Customizer interface
514type Module struct {
Colin Crossc472d572015-03-17 15:06:21 -0700515 common.AndroidModuleBase
Colin Crosscfad1192015-11-02 16:43:11 -0800516 common.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700517
Colin Crossca860ac2016-01-04 14:34:37 -0800518 Properties BaseProperties
519 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700520
Colin Crossca860ac2016-01-04 14:34:37 -0800521 // initialize before calling Init
522 hod common.HostOrDeviceSupported
523 multilib common.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700524
Colin Crossca860ac2016-01-04 14:34:37 -0800525 // delegates, initialize before calling Init
526 customizer Customizer
527 features []feature
528 compiler compiler
529 linker linker
530 installer installer
Colin Crossa8e07cc2016-04-04 15:07:06 -0700531 stl *stl
Colin Cross74d1ec02015-04-28 13:30:13 -0700532
Colin Crossca860ac2016-01-04 14:34:37 -0800533 outputFile common.OptionalPath
534
535 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700536}
537
Colin Crossca860ac2016-01-04 14:34:37 -0800538func (c *Module) Init() (blueprint.Module, []interface{}) {
539 props := []interface{}{&c.Properties, &c.unused}
540 if c.customizer != nil {
541 props = append(props, c.customizer.Properties()...)
542 }
543 if c.compiler != nil {
544 props = append(props, c.compiler.props()...)
545 }
546 if c.linker != nil {
547 props = append(props, c.linker.props()...)
548 }
549 if c.installer != nil {
550 props = append(props, c.installer.props()...)
551 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700552 if c.stl != nil {
553 props = append(props, c.stl.props()...)
554 }
Colin Crossca860ac2016-01-04 14:34:37 -0800555 for _, feature := range c.features {
556 props = append(props, feature.props()...)
557 }
Colin Crossc472d572015-03-17 15:06:21 -0700558
Colin Crossca860ac2016-01-04 14:34:37 -0800559 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700560
Colin Crossca860ac2016-01-04 14:34:37 -0800561 return common.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700562}
563
Colin Crossca860ac2016-01-04 14:34:37 -0800564type baseModuleContext struct {
565 common.AndroidBaseContext
566 moduleContextImpl
567}
568
569type moduleContext struct {
570 common.AndroidModuleContext
571 moduleContextImpl
572}
573
574type moduleContextImpl struct {
575 mod *Module
576 ctx BaseModuleContext
577}
578
579func (ctx *moduleContextImpl) module() *Module {
580 return ctx.mod
581}
582
583func (ctx *moduleContextImpl) clang() bool {
584 return ctx.mod.clang(ctx.ctx)
585}
586
587func (ctx *moduleContextImpl) toolchain() Toolchain {
588 return ctx.mod.toolchain(ctx.ctx)
589}
590
591func (ctx *moduleContextImpl) static() bool {
592 if ctx.mod.linker == nil {
593 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
594 }
595 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
596 return linker.static()
597 } else {
598 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
599 }
600}
601
602func (ctx *moduleContextImpl) staticBinary() bool {
603 if ctx.mod.linker == nil {
604 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
605 }
606 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
607 return linker.staticBinary()
608 } else {
609 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
610 }
611}
612
613func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
614 return Bool(ctx.mod.Properties.No_default_compiler_flags)
615}
616
617func (ctx *moduleContextImpl) sdk() bool {
618 return ctx.mod.Properties.Sdk_version != ""
619}
620
621func (ctx *moduleContextImpl) sdkVersion() string {
622 return ctx.mod.Properties.Sdk_version
623}
624
625func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
626 return &Module{
627 hod: hod,
628 multilib: multilib,
629 }
630}
631
632func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
633 module := newBaseModule(hod, multilib)
Colin Crossa8e07cc2016-04-04 15:07:06 -0700634 module.stl = &stl{}
Colin Crossca860ac2016-01-04 14:34:37 -0800635 return module
636}
637
638func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
639 ctx := &moduleContext{
640 AndroidModuleContext: actx,
641 moduleContextImpl: moduleContextImpl{
642 mod: c,
643 },
644 }
645 ctx.ctx = ctx
646
647 flags := Flags{
648 Toolchain: c.toolchain(ctx),
649 Clang: c.clang(ctx),
650 }
651
652 if c.compiler != nil {
653 flags = c.compiler.flags(ctx, flags)
654 }
655 if c.linker != nil {
656 flags = c.linker.flags(ctx, flags)
657 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700658 if c.stl != nil {
659 flags = c.stl.flags(ctx, flags)
660 }
Colin Crossca860ac2016-01-04 14:34:37 -0800661 for _, feature := range c.features {
662 flags = feature.flags(ctx, flags)
663 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800664 if ctx.Failed() {
665 return
666 }
667
Colin Crossca860ac2016-01-04 14:34:37 -0800668 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
669 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
670 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800671
Colin Crossca860ac2016-01-04 14:34:37 -0800672 // Optimization to reduce size of build.ninja
673 // Replace the long list of flags for each file with a module-local variable
674 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
675 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
676 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
677 flags.CFlags = []string{"$cflags"}
678 flags.CppFlags = []string{"$cppflags"}
679 flags.AsFlags = []string{"$asflags"}
680
Colin Crossc99deeb2016-04-11 15:06:20 -0700681 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800682 if ctx.Failed() {
683 return
684 }
685
Colin Cross28344522015-04-22 13:07:53 -0700686 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700687
Colin Crossca860ac2016-01-04 14:34:37 -0800688 var objFiles common.Paths
689 if c.compiler != nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700690 objFiles = c.compiler.compile(ctx, flags, deps)
Colin Crossca860ac2016-01-04 14:34:37 -0800691 if ctx.Failed() {
692 return
693 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800694 }
695
Colin Crossca860ac2016-01-04 14:34:37 -0800696 if c.linker != nil {
697 outputFile := c.linker.link(ctx, flags, deps, objFiles)
698 if ctx.Failed() {
699 return
700 }
701 c.outputFile = common.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700702
Colin Crossc99deeb2016-04-11 15:06:20 -0700703 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800704 c.installer.install(ctx, outputFile)
705 if ctx.Failed() {
706 return
707 }
708 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700709 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800710}
711
Colin Crossca860ac2016-01-04 14:34:37 -0800712func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
713 if c.cachedToolchain == nil {
714 arch := ctx.Arch()
715 hod := ctx.HostOrDevice()
716 ht := ctx.HostType()
717 factory := toolchainFactories[hod][ht][arch.ArchType]
718 if factory == nil {
719 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
720 return nil
721 }
722 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800723 }
Colin Crossca860ac2016-01-04 14:34:37 -0800724 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800725}
726
Colin Crossca860ac2016-01-04 14:34:37 -0800727func (c *Module) begin(ctx BaseModuleContext) {
728 if c.compiler != nil {
729 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700730 }
Colin Crossca860ac2016-01-04 14:34:37 -0800731 if c.linker != nil {
732 c.linker.begin(ctx)
733 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700734 if c.stl != nil {
735 c.stl.begin(ctx)
736 }
Colin Crossca860ac2016-01-04 14:34:37 -0800737 for _, feature := range c.features {
738 feature.begin(ctx)
739 }
740}
741
Colin Crossc99deeb2016-04-11 15:06:20 -0700742func (c *Module) deps(ctx BaseModuleContext) Deps {
743 deps := Deps{}
744
745 if c.compiler != nil {
746 deps = c.compiler.deps(ctx, deps)
747 }
748 if c.linker != nil {
749 deps = c.linker.deps(ctx, deps)
750 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700751 if c.stl != nil {
752 deps = c.stl.deps(ctx, deps)
753 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700754 for _, feature := range c.features {
755 deps = feature.deps(ctx, deps)
756 }
757
758 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
759 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
760 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
761 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
762 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
763
764 return deps
765}
766
Colin Crossca860ac2016-01-04 14:34:37 -0800767func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
768 ctx := &baseModuleContext{
769 AndroidBaseContext: actx,
770 moduleContextImpl: moduleContextImpl{
771 mod: c,
772 },
773 }
774 ctx.ctx = ctx
775
776 if c.customizer != nil {
777 c.customizer.CustomizeProperties(ctx)
778 }
779
780 c.begin(ctx)
781
Colin Crossc99deeb2016-04-11 15:06:20 -0700782 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800783
Colin Crossc99deeb2016-04-11 15:06:20 -0700784 c.Properties.AndroidMkSharedLibs = deps.SharedLibs
785
786 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
787 deps.WholeStaticLibs...)
788
789 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticDepTag,
790 deps.StaticLibs...)
791
792 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
793 deps.LateStaticLibs...)
794
795 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedDepTag,
796 deps.SharedLibs...)
797
798 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
799 deps.LateSharedLibs...)
800
Dan Willemsenb40aab62016-04-20 14:21:14 -0700801 actx.AddDependency(ctx.module(), genSourceDepTag, deps.GeneratedSources...)
802 actx.AddDependency(ctx.module(), genHeaderDepTag, deps.GeneratedHeaders...)
803
Colin Crossc99deeb2016-04-11 15:06:20 -0700804 actx.AddDependency(ctx.module(), objDepTag, deps.ObjFiles...)
805
806 if deps.CrtBegin != "" {
807 actx.AddDependency(ctx.module(), crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800808 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700809 if deps.CrtEnd != "" {
810 actx.AddDependency(ctx.module(), crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700811 }
Colin Cross6362e272015-10-29 15:25:03 -0700812}
Colin Cross21b9a242015-03-24 14:15:58 -0700813
Colin Cross6362e272015-10-29 15:25:03 -0700814func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800815 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700816 c.depsMutator(ctx)
817 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800818}
819
Colin Crossca860ac2016-01-04 14:34:37 -0800820func (c *Module) clang(ctx BaseModuleContext) bool {
821 clang := Bool(c.Properties.Clang)
822
823 if c.Properties.Clang == nil {
824 if ctx.Host() {
825 clang = true
826 }
827
828 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
829 clang = true
830 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800831 }
Colin Cross28344522015-04-22 13:07:53 -0700832
Colin Crossca860ac2016-01-04 14:34:37 -0800833 if !c.toolchain(ctx).ClangSupported() {
834 clang = false
835 }
836
837 return clang
838}
839
Colin Crossc99deeb2016-04-11 15:06:20 -0700840// Convert dependencies to paths. Returns a PathDeps containing paths
841func (c *Module) depsToPaths(ctx common.AndroidModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800842 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800843
Colin Crossc99deeb2016-04-11 15:06:20 -0700844 ctx.VisitDirectDeps(func(m blueprint.Module) {
845 name := ctx.OtherModuleName(m)
846 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800847
Colin Crossc99deeb2016-04-11 15:06:20 -0700848 a, _ := m.(common.AndroidModule)
849 if a == nil {
850 ctx.ModuleErrorf("module %q not an android module", name)
851 return
Colin Crossca860ac2016-01-04 14:34:37 -0800852 }
Colin Crossca860ac2016-01-04 14:34:37 -0800853
Colin Crossc99deeb2016-04-11 15:06:20 -0700854 c, _ := m.(*Module)
855 if c == nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700856 switch tag {
857 case common.DefaultsDepTag:
858 case genSourceDepTag:
859 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
860 depPaths.GeneratedSources = append(depPaths.GeneratedSources,
861 genRule.GeneratedSourceFiles()...)
862 } else {
863 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
864 }
865 case genHeaderDepTag:
866 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
867 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
868 genRule.GeneratedSourceFiles()...)
869 depPaths.Cflags = append(depPaths.Cflags,
870 includeDirsToFlags(common.Paths{genRule.GeneratedHeaderDir()}))
871 } else {
872 ctx.ModuleErrorf("module %q is not a genrule", name)
873 }
874 default:
Colin Crossc99deeb2016-04-11 15:06:20 -0700875 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -0800876 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700877 return
878 }
879
880 if !a.Enabled() {
881 ctx.ModuleErrorf("depends on disabled module %q", name)
882 return
883 }
884
885 if a.HostOrDevice() != ctx.HostOrDevice() {
886 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(), name)
887 return
888 }
889
890 if !c.outputFile.Valid() {
891 ctx.ModuleErrorf("module %q missing output file", name)
892 return
893 }
894
895 if tag == reuseObjTag {
896 depPaths.ObjFiles = append(depPaths.ObjFiles,
897 c.compiler.(*libraryCompiler).reuseObjFiles...)
898 return
899 }
900
901 var cflags []string
902 if t, _ := tag.(dependencyTag); t.library {
903 if i, ok := c.linker.(exportedFlagsProducer); ok {
904 cflags = i.exportedFlags()
905 depPaths.Cflags = append(depPaths.Cflags, cflags...)
906 }
907 }
908
909 var depPtr *common.Paths
910
911 switch tag {
912 case sharedDepTag:
913 depPtr = &depPaths.SharedLibs
914 case lateSharedDepTag:
915 depPtr = &depPaths.LateSharedLibs
916 case staticDepTag:
917 depPtr = &depPaths.StaticLibs
918 case lateStaticDepTag:
919 depPtr = &depPaths.LateStaticLibs
920 case wholeStaticDepTag:
921 depPtr = &depPaths.WholeStaticLibs
922 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, cflags...)
923 staticLib, _ := c.linker.(*libraryLinker)
924 if staticLib == nil || !staticLib.static() {
925 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
926 return
927 }
928
929 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
930 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
931 for i := range missingDeps {
932 missingDeps[i] += postfix
933 }
934 ctx.AddMissingDependencies(missingDeps)
935 }
936 depPaths.WholeStaticLibObjFiles =
937 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
938 case objDepTag:
939 depPtr = &depPaths.ObjFiles
940 case crtBeginDepTag:
941 depPaths.CrtBegin = c.outputFile
942 case crtEndDepTag:
943 depPaths.CrtEnd = c.outputFile
944 default:
945 panic(fmt.Errorf("unknown dependency tag: %s", ctx.OtherModuleDependencyTag(m)))
946 }
947
948 if depPtr != nil {
949 *depPtr = append(*depPtr, c.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -0800950 }
951 })
952
953 return depPaths
954}
955
956func (c *Module) InstallInData() bool {
957 if c.installer == nil {
958 return false
959 }
960 return c.installer.inData()
961}
962
963// Compiler
964
965type baseCompiler struct {
966 Properties BaseCompilerProperties
967}
968
969var _ compiler = (*baseCompiler)(nil)
970
971func (compiler *baseCompiler) props() []interface{} {
972 return []interface{}{&compiler.Properties}
973}
974
Dan Willemsenb40aab62016-04-20 14:21:14 -0700975func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
976
977func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
978 deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
979 deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
980
981 return deps
982}
Colin Crossca860ac2016-01-04 14:34:37 -0800983
984// Create a Flags struct that collects the compile flags from global values,
985// per-target values, module type values, and per-module Blueprints properties
986func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
987 toolchain := ctx.toolchain()
988
989 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
990 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
991 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
992 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
993 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
994
Colin Cross28344522015-04-22 13:07:53 -0700995 // Include dir cflags
Colin Crossca860ac2016-01-04 14:34:37 -0800996 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
997 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -0700998 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -0700999 includeDirsToFlags(localIncludeDirs),
1000 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -07001001
Colin Crossca860ac2016-01-04 14:34:37 -08001002 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
1003 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -07001004
1005 flags.GlobalFlags = append(flags.GlobalFlags,
1006 includeFilesToFlags(rootIncludeFiles),
1007 includeFilesToFlags(localIncludeFiles))
1008
Colin Crossca860ac2016-01-04 14:34:37 -08001009 if !ctx.noDefaultCompilerFlags() {
1010 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -07001011 flags.GlobalFlags = append(flags.GlobalFlags,
1012 "${commonGlobalIncludes}",
1013 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -08001014 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -07001015 }
1016
1017 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001018 "-I" + common.PathForModuleSrc(ctx).String(),
1019 "-I" + common.PathForModuleOut(ctx).String(),
1020 "-I" + common.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -07001021 }...)
1022 }
1023
Colin Crossca860ac2016-01-04 14:34:37 -08001024 instructionSet := compiler.Properties.Instruction_set
1025 if flags.RequiredInstructionSet != "" {
1026 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -08001027 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001028 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
1029 if flags.Clang {
1030 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
1031 }
1032 if err != nil {
1033 ctx.ModuleErrorf("%s", err)
1034 }
1035
1036 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -08001037 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001038
Colin Cross97ba0732015-03-23 17:50:24 -07001039 if flags.Clang {
1040 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001041 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
1042 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -07001043 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
1044 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
1045 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001046
1047 target := "-target " + toolchain.ClangTriple()
1048 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
1049
Colin Cross97ba0732015-03-23 17:50:24 -07001050 flags.CFlags = append(flags.CFlags, target, gccPrefix)
1051 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
1052 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -08001053 }
1054
Colin Crossca860ac2016-01-04 14:34:37 -08001055 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001056 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1057
Colin Cross97ba0732015-03-23 17:50:24 -07001058 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001059 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001060 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001061 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001062 toolchain.ClangCflags(),
1063 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001064 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001065
1066 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001067 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001068 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001069 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001070 toolchain.Cflags(),
1071 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001072 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001073 }
1074
Colin Cross7b66f152015-12-15 16:07:43 -08001075 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1076 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1077 }
1078
Colin Crossf6566ed2015-03-24 11:13:38 -07001079 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001080 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001081 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001082 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001083 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001084 }
1085 }
1086
Colin Cross97ba0732015-03-23 17:50:24 -07001087 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001088
Colin Cross97ba0732015-03-23 17:50:24 -07001089 if flags.Clang {
1090 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001091 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001092 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001093 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001094 }
1095
Colin Crossc4bde762015-11-23 16:11:30 -08001096 if flags.Clang {
1097 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1098 } else {
1099 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001100 }
1101
Colin Crossca860ac2016-01-04 14:34:37 -08001102 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001103 if ctx.Host() && !flags.Clang {
1104 // The host GCC doesn't support C++14 (and is deprecated, so likely
1105 // never will). Build these modules with C++11.
1106 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1107 } else {
1108 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1109 }
1110 }
1111
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001112 // We can enforce some rules more strictly in the code we own. strict
1113 // indicates if this is code that we can be stricter with. If we have
1114 // rules that we want to apply to *our* code (but maybe can't for
1115 // vendor/device specific things), we could extend this to be a ternary
1116 // value.
1117 strict := true
1118 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1119 strict = false
1120 }
1121
1122 // Can be used to make some annotations stricter for code we can fix
1123 // (such as when we mark functions as deprecated).
1124 if strict {
1125 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1126 }
1127
Colin Cross3f40fa42015-01-30 17:27:36 -08001128 return flags
1129}
1130
Dan Willemsenb40aab62016-04-20 14:21:14 -07001131func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001132 // Compile files listed in c.Properties.Srcs into objects
Dan Willemsenb40aab62016-04-20 14:21:14 -07001133 objFiles := compiler.compileObjs(ctx, flags, "",
1134 compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
1135 deps.GeneratedSources, deps.GeneratedHeaders)
1136
Colin Crossca860ac2016-01-04 14:34:37 -08001137 if ctx.Failed() {
1138 return nil
1139 }
1140
Colin Crossca860ac2016-01-04 14:34:37 -08001141 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001142}
1143
1144// Compile a list of source files into objects a specified subdirectory
Colin Crossca860ac2016-01-04 14:34:37 -08001145func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001146 subdir string, srcFiles, excludes []string, extraSrcs, deps common.Paths) common.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001147
Colin Crossca860ac2016-01-04 14:34:37 -08001148 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001149
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001150 inputFiles := ctx.ExpandSources(srcFiles, excludes)
Dan Willemsenb40aab62016-04-20 14:21:14 -07001151 inputFiles = append(inputFiles, extraSrcs...)
1152 srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)
1153
1154 deps = append(deps, gendeps...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001155
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001156 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001157}
1158
Colin Crossca860ac2016-01-04 14:34:37 -08001159// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1160type baseLinker struct {
1161 Properties BaseLinkerProperties
1162 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001163 VariantIsShared bool `blueprint:"mutated"`
1164 VariantIsStatic bool `blueprint:"mutated"`
1165 VariantIsStaticBinary bool `blueprint:"mutated"`
1166 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001167 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001168}
1169
Dan Willemsend30e6102016-03-30 17:35:50 -07001170func (linker *baseLinker) begin(ctx BaseModuleContext) {
1171 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001172 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001173 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001174 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001175 }
1176}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001177
Colin Crossca860ac2016-01-04 14:34:37 -08001178func (linker *baseLinker) props() []interface{} {
1179 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001180}
1181
Colin Crossca860ac2016-01-04 14:34:37 -08001182func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1183 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1184 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1185 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001186
Colin Cross74d1ec02015-04-28 13:30:13 -07001187 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001188 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001189 }
1190
Colin Crossf6566ed2015-03-24 11:13:38 -07001191 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001192 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001193 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1194 if !Bool(linker.Properties.No_libgcc) {
1195 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001196 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001197
Colin Crossca860ac2016-01-04 14:34:37 -08001198 if !linker.static() {
1199 if linker.Properties.System_shared_libs != nil {
1200 deps.LateSharedLibs = append(deps.LateSharedLibs,
1201 linker.Properties.System_shared_libs...)
1202 } else if !ctx.sdk() {
1203 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1204 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001205 }
Colin Cross577f6e42015-03-27 18:23:34 -07001206
Colin Crossca860ac2016-01-04 14:34:37 -08001207 if ctx.sdk() {
1208 version := ctx.sdkVersion()
1209 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001210 "ndk_libc."+version,
1211 "ndk_libm."+version,
1212 )
1213 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001214 }
1215
Colin Crossca860ac2016-01-04 14:34:37 -08001216 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001217}
1218
Colin Crossca860ac2016-01-04 14:34:37 -08001219func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1220 toolchain := ctx.toolchain()
1221
1222 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1223
1224 if !ctx.noDefaultCompilerFlags() {
1225 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1226 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1227 }
1228
1229 if flags.Clang {
1230 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1231 } else {
1232 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1233 }
1234
1235 if ctx.Host() {
1236 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1237 }
1238 }
1239
Dan Willemsend30e6102016-03-30 17:35:50 -07001240 if ctx.Host() && !linker.static() {
1241 rpath_prefix := `\$$ORIGIN/`
1242 if ctx.Darwin() {
1243 rpath_prefix = "@loader_path/"
1244 }
1245
Colin Crossc99deeb2016-04-11 15:06:20 -07001246 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001247 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1248 }
1249 }
1250
Dan Willemsene7174922016-03-30 17:33:52 -07001251 if flags.Clang {
1252 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1253 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001254 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1255 }
1256
1257 return flags
1258}
1259
1260func (linker *baseLinker) static() bool {
1261 return linker.dynamicProperties.VariantIsStatic
1262}
1263
1264func (linker *baseLinker) staticBinary() bool {
1265 return linker.dynamicProperties.VariantIsStaticBinary
1266}
1267
1268func (linker *baseLinker) setStatic(static bool) {
1269 linker.dynamicProperties.VariantIsStatic = static
1270}
1271
1272type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001273 // Returns true if the build options for the module have selected a static or shared build
1274 buildStatic() bool
1275 buildShared() bool
1276
1277 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001278 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001279
Colin Cross18b6dc52015-04-28 13:20:37 -07001280 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001281 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001282
1283 // Returns whether a module is a static binary
1284 staticBinary() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001285}
1286
Colin Crossca860ac2016-01-04 14:34:37 -08001287type baseInstaller struct {
1288 Properties InstallerProperties
1289
1290 dir string
1291 dir64 string
1292 data bool
1293
Colin Crossa2344662016-03-24 13:14:12 -07001294 path common.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001295}
1296
1297var _ installer = (*baseInstaller)(nil)
1298
1299func (installer *baseInstaller) props() []interface{} {
1300 return []interface{}{&installer.Properties}
1301}
1302
1303func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1304 subDir := installer.dir
1305 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1306 subDir = installer.dir64
1307 }
1308 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1309 installer.path = ctx.InstallFile(dir, file)
1310}
1311
1312func (installer *baseInstaller) inData() bool {
1313 return installer.data
1314}
1315
Colin Cross3f40fa42015-01-30 17:27:36 -08001316//
1317// Combined static+shared libraries
1318//
1319
Colin Cross919281a2016-04-05 16:42:05 -07001320type flagExporter struct {
1321 Properties FlagExporterProperties
1322
1323 flags []string
1324}
1325
1326func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
1327 includeDirs := common.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
1328 f.flags = append(f.flags, common.JoinWithPrefix(includeDirs.Strings(), inc))
1329}
1330
1331func (f *flagExporter) reexportFlags(flags []string) {
1332 f.flags = append(f.flags, flags...)
1333}
1334
1335func (f *flagExporter) exportedFlags() []string {
1336 return f.flags
1337}
1338
1339type exportedFlagsProducer interface {
1340 exportedFlags() []string
1341}
1342
1343var _ exportedFlagsProducer = (*flagExporter)(nil)
1344
Colin Crossca860ac2016-01-04 14:34:37 -08001345type libraryCompiler struct {
1346 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001347
Colin Crossca860ac2016-01-04 14:34:37 -08001348 linker *libraryLinker
1349 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001350
Colin Crossca860ac2016-01-04 14:34:37 -08001351 // For reusing static library objects for shared library
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001352 reuseObjFiles common.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001353}
1354
Colin Crossca860ac2016-01-04 14:34:37 -08001355var _ compiler = (*libraryCompiler)(nil)
1356
1357func (library *libraryCompiler) props() []interface{} {
1358 props := library.baseCompiler.props()
1359 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001360}
1361
Colin Crossca860ac2016-01-04 14:34:37 -08001362func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1363 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001364
Dan Willemsen490fd492015-11-24 17:53:15 -08001365 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1366 // all code is position independent, and then those warnings get promoted to
1367 // errors.
1368 if ctx.HostType() != common.Windows {
1369 flags.CFlags = append(flags.CFlags, "-fPIC")
1370 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001371
Colin Crossca860ac2016-01-04 14:34:37 -08001372 if library.linker.static() {
1373 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001374 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001375 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001376 }
1377
Colin Crossca860ac2016-01-04 14:34:37 -08001378 return flags
1379}
1380
Dan Willemsenb40aab62016-04-20 14:21:14 -07001381func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001382 var objFiles common.Paths
1383
Dan Willemsenb40aab62016-04-20 14:21:14 -07001384 objFiles = library.baseCompiler.compile(ctx, flags, deps)
Colin Crossc99deeb2016-04-11 15:06:20 -07001385 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001386
1387 if library.linker.static() {
1388 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001389 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
1390 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001391 } else {
1392 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001393 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
1394 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001395 }
1396
1397 return objFiles
1398}
1399
1400type libraryLinker struct {
1401 baseLinker
Colin Cross919281a2016-04-05 16:42:05 -07001402 flagExporter
Colin Crossca860ac2016-01-04 14:34:37 -08001403
1404 Properties LibraryLinkerProperties
1405
1406 dynamicProperties struct {
1407 BuildStatic bool `blueprint:"mutated"`
1408 BuildShared bool `blueprint:"mutated"`
1409 }
1410
Colin Crossca860ac2016-01-04 14:34:37 -08001411 // If we're used as a whole_static_lib, our missing dependencies need
1412 // to be given
1413 wholeStaticMissingDeps []string
1414
1415 // For whole_static_libs
1416 objFiles common.Paths
1417}
1418
1419var _ linker = (*libraryLinker)(nil)
Colin Crossca860ac2016-01-04 14:34:37 -08001420
1421func (library *libraryLinker) props() []interface{} {
1422 props := library.baseLinker.props()
Colin Cross919281a2016-04-05 16:42:05 -07001423 return append(props,
1424 &library.Properties,
1425 &library.dynamicProperties,
1426 &library.flagExporter.Properties)
Colin Crossca860ac2016-01-04 14:34:37 -08001427}
1428
1429func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1430 flags = library.baseLinker.flags(ctx, flags)
1431
1432 flags.Nocrt = Bool(library.Properties.Nocrt)
1433
1434 if !library.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001435 libName := ctx.ModuleName()
1436 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1437 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001438 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001439 sharedFlag = "-shared"
1440 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001441 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001442 flags.LdFlags = append(flags.LdFlags,
1443 "-nostdlib",
1444 "-Wl,--gc-sections",
1445 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001446 }
Colin Cross97ba0732015-03-23 17:50:24 -07001447
Colin Cross0af4b842015-04-30 16:36:18 -07001448 if ctx.Darwin() {
1449 flags.LdFlags = append(flags.LdFlags,
1450 "-dynamiclib",
1451 "-single_module",
1452 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001453 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001454 )
1455 } else {
1456 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001457 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001458 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001459 )
1460 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001461 }
Colin Cross97ba0732015-03-23 17:50:24 -07001462
1463 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001464}
1465
Colin Crossca860ac2016-01-04 14:34:37 -08001466func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1467 deps = library.baseLinker.deps(ctx, deps)
1468 if library.static() {
1469 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1470 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1471 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1472 } else {
1473 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1474 if !ctx.sdk() {
1475 deps.CrtBegin = "crtbegin_so"
1476 deps.CrtEnd = "crtend_so"
1477 } else {
1478 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1479 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1480 }
1481 }
1482 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1483 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1484 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1485 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001486
Colin Crossca860ac2016-01-04 14:34:37 -08001487 return deps
1488}
Colin Cross3f40fa42015-01-30 17:27:36 -08001489
Colin Crossca860ac2016-01-04 14:34:37 -08001490func (library *libraryLinker) linkStatic(ctx ModuleContext,
1491 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1492
Colin Cross21b9a242015-03-24 14:15:58 -07001493 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Crossca860ac2016-01-04 14:34:37 -08001494 library.objFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001495
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001496 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001497
Colin Cross0af4b842015-04-30 16:36:18 -07001498 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001499 TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001500 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001501 TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001502 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001503
Colin Crossca860ac2016-01-04 14:34:37 -08001504 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001505
1506 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001507
1508 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001509}
1510
Colin Crossca860ac2016-01-04 14:34:37 -08001511func (library *libraryLinker) linkShared(ctx ModuleContext,
1512 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001513
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001514 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
Colin Cross3f40fa42015-01-30 17:27:36 -08001515
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001516 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001517
Colin Crossca860ac2016-01-04 14:34:37 -08001518 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1519 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1520 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1521 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001522 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001523 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001524 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001525 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001526 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001527 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001528 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1529 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001530 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001531 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1532 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001533 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001534 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1535 }
1536 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001537 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001538 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1539 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001540 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001541 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001542 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001543 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001544 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001545 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001546 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001547 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001548 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001549 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001550 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001551 }
Colin Crossaee540a2015-07-06 17:48:31 -07001552 }
1553
Colin Crossca860ac2016-01-04 14:34:37 -08001554 sharedLibs := deps.SharedLibs
1555 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001556
Colin Crossca860ac2016-01-04 14:34:37 -08001557 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1558 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1559 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile)
1560
1561 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001562}
1563
Colin Crossca860ac2016-01-04 14:34:37 -08001564func (library *libraryLinker) link(ctx ModuleContext,
1565 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001566
Colin Crossc99deeb2016-04-11 15:06:20 -07001567 objFiles = append(objFiles, deps.ObjFiles...)
1568
Colin Crossca860ac2016-01-04 14:34:37 -08001569 var out common.Path
1570 if library.static() {
1571 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001572 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001573 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001574 }
1575
Colin Cross919281a2016-04-05 16:42:05 -07001576 library.exportIncludes(ctx, "-I")
1577 library.reexportFlags(deps.ReexportedCflags)
Colin Crossca860ac2016-01-04 14:34:37 -08001578
1579 return out
1580}
1581
1582func (library *libraryLinker) buildStatic() bool {
1583 return library.dynamicProperties.BuildStatic
1584}
1585
1586func (library *libraryLinker) buildShared() bool {
1587 return library.dynamicProperties.BuildShared
1588}
1589
1590func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1591 return library.wholeStaticMissingDeps
1592}
1593
Colin Crossc99deeb2016-04-11 15:06:20 -07001594func (library *libraryLinker) installable() bool {
1595 return !library.static()
1596}
1597
Colin Crossca860ac2016-01-04 14:34:37 -08001598type libraryInstaller struct {
1599 baseInstaller
1600
1601 linker *libraryLinker
1602}
1603
1604func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1605 if !library.linker.static() {
1606 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001607 }
1608}
1609
Colin Crossca860ac2016-01-04 14:34:37 -08001610func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1611 module := newModule(hod, common.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001612
Colin Crossca860ac2016-01-04 14:34:37 -08001613 linker := &libraryLinker{}
1614 linker.dynamicProperties.BuildShared = shared
1615 linker.dynamicProperties.BuildStatic = static
1616 module.linker = linker
1617
1618 module.compiler = &libraryCompiler{
1619 linker: linker,
1620 }
1621 module.installer = &libraryInstaller{
1622 baseInstaller: baseInstaller{
1623 dir: "lib",
1624 dir64: "lib64",
1625 },
1626 linker: linker,
Dan Albertc403f7c2015-03-18 14:01:18 -07001627 }
1628
Colin Crossca860ac2016-01-04 14:34:37 -08001629 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001630}
1631
Colin Crossca860ac2016-01-04 14:34:37 -08001632func libraryFactory() (blueprint.Module, []interface{}) {
1633 module := NewLibrary(common.HostAndDeviceSupported, true, true)
1634 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001635}
1636
Colin Cross3f40fa42015-01-30 17:27:36 -08001637//
1638// Objects (for crt*.o)
1639//
1640
Colin Crossca860ac2016-01-04 14:34:37 -08001641type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001642 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001643}
1644
Colin Crossca860ac2016-01-04 14:34:37 -08001645func objectFactory() (blueprint.Module, []interface{}) {
1646 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1647 module.compiler = &baseCompiler{}
1648 module.linker = &objectLinker{}
1649 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001650}
1651
Colin Cross81413472016-04-11 14:37:39 -07001652func (object *objectLinker) props() []interface{} {
1653 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001654}
1655
Colin Crossca860ac2016-01-04 14:34:37 -08001656func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001657
Colin Cross81413472016-04-11 14:37:39 -07001658func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1659 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001660 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001661}
1662
Colin Crossca860ac2016-01-04 14:34:37 -08001663func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001664 if flags.Clang {
1665 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1666 } else {
1667 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1668 }
1669
Colin Crossca860ac2016-01-04 14:34:37 -08001670 return flags
1671}
1672
1673func (object *objectLinker) link(ctx ModuleContext,
1674 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001675
Colin Cross97ba0732015-03-23 17:50:24 -07001676 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001677
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001678 var outputFile common.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001679 if len(objFiles) == 1 {
1680 outputFile = objFiles[0]
1681 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001682 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001683 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001684 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001685 }
1686
Colin Cross3f40fa42015-01-30 17:27:36 -08001687 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001688 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001689}
1690
Colin Crossc99deeb2016-04-11 15:06:20 -07001691func (*objectLinker) installable() bool {
1692 return false
1693}
1694
Colin Cross3f40fa42015-01-30 17:27:36 -08001695//
1696// Executables
1697//
1698
Colin Crossca860ac2016-01-04 14:34:37 -08001699type binaryLinker struct {
1700 baseLinker
Colin Cross7d5136f2015-05-11 13:39:40 -07001701
Colin Crossca860ac2016-01-04 14:34:37 -08001702 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001703
Colin Crossca860ac2016-01-04 14:34:37 -08001704 hostToolPath common.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001705}
1706
Colin Crossca860ac2016-01-04 14:34:37 -08001707var _ linker = (*binaryLinker)(nil)
1708
1709func (binary *binaryLinker) props() []interface{} {
1710 return append(binary.baseLinker.props(), &binary.Properties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001711}
1712
Colin Crossca860ac2016-01-04 14:34:37 -08001713func (binary *binaryLinker) buildStatic() bool {
1714 return Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001715}
1716
Colin Crossca860ac2016-01-04 14:34:37 -08001717func (binary *binaryLinker) buildShared() bool {
1718 return !Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001719}
1720
Colin Crossca860ac2016-01-04 14:34:37 -08001721func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001722 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001723 if binary.Properties.Stem != "" {
1724 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001725 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001726
Colin Crossca860ac2016-01-04 14:34:37 -08001727 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001728}
1729
Colin Crossca860ac2016-01-04 14:34:37 -08001730func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1731 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001732 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001733 if !ctx.sdk() {
1734 if Bool(binary.Properties.Static_executable) {
1735 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001736 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001737 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001738 }
Colin Crossca860ac2016-01-04 14:34:37 -08001739 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001740 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001741 if Bool(binary.Properties.Static_executable) {
1742 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001743 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001744 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001745 }
Colin Crossca860ac2016-01-04 14:34:37 -08001746 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001747 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001748
Colin Crossca860ac2016-01-04 14:34:37 -08001749 if Bool(binary.Properties.Static_executable) {
1750 if inList("libc++_static", deps.StaticLibs) {
1751 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001752 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001753 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1754 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1755 // move them to the beginning of deps.LateStaticLibs
1756 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001757 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001758 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001759 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001760 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001761 }
Colin Crossca860ac2016-01-04 14:34:37 -08001762
1763 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1764 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1765 "from static libs or set static_executable: true")
1766 }
1767 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001768}
1769
Colin Crossc99deeb2016-04-11 15:06:20 -07001770func (*binaryLinker) installable() bool {
1771 return true
1772}
1773
Colin Crossca860ac2016-01-04 14:34:37 -08001774func NewBinary(hod common.HostOrDeviceSupported) *Module {
1775 module := newModule(hod, common.MultilibFirst)
1776 module.compiler = &baseCompiler{}
1777 module.linker = &binaryLinker{}
1778 module.installer = &baseInstaller{
1779 dir: "bin",
1780 }
1781 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001782}
1783
Colin Crossca860ac2016-01-04 14:34:37 -08001784func binaryFactory() (blueprint.Module, []interface{}) {
1785 module := NewBinary(common.HostAndDeviceSupported)
1786 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001787}
1788
Colin Crossca860ac2016-01-04 14:34:37 -08001789func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001790 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001791 binary.Properties.Static_executable = proptools.BoolPtr(false)
Colin Cross0af4b842015-04-30 16:36:18 -07001792 }
Colin Crossca860ac2016-01-04 14:34:37 -08001793 if Bool(binary.Properties.Static_executable) {
1794 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001795 }
1796}
1797
Colin Crossca860ac2016-01-04 14:34:37 -08001798func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1799 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001800
Dan Willemsen490fd492015-11-24 17:53:15 -08001801 if ctx.Host() {
1802 flags.LdFlags = append(flags.LdFlags, "-pie")
1803 if ctx.HostType() == common.Windows {
1804 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1805 }
1806 }
1807
1808 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1809 // all code is position independent, and then those warnings get promoted to
1810 // errors.
1811 if ctx.HostType() != common.Windows {
1812 flags.CFlags = append(flags.CFlags, "-fpie")
1813 }
Colin Cross97ba0732015-03-23 17:50:24 -07001814
Colin Crossf6566ed2015-03-24 11:13:38 -07001815 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001816 if Bool(binary.Properties.Static_executable) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001817 // Clang driver needs -static to create static executable.
1818 // However, bionic/linker uses -shared to overwrite.
1819 // Linker for x86 targets does not allow coexistance of -static and -shared,
1820 // so we add -static only if -shared is not used.
1821 if !inList("-shared", flags.LdFlags) {
1822 flags.LdFlags = append(flags.LdFlags, "-static")
1823 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001824
Colin Crossed4cf0b2015-03-26 14:43:45 -07001825 flags.LdFlags = append(flags.LdFlags,
1826 "-nostdlib",
1827 "-Bstatic",
1828 "-Wl,--gc-sections",
1829 )
1830
1831 } else {
1832 linker := "/system/bin/linker"
1833 if flags.Toolchain.Is64Bit() {
Colin Crossca860ac2016-01-04 14:34:37 -08001834 linker += "64"
Colin Crossed4cf0b2015-03-26 14:43:45 -07001835 }
1836
1837 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001838 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001839 "-nostdlib",
1840 "-Bdynamic",
1841 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
1842 "-Wl,--gc-sections",
1843 "-Wl,-z,nocopyreloc",
1844 )
1845 }
Colin Cross0af4b842015-04-30 16:36:18 -07001846 } else if ctx.Darwin() {
1847 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001848 }
1849
Colin Cross97ba0732015-03-23 17:50:24 -07001850 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001851}
1852
Colin Crossca860ac2016-01-04 14:34:37 -08001853func (binary *binaryLinker) link(ctx ModuleContext,
1854 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001855
Colin Crossca860ac2016-01-04 14:34:37 -08001856 outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
1857 if ctx.HostOrDevice().Host() {
1858 binary.hostToolPath = common.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001859 }
Colin Crossca860ac2016-01-04 14:34:37 -08001860 ret := outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001861
Colin Crossca860ac2016-01-04 14:34:37 -08001862 if binary.Properties.Prefix_symbols != "" {
Colin Crossbfae8852015-03-26 14:44:11 -07001863 afterPrefixSymbols := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001864 outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate")
1865 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1866 flagsToBuilderFlags(flags), afterPrefixSymbols)
Colin Crossbfae8852015-03-26 14:44:11 -07001867 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001868
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001869 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001870
Colin Crossca860ac2016-01-04 14:34:37 -08001871 sharedLibs := deps.SharedLibs
1872 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1873
1874 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001875 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Crossca860ac2016-01-04 14:34:37 -08001876 flagsToBuilderFlags(flags), outputFile)
1877
1878 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001879}
Colin Cross3f40fa42015-01-30 17:27:36 -08001880
Colin Crossca860ac2016-01-04 14:34:37 -08001881func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1882 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001883}
1884
Colin Cross6362e272015-10-29 15:25:03 -07001885func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08001886 if m, ok := mctx.Module().(*Module); ok {
1887 if test, ok := m.linker.(*testLinker); ok {
1888 if Bool(test.Properties.Test_per_src) {
1889 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
1890 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1891 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
1892 }
1893 tests := mctx.CreateLocalVariations(testNames...)
1894 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1895 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
1896 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
1897 }
Colin Cross6002e052015-09-16 16:00:08 -07001898 }
1899 }
1900 }
Colin Cross7d5136f2015-05-11 13:39:40 -07001901}
1902
Colin Crossca860ac2016-01-04 14:34:37 -08001903type testLinker struct {
1904 binaryLinker
1905 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001906}
1907
Dan Willemsend30e6102016-03-30 17:35:50 -07001908func (test *testLinker) begin(ctx BaseModuleContext) {
1909 test.binaryLinker.begin(ctx)
1910
1911 runpath := "../../lib"
1912 if ctx.toolchain().Is64Bit() {
1913 runpath += "64"
1914 }
Colin Crossc99deeb2016-04-11 15:06:20 -07001915 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
Dan Willemsend30e6102016-03-30 17:35:50 -07001916}
1917
Colin Crossca860ac2016-01-04 14:34:37 -08001918func (test *testLinker) props() []interface{} {
1919 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07001920}
1921
Colin Crossca860ac2016-01-04 14:34:37 -08001922func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
1923 flags = test.binaryLinker.flags(ctx, flags)
1924
1925 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001926 return flags
1927 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001928
Colin Cross97ba0732015-03-23 17:50:24 -07001929 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001930 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001931 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001932
1933 if ctx.HostType() == common.Windows {
1934 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
1935 } else {
1936 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
1937 flags.LdFlags = append(flags.LdFlags, "-lpthread")
1938 }
1939 } else {
1940 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07001941 }
1942
1943 // TODO(danalbert): Make gtest export its dependencies.
Colin Cross28344522015-04-22 13:07:53 -07001944 flags.CFlags = append(flags.CFlags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001945 "-I"+common.PathForSource(ctx, "external/gtest/include").String())
Dan Albertc403f7c2015-03-18 14:01:18 -07001946
Colin Cross21b9a242015-03-24 14:15:58 -07001947 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07001948}
1949
Colin Crossca860ac2016-01-04 14:34:37 -08001950func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1951 if test.Properties.Gtest {
1952 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001953 }
Colin Crossca860ac2016-01-04 14:34:37 -08001954 deps = test.binaryLinker.deps(ctx, deps)
1955 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07001956}
1957
Colin Crossca860ac2016-01-04 14:34:37 -08001958type testInstaller struct {
1959 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08001960}
1961
Colin Crossca860ac2016-01-04 14:34:37 -08001962func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
1963 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
1964 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
1965 installer.baseInstaller.install(ctx, file)
1966}
1967
1968func NewTest(hod common.HostOrDeviceSupported) *Module {
1969 module := newModule(hod, common.MultilibBoth)
1970 module.compiler = &baseCompiler{}
1971 linker := &testLinker{}
1972 linker.Properties.Gtest = true
1973 module.linker = linker
1974 module.installer = &testInstaller{
1975 baseInstaller: baseInstaller{
1976 dir: "nativetest",
1977 dir64: "nativetest64",
1978 data: true,
1979 },
Dan Albertc403f7c2015-03-18 14:01:18 -07001980 }
Colin Crossca860ac2016-01-04 14:34:37 -08001981 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001982}
1983
Colin Crossca860ac2016-01-04 14:34:37 -08001984func testFactory() (blueprint.Module, []interface{}) {
1985 module := NewTest(common.HostAndDeviceSupported)
1986 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001987}
1988
Colin Crossca860ac2016-01-04 14:34:37 -08001989type benchmarkLinker struct {
1990 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07001991}
1992
Colin Crossca860ac2016-01-04 14:34:37 -08001993func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1994 deps = benchmark.binaryLinker.deps(ctx, deps)
1995 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
1996 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07001997}
1998
Colin Crossca860ac2016-01-04 14:34:37 -08001999func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
2000 module := newModule(hod, common.MultilibFirst)
2001 module.compiler = &baseCompiler{}
2002 module.linker = &benchmarkLinker{}
2003 module.installer = &baseInstaller{
2004 dir: "nativetest",
2005 dir64: "nativetest64",
2006 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07002007 }
Colin Crossca860ac2016-01-04 14:34:37 -08002008 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07002009}
2010
Colin Crossca860ac2016-01-04 14:34:37 -08002011func benchmarkFactory() (blueprint.Module, []interface{}) {
2012 module := NewBenchmark(common.HostAndDeviceSupported)
2013 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002014}
2015
Colin Cross3f40fa42015-01-30 17:27:36 -08002016//
2017// Static library
2018//
2019
Colin Crossca860ac2016-01-04 14:34:37 -08002020func libraryStaticFactory() (blueprint.Module, []interface{}) {
2021 module := NewLibrary(common.HostAndDeviceSupported, false, true)
2022 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002023}
2024
2025//
2026// Shared libraries
2027//
2028
Colin Crossca860ac2016-01-04 14:34:37 -08002029func librarySharedFactory() (blueprint.Module, []interface{}) {
2030 module := NewLibrary(common.HostAndDeviceSupported, true, false)
2031 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002032}
2033
2034//
2035// Host static library
2036//
2037
Colin Crossca860ac2016-01-04 14:34:37 -08002038func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
2039 module := NewLibrary(common.HostSupported, false, true)
2040 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002041}
2042
2043//
2044// Host Shared libraries
2045//
2046
Colin Crossca860ac2016-01-04 14:34:37 -08002047func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
2048 module := NewLibrary(common.HostSupported, true, false)
2049 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002050}
2051
2052//
2053// Host Binaries
2054//
2055
Colin Crossca860ac2016-01-04 14:34:37 -08002056func binaryHostFactory() (blueprint.Module, []interface{}) {
2057 module := NewBinary(common.HostSupported)
2058 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002059}
2060
2061//
Colin Cross1f8f2342015-03-26 16:09:47 -07002062// Host Tests
2063//
2064
Colin Crossca860ac2016-01-04 14:34:37 -08002065func testHostFactory() (blueprint.Module, []interface{}) {
2066 module := NewTest(common.HostSupported)
2067 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07002068}
2069
2070//
Colin Cross2ba19d92015-05-07 15:44:20 -07002071// Host Benchmarks
2072//
2073
Colin Crossca860ac2016-01-04 14:34:37 -08002074func benchmarkHostFactory() (blueprint.Module, []interface{}) {
2075 module := NewBenchmark(common.HostSupported)
2076 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002077}
2078
2079//
Colin Crosscfad1192015-11-02 16:43:11 -08002080// Defaults
2081//
Colin Crossca860ac2016-01-04 14:34:37 -08002082type Defaults struct {
Colin Crosscfad1192015-11-02 16:43:11 -08002083 common.AndroidModuleBase
2084 common.DefaultsModule
2085}
2086
Colin Crossca860ac2016-01-04 14:34:37 -08002087func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002088}
2089
Colin Crossca860ac2016-01-04 14:34:37 -08002090func defaultsFactory() (blueprint.Module, []interface{}) {
2091 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002092
2093 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002094 &BaseProperties{},
2095 &BaseCompilerProperties{},
2096 &BaseLinkerProperties{},
2097 &LibraryCompilerProperties{},
Colin Cross919281a2016-04-05 16:42:05 -07002098 &FlagExporterProperties{},
Colin Crossca860ac2016-01-04 14:34:37 -08002099 &LibraryLinkerProperties{},
2100 &BinaryLinkerProperties{},
2101 &TestLinkerProperties{},
2102 &UnusedProperties{},
2103 &StlProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002104 }
2105
Dan Willemsen218f6562015-07-08 18:13:11 -07002106 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
2107 common.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002108
2109 return common.InitDefaultsModule(module, module, propertyStructs...)
2110}
2111
2112//
Colin Cross3f40fa42015-01-30 17:27:36 -08002113// Device libraries shipped with gcc
2114//
2115
Colin Crossca860ac2016-01-04 14:34:37 -08002116type toolchainLibraryLinker struct {
2117 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002118}
2119
Colin Crossca860ac2016-01-04 14:34:37 -08002120var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2121
2122func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002123 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002124 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002125}
2126
Colin Crossca860ac2016-01-04 14:34:37 -08002127func (*toolchainLibraryLinker) buildStatic() bool {
2128 return true
2129}
Colin Cross3f40fa42015-01-30 17:27:36 -08002130
Colin Crossca860ac2016-01-04 14:34:37 -08002131func (*toolchainLibraryLinker) buildShared() bool {
2132 return false
2133}
2134
2135func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
2136 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2137 module.compiler = &baseCompiler{}
2138 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002139 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002140 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002141}
2142
Colin Crossca860ac2016-01-04 14:34:37 -08002143func (library *toolchainLibraryLinker) link(ctx ModuleContext,
2144 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002145
2146 libName := ctx.ModuleName() + staticLibraryExtension
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002147 outputFile := common.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002148
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002149 if flags.Clang {
2150 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2151 }
2152
Colin Crossca860ac2016-01-04 14:34:37 -08002153 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002154
2155 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002156
Colin Crossca860ac2016-01-04 14:34:37 -08002157 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002158}
2159
Colin Crossc99deeb2016-04-11 15:06:20 -07002160func (*toolchainLibraryLinker) installable() bool {
2161 return false
2162}
2163
Dan Albertbe961682015-03-18 23:38:50 -07002164// NDK prebuilt libraries.
2165//
2166// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2167// either (with the exception of the shared STLs, which are installed to the app's directory rather
2168// than to the system image).
2169
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002170func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2171 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2172 version, toolchain.Name()))
Dan Albertbe961682015-03-18 23:38:50 -07002173}
2174
Dan Albertc3144b12015-04-28 18:17:56 -07002175func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002176 ext string, version string) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002177
2178 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2179 // We want to translate to just NAME.EXT
2180 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2181 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002182 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002183}
2184
Colin Crossca860ac2016-01-04 14:34:37 -08002185type ndkPrebuiltObjectLinker struct {
2186 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002187}
2188
Colin Crossca860ac2016-01-04 14:34:37 -08002189func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002190 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002191 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002192}
2193
Colin Crossca860ac2016-01-04 14:34:37 -08002194func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2195 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2196 module.linker = &ndkPrebuiltObjectLinker{}
2197 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002198}
2199
Colin Crossca860ac2016-01-04 14:34:37 -08002200func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2201 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002202 // A null build step, but it sets up the output path.
2203 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2204 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2205 }
2206
Colin Crossca860ac2016-01-04 14:34:37 -08002207 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002208}
2209
Colin Crossca860ac2016-01-04 14:34:37 -08002210type ndkPrebuiltLibraryLinker struct {
2211 libraryLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002212}
2213
Colin Crossca860ac2016-01-04 14:34:37 -08002214var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2215var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002216
Colin Crossca860ac2016-01-04 14:34:37 -08002217func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Cross919281a2016-04-05 16:42:05 -07002218 return append(ndk.libraryLinker.props(), &ndk.Properties, &ndk.flagExporter.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002219}
2220
Colin Crossca860ac2016-01-04 14:34:37 -08002221func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002222 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002223 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002224}
2225
Colin Crossca860ac2016-01-04 14:34:37 -08002226func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2227 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2228 linker := &ndkPrebuiltLibraryLinker{}
2229 linker.dynamicProperties.BuildShared = true
2230 module.linker = linker
2231 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002232}
2233
Colin Crossca860ac2016-01-04 14:34:37 -08002234func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2235 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002236 // A null build step, but it sets up the output path.
2237 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2238 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2239 }
2240
Colin Cross919281a2016-04-05 16:42:05 -07002241 ndk.exportIncludes(ctx, "-isystem")
Dan Albertbe961682015-03-18 23:38:50 -07002242
Colin Crossca860ac2016-01-04 14:34:37 -08002243 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2244 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002245}
2246
2247// The NDK STLs are slightly different from the prebuilt system libraries:
2248// * Are not specific to each platform version.
2249// * The libraries are not in a predictable location for each STL.
2250
Colin Crossca860ac2016-01-04 14:34:37 -08002251type ndkPrebuiltStlLinker struct {
2252 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002253}
2254
Colin Crossca860ac2016-01-04 14:34:37 -08002255func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2256 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2257 linker := &ndkPrebuiltStlLinker{}
2258 linker.dynamicProperties.BuildShared = true
2259 module.linker = linker
2260 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002261}
2262
Colin Crossca860ac2016-01-04 14:34:37 -08002263func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2264 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2265 linker := &ndkPrebuiltStlLinker{}
2266 linker.dynamicProperties.BuildStatic = true
2267 module.linker = linker
2268 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002269}
2270
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002271func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002272 gccVersion := toolchain.GccVersion()
2273 var libDir string
2274 switch stl {
2275 case "libstlport":
2276 libDir = "cxx-stl/stlport/libs"
2277 case "libc++":
2278 libDir = "cxx-stl/llvm-libc++/libs"
2279 case "libgnustl":
2280 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2281 }
2282
2283 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002284 ndkSrcRoot := "prebuilts/ndk/current/sources"
2285 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002286 }
2287
2288 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002289 return common.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002290}
2291
Colin Crossca860ac2016-01-04 14:34:37 -08002292func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2293 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002294 // A null build step, but it sets up the output path.
2295 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2296 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2297 }
2298
Colin Cross919281a2016-04-05 16:42:05 -07002299 ndk.exportIncludes(ctx, "-I")
Dan Albertbe961682015-03-18 23:38:50 -07002300
2301 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002302 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002303 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002304 libExt = staticLibraryExtension
2305 }
2306
2307 stlName := strings.TrimSuffix(libName, "_shared")
2308 stlName = strings.TrimSuffix(stlName, "_static")
2309 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002310 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002311}
2312
Colin Cross6362e272015-10-29 15:25:03 -07002313func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002314 if m, ok := mctx.Module().(*Module); ok {
2315 if m.linker != nil {
2316 if linker, ok := m.linker.(baseLinkerInterface); ok {
2317 var modules []blueprint.Module
2318 if linker.buildStatic() && linker.buildShared() {
2319 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002320 static := modules[0].(*Module)
2321 shared := modules[1].(*Module)
2322
2323 static.linker.(baseLinkerInterface).setStatic(true)
2324 shared.linker.(baseLinkerInterface).setStatic(false)
2325
2326 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2327 sharedCompiler := shared.compiler.(*libraryCompiler)
2328 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2329 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2330 // Optimize out compiling common .o files twice for static+shared libraries
2331 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2332 sharedCompiler.baseCompiler.Properties.Srcs = nil
2333 }
2334 }
Colin Crossca860ac2016-01-04 14:34:37 -08002335 } else if linker.buildStatic() {
2336 modules = mctx.CreateLocalVariations("static")
2337 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2338 } else if linker.buildShared() {
2339 modules = mctx.CreateLocalVariations("shared")
2340 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2341 } else {
2342 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2343 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002344 }
2345 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002346 }
2347}
Colin Cross74d1ec02015-04-28 13:30:13 -07002348
2349// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2350// modifies the slice contents in place, and returns a subslice of the original slice
2351func lastUniqueElements(list []string) []string {
2352 totalSkip := 0
2353 for i := len(list) - 1; i >= totalSkip; i-- {
2354 skip := 0
2355 for j := i - 1; j >= totalSkip; j-- {
2356 if list[i] == list[j] {
2357 skip++
2358 } else {
2359 list[j+skip] = list[j]
2360 }
2361 }
2362 totalSkip += skip
2363 }
2364 return list[totalSkip:]
2365}
Colin Cross06a931b2015-10-28 17:23:31 -07002366
2367var Bool = proptools.Bool