blob: 6297a4ebf58762b8328eecc439a0212dc710e68a [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 Cross16b23492016-01-06 14:41:07 -080062
63 common.RegisterTopDownMutator("asan_deps", sanitizerDepsMutator(asan))
64 common.RegisterBottomUpMutator("asan", sanitizerMutator(asan))
65
66 common.RegisterTopDownMutator("tsan_deps", sanitizerDepsMutator(tsan))
67 common.RegisterBottomUpMutator("tsan", sanitizerMutator(tsan))
Colin Cross463a90e2015-06-17 14:20:06 -070068}
69
Colin Cross3f40fa42015-01-30 17:27:36 -080070var (
Colin Cross1332b002015-04-07 17:11:30 -070071 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
Colin Cross3f40fa42015-01-30 17:27:36 -080072
Dan Willemsen34cc69e2015-09-23 15:26:20 -070073 LibcRoot = pctx.SourcePathVariable("LibcRoot", "bionic/libc")
Colin Cross3f40fa42015-01-30 17:27:36 -080074)
75
76// Flags used by lots of devices. Putting them in package static variables will save bytes in
77// build.ninja so they aren't repeated for every file
78var (
79 commonGlobalCflags = []string{
80 "-DANDROID",
81 "-fmessage-length=0",
82 "-W",
83 "-Wall",
84 "-Wno-unused",
85 "-Winit-self",
86 "-Wpointer-arith",
87
88 // COMMON_RELEASE_CFLAGS
89 "-DNDEBUG",
90 "-UDEBUG",
91 }
92
93 deviceGlobalCflags = []string{
Dan Willemsen490fd492015-11-24 17:53:15 -080094 "-fdiagnostics-color",
95
Colin Cross3f40fa42015-01-30 17:27:36 -080096 // TARGET_ERROR_FLAGS
97 "-Werror=return-type",
98 "-Werror=non-virtual-dtor",
99 "-Werror=address",
100 "-Werror=sequence-point",
Dan Willemsena6084a32016-03-01 15:16:50 -0800101 "-Werror=date-time",
Colin Cross3f40fa42015-01-30 17:27:36 -0800102 }
103
104 hostGlobalCflags = []string{}
105
106 commonGlobalCppflags = []string{
107 "-Wsign-promo",
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700108 }
109
Dan Willemsenbe03f342016-03-03 17:21:04 -0800110 noOverrideGlobalCflags = []string{
111 "-Werror=int-to-pointer-cast",
112 "-Werror=pointer-to-int-cast",
113 }
114
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700115 illegalFlags = []string{
116 "-w",
Colin Cross3f40fa42015-01-30 17:27:36 -0800117 }
118)
119
120func init() {
Dan Willemsen0c38c5e2016-03-29 17:31:57 -0700121 if common.CurrentHostType() == common.Linux {
122 commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
123 }
124
Colin Cross3f40fa42015-01-30 17:27:36 -0800125 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
126 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
127 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800128 pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800129
130 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
131
132 pctx.StaticVariable("commonClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800133 strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800134 pctx.StaticVariable("deviceClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800135 strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800136 pctx.StaticVariable("hostClangGlobalCflags",
137 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800138 pctx.StaticVariable("noOverrideClangGlobalCflags",
139 strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
140
Tim Kilbournf2948142015-03-11 12:03:03 -0700141 pctx.StaticVariable("commonClangGlobalCppflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800142 strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800143
144 // Everything in this list is a crime against abstraction and dependency tracking.
145 // Do not add anything to this list.
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800146 pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700147 []string{
148 "system/core/include",
Dan Willemsen98f93c72016-03-01 15:27:03 -0800149 "system/media/audio/include",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700150 "hardware/libhardware/include",
151 "hardware/libhardware_legacy/include",
152 "hardware/ril/include",
153 "libnativehelper/include",
154 "frameworks/native/include",
155 "frameworks/native/opengl/include",
156 "frameworks/av/include",
157 "frameworks/base/include",
158 })
Dan Willemsene0378dd2016-01-07 17:42:34 -0800159 // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
160 // with this, since there is no associated library.
161 pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
162 []string{"libnativehelper/include/nativehelper"})
Colin Cross3f40fa42015-01-30 17:27:36 -0800163
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700164 pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
165 pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
166 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
167 return override, nil
168 }
169 return "${clangDefaultBase}", nil
170 })
171 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
172 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
173 return override, nil
174 }
Stephen Hines369f0132016-04-26 14:34:07 -0700175 return "clang-2812033", nil
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700176 })
Colin Cross16b23492016-01-06 14:41:07 -0800177 pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}")
178 pctx.StaticVariable("clangBin", "${clangPath}/bin")
Colin Cross3f40fa42015-01-30 17:27:36 -0800179}
180
Colin Crossca860ac2016-01-04 14:34:37 -0800181type Deps struct {
182 SharedLibs, LateSharedLibs []string
183 StaticLibs, LateStaticLibs, WholeStaticLibs []string
Colin Crossc472d572015-03-17 15:06:21 -0700184
Colin Cross81413472016-04-11 14:37:39 -0700185 ObjFiles []string
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700186
Dan Willemsenb40aab62016-04-20 14:21:14 -0700187 GeneratedSources []string
188 GeneratedHeaders []string
189
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700190 Cflags, ReexportedCflags []string
Colin Cross21b9a242015-03-24 14:15:58 -0700191
Colin Cross97ba0732015-03-23 17:50:24 -0700192 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700193}
194
Colin Crossca860ac2016-01-04 14:34:37 -0800195type PathDeps struct {
196 SharedLibs, LateSharedLibs common.Paths
197 StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700198
199 ObjFiles common.Paths
200 WholeStaticLibObjFiles common.Paths
201
Dan Willemsenb40aab62016-04-20 14:21:14 -0700202 GeneratedSources common.Paths
203 GeneratedHeaders common.Paths
204
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700205 Cflags, ReexportedCflags []string
206
207 CrtBegin, CrtEnd common.OptionalPath
208}
209
Colin Crossca860ac2016-01-04 14:34:37 -0800210type Flags struct {
Colin Cross28344522015-04-22 13:07:53 -0700211 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
212 AsFlags []string // Flags that apply to assembly source files
213 CFlags []string // Flags that apply to C and C++ source files
214 ConlyFlags []string // Flags that apply to C source files
215 CppFlags []string // Flags that apply to C++ source files
216 YaccFlags []string // Flags that apply to Yacc source files
217 LdFlags []string // Flags that apply to linker command lines
Colin Cross16b23492016-01-06 14:41:07 -0800218 libFlags []string // Flags to add libraries early to the link order
Colin Cross28344522015-04-22 13:07:53 -0700219
220 Nocrt bool
221 Toolchain Toolchain
222 Clang bool
Colin Crossca860ac2016-01-04 14:34:37 -0800223
224 RequiredInstructionSet string
Colin Cross16b23492016-01-06 14:41:07 -0800225 DynamicLinker string
226
227 CFlagsDeps common.Paths // Files depended on by compiler flags
Colin Crossc472d572015-03-17 15:06:21 -0700228}
229
Colin Crossca860ac2016-01-04 14:34:37 -0800230type BaseCompilerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700231 // 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 -0700232 Srcs []string `android:"arch_variant"`
233
234 // list of source files that should not be used to build the C/C++ module.
235 // This is most useful in the arch/multilib variants to remove non-common files
236 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700237
238 // list of module-specific flags that will be used for C and C++ compiles.
239 Cflags []string `android:"arch_variant"`
240
241 // list of module-specific flags that will be used for C++ compiles
242 Cppflags []string `android:"arch_variant"`
243
244 // list of module-specific flags that will be used for C compiles
245 Conlyflags []string `android:"arch_variant"`
246
247 // list of module-specific flags that will be used for .S compiles
248 Asflags []string `android:"arch_variant"`
249
Colin Crossca860ac2016-01-04 14:34:37 -0800250 // list of module-specific flags that will be used for C and C++ compiles when
251 // compiling with clang
252 Clang_cflags []string `android:"arch_variant"`
253
254 // list of module-specific flags that will be used for .S compiles when
255 // compiling with clang
256 Clang_asflags []string `android:"arch_variant"`
257
Colin Cross7d5136f2015-05-11 13:39:40 -0700258 // list of module-specific flags that will be used for .y and .yy compiles
259 Yaccflags []string
260
Colin Cross7d5136f2015-05-11 13:39:40 -0700261 // the instruction set architecture to use to compile the C/C++
262 // module.
263 Instruction_set string `android:"arch_variant"`
264
265 // list of directories relative to the root of the source tree that will
266 // be added to the include path using -I.
267 // If possible, don't use this. If adding paths from the current directory use
268 // local_include_dirs, if adding paths from other modules use export_include_dirs in
269 // that module.
270 Include_dirs []string `android:"arch_variant"`
271
Colin Cross39d97f22015-09-14 12:30:50 -0700272 // list of files relative to the root of the source tree that will be included
273 // using -include.
274 // If possible, don't use this.
275 Include_files []string `android:"arch_variant"`
276
Colin Cross7d5136f2015-05-11 13:39:40 -0700277 // list of directories relative to the Blueprints file that will
278 // be added to the include path using -I
279 Local_include_dirs []string `android:"arch_variant"`
280
Colin Cross39d97f22015-09-14 12:30:50 -0700281 // list of files relative to the Blueprints file that will be included
282 // using -include.
283 // If possible, don't use this.
284 Local_include_files []string `android:"arch_variant"`
285
Dan Willemsenb40aab62016-04-20 14:21:14 -0700286 // list of generated sources to compile. These are the names of gensrcs or
287 // genrule modules.
288 Generated_sources []string `android:"arch_variant"`
289
290 // list of generated headers to add to the include path. These are the names
291 // of genrule modules.
292 Generated_headers []string `android:"arch_variant"`
293
Colin Crossca860ac2016-01-04 14:34:37 -0800294 // pass -frtti instead of -fno-rtti
295 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700296
Colin Crossca860ac2016-01-04 14:34:37 -0800297 Debug, Release struct {
298 // list of module-specific flags that will be used for C and C++ compiles in debug or
299 // release builds
300 Cflags []string `android:"arch_variant"`
301 } `android:"arch_variant"`
302}
Colin Cross7d5136f2015-05-11 13:39:40 -0700303
Colin Crossca860ac2016-01-04 14:34:37 -0800304type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700305 // list of modules whose object files should be linked into this module
306 // in their entirety. For static library modules, all of the .o files from the intermediate
307 // directory of the dependency will be linked into this modules .a file. For a shared library,
308 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
309 Whole_static_libs []string `android:"arch_variant"`
310
311 // list of modules that should be statically linked into this module.
312 Static_libs []string `android:"arch_variant"`
313
314 // list of modules that should be dynamically linked into this module.
315 Shared_libs []string `android:"arch_variant"`
316
Colin Crossca860ac2016-01-04 14:34:37 -0800317 // list of module-specific flags that will be used for all link steps
318 Ldflags []string `android:"arch_variant"`
319
320 // don't insert default compiler flags into asflags, cflags,
321 // cppflags, conlyflags, ldflags, or include_dirs
322 No_default_compiler_flags *bool
323
324 // list of system libraries that will be dynamically linked to
325 // shared library and executable modules. If unset, generally defaults to libc
326 // and libm. Set to [] to prevent linking against libc and libm.
327 System_shared_libs []string
328
Colin Cross7d5136f2015-05-11 13:39:40 -0700329 // allow the module to contain undefined symbols. By default,
330 // modules cannot contain undefined symbols that are not satisified by their immediate
331 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
332 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700333 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700334
Dan Willemsend67be222015-09-16 15:19:33 -0700335 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700336 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700337
Colin Cross7d5136f2015-05-11 13:39:40 -0700338 // -l arguments to pass to linker for host-provided shared libraries
339 Host_ldlibs []string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800340}
Colin Cross7d5136f2015-05-11 13:39:40 -0700341
Colin Crossca860ac2016-01-04 14:34:37 -0800342type LibraryCompilerProperties struct {
343 Static struct {
344 Srcs []string `android:"arch_variant"`
345 Exclude_srcs []string `android:"arch_variant"`
346 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700347 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800348 Shared struct {
349 Srcs []string `android:"arch_variant"`
350 Exclude_srcs []string `android:"arch_variant"`
351 Cflags []string `android:"arch_variant"`
352 } `android:"arch_variant"`
353}
354
Colin Cross919281a2016-04-05 16:42:05 -0700355type FlagExporterProperties struct {
356 // list of directories relative to the Blueprints file that will
357 // be added to the include path using -I for any module that links against this module
358 Export_include_dirs []string `android:"arch_variant"`
359}
360
Colin Crossca860ac2016-01-04 14:34:37 -0800361type LibraryLinkerProperties struct {
362 Static struct {
363 Whole_static_libs []string `android:"arch_variant"`
364 Static_libs []string `android:"arch_variant"`
365 Shared_libs []string `android:"arch_variant"`
366 } `android:"arch_variant"`
367 Shared struct {
368 Whole_static_libs []string `android:"arch_variant"`
369 Static_libs []string `android:"arch_variant"`
370 Shared_libs []string `android:"arch_variant"`
371 } `android:"arch_variant"`
372
373 // local file name to pass to the linker as --version_script
374 Version_script *string `android:"arch_variant"`
375 // local file name to pass to the linker as -unexported_symbols_list
376 Unexported_symbols_list *string `android:"arch_variant"`
377 // local file name to pass to the linker as -force_symbols_not_weak_list
378 Force_symbols_not_weak_list *string `android:"arch_variant"`
379 // local file name to pass to the linker as -force_symbols_weak_list
380 Force_symbols_weak_list *string `android:"arch_variant"`
381
Colin Crossca860ac2016-01-04 14:34:37 -0800382 // don't link in crt_begin and crt_end. This flag should only be necessary for
383 // compiling crt or libc.
384 Nocrt *bool `android:"arch_variant"`
Colin Cross16b23492016-01-06 14:41:07 -0800385
386 VariantName string `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800387}
388
389type BinaryLinkerProperties struct {
390 // compile executable with -static
391 Static_executable *bool
392
393 // set the name of the output
394 Stem string `android:"arch_variant"`
395
396 // append to the name of the output
397 Suffix string `android:"arch_variant"`
398
399 // if set, add an extra objcopy --prefix-symbols= step
400 Prefix_symbols string
401}
402
403type TestLinkerProperties struct {
404 // if set, build against the gtest library. Defaults to true.
405 Gtest bool
406
407 // Create a separate binary for each source file. Useful when there is
408 // global state that can not be torn down and reset between each test suite.
409 Test_per_src *bool
410}
411
Colin Cross81413472016-04-11 14:37:39 -0700412type ObjectLinkerProperties struct {
413 // names of other cc_object modules to link into this module using partial linking
414 Objs []string `android:"arch_variant"`
415}
416
Colin Crossca860ac2016-01-04 14:34:37 -0800417// Properties used to compile all C or C++ modules
418type BaseProperties struct {
419 // compile module with clang instead of gcc
420 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700421
422 // Minimum sdk version supported when compiling against the ndk
423 Sdk_version string
424
Colin Crossca860ac2016-01-04 14:34:37 -0800425 // don't insert default compiler flags into asflags, cflags,
426 // cppflags, conlyflags, ldflags, or include_dirs
427 No_default_compiler_flags *bool
Colin Crossc99deeb2016-04-11 15:06:20 -0700428
429 AndroidMkSharedLibs []string `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800430}
431
432type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700433 // install to a subdirectory of the default install path for the module
434 Relative_install_path string
435}
436
Colin Crossca860ac2016-01-04 14:34:37 -0800437type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700438 Native_coverage *bool
439 Required []string
440 Strip string
441 Tags []string
Colin Crosscfad1192015-11-02 16:43:11 -0800442}
443
Colin Crossca860ac2016-01-04 14:34:37 -0800444type ModuleContextIntf interface {
445 module() *Module
446 static() bool
447 staticBinary() bool
448 clang() bool
449 toolchain() Toolchain
450 noDefaultCompilerFlags() bool
451 sdk() bool
452 sdkVersion() string
453}
454
455type ModuleContext interface {
456 common.AndroidModuleContext
457 ModuleContextIntf
458}
459
460type BaseModuleContext interface {
461 common.AndroidBaseContext
462 ModuleContextIntf
463}
464
465type Customizer interface {
466 CustomizeProperties(BaseModuleContext)
467 Properties() []interface{}
468}
469
470type feature interface {
471 begin(ctx BaseModuleContext)
472 deps(ctx BaseModuleContext, deps Deps) Deps
473 flags(ctx ModuleContext, flags Flags) Flags
474 props() []interface{}
475}
476
477type compiler interface {
478 feature
Dan Willemsenb40aab62016-04-20 14:21:14 -0700479 compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800480}
481
482type linker interface {
483 feature
484 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
Colin Crossc99deeb2016-04-11 15:06:20 -0700485 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800486}
487
488type installer interface {
489 props() []interface{}
490 install(ctx ModuleContext, path common.Path)
491 inData() bool
492}
493
Colin Crossc99deeb2016-04-11 15:06:20 -0700494type dependencyTag struct {
495 blueprint.BaseDependencyTag
496 name string
497 library bool
498}
499
500var (
501 sharedDepTag = dependencyTag{name: "shared", library: true}
502 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
503 staticDepTag = dependencyTag{name: "static", library: true}
504 lateStaticDepTag = dependencyTag{name: "late static", library: true}
505 wholeStaticDepTag = dependencyTag{name: "whole static", library: true}
Dan Willemsenb40aab62016-04-20 14:21:14 -0700506 genSourceDepTag = dependencyTag{name: "gen source"}
507 genHeaderDepTag = dependencyTag{name: "gen header"}
Colin Crossc99deeb2016-04-11 15:06:20 -0700508 objDepTag = dependencyTag{name: "obj"}
509 crtBeginDepTag = dependencyTag{name: "crtbegin"}
510 crtEndDepTag = dependencyTag{name: "crtend"}
511 reuseObjTag = dependencyTag{name: "reuse objects"}
512)
513
Colin Crossca860ac2016-01-04 14:34:37 -0800514// Module contains the properties and members used by all C/C++ module types, and implements
515// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
516// to construct the output file. Behavior can be customized with a Customizer interface
517type Module struct {
Colin Crossc472d572015-03-17 15:06:21 -0700518 common.AndroidModuleBase
Colin Crosscfad1192015-11-02 16:43:11 -0800519 common.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700520
Colin Crossca860ac2016-01-04 14:34:37 -0800521 Properties BaseProperties
522 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700523
Colin Crossca860ac2016-01-04 14:34:37 -0800524 // initialize before calling Init
525 hod common.HostOrDeviceSupported
526 multilib common.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700527
Colin Crossca860ac2016-01-04 14:34:37 -0800528 // delegates, initialize before calling Init
529 customizer Customizer
530 features []feature
531 compiler compiler
532 linker linker
533 installer installer
Colin Crossa8e07cc2016-04-04 15:07:06 -0700534 stl *stl
Colin Cross16b23492016-01-06 14:41:07 -0800535 sanitize *sanitize
536
537 androidMkSharedLibDeps []string
Colin Cross74d1ec02015-04-28 13:30:13 -0700538
Colin Crossca860ac2016-01-04 14:34:37 -0800539 outputFile common.OptionalPath
540
541 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700542}
543
Colin Crossca860ac2016-01-04 14:34:37 -0800544func (c *Module) Init() (blueprint.Module, []interface{}) {
545 props := []interface{}{&c.Properties, &c.unused}
546 if c.customizer != nil {
547 props = append(props, c.customizer.Properties()...)
548 }
549 if c.compiler != nil {
550 props = append(props, c.compiler.props()...)
551 }
552 if c.linker != nil {
553 props = append(props, c.linker.props()...)
554 }
555 if c.installer != nil {
556 props = append(props, c.installer.props()...)
557 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700558 if c.stl != nil {
559 props = append(props, c.stl.props()...)
560 }
Colin Cross16b23492016-01-06 14:41:07 -0800561 if c.sanitize != nil {
562 props = append(props, c.sanitize.props()...)
563 }
Colin Crossca860ac2016-01-04 14:34:37 -0800564 for _, feature := range c.features {
565 props = append(props, feature.props()...)
566 }
Colin Crossc472d572015-03-17 15:06:21 -0700567
Colin Crossca860ac2016-01-04 14:34:37 -0800568 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700569
Colin Crossca860ac2016-01-04 14:34:37 -0800570 return common.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700571}
572
Colin Crossca860ac2016-01-04 14:34:37 -0800573type baseModuleContext struct {
574 common.AndroidBaseContext
575 moduleContextImpl
576}
577
578type moduleContext struct {
579 common.AndroidModuleContext
580 moduleContextImpl
581}
582
583type moduleContextImpl struct {
584 mod *Module
585 ctx BaseModuleContext
586}
587
588func (ctx *moduleContextImpl) module() *Module {
589 return ctx.mod
590}
591
592func (ctx *moduleContextImpl) clang() bool {
593 return ctx.mod.clang(ctx.ctx)
594}
595
596func (ctx *moduleContextImpl) toolchain() Toolchain {
597 return ctx.mod.toolchain(ctx.ctx)
598}
599
600func (ctx *moduleContextImpl) static() bool {
601 if ctx.mod.linker == nil {
602 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
603 }
604 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
605 return linker.static()
606 } else {
607 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
608 }
609}
610
611func (ctx *moduleContextImpl) staticBinary() bool {
612 if ctx.mod.linker == nil {
613 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
614 }
615 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
616 return linker.staticBinary()
617 } else {
618 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
619 }
620}
621
622func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
623 return Bool(ctx.mod.Properties.No_default_compiler_flags)
624}
625
626func (ctx *moduleContextImpl) sdk() bool {
627 return ctx.mod.Properties.Sdk_version != ""
628}
629
630func (ctx *moduleContextImpl) sdkVersion() string {
631 return ctx.mod.Properties.Sdk_version
632}
633
634func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
635 return &Module{
636 hod: hod,
637 multilib: multilib,
638 }
639}
640
641func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
642 module := newBaseModule(hod, multilib)
Colin Crossa8e07cc2016-04-04 15:07:06 -0700643 module.stl = &stl{}
Colin Cross16b23492016-01-06 14:41:07 -0800644 module.sanitize = &sanitize{}
Colin Crossca860ac2016-01-04 14:34:37 -0800645 return module
646}
647
648func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
649 ctx := &moduleContext{
650 AndroidModuleContext: actx,
651 moduleContextImpl: moduleContextImpl{
652 mod: c,
653 },
654 }
655 ctx.ctx = ctx
656
657 flags := Flags{
658 Toolchain: c.toolchain(ctx),
659 Clang: c.clang(ctx),
660 }
Colin Crossca860ac2016-01-04 14:34:37 -0800661 if c.compiler != nil {
662 flags = c.compiler.flags(ctx, flags)
663 }
664 if c.linker != nil {
665 flags = c.linker.flags(ctx, flags)
666 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700667 if c.stl != nil {
668 flags = c.stl.flags(ctx, flags)
669 }
Colin Cross16b23492016-01-06 14:41:07 -0800670 if c.sanitize != nil {
671 flags = c.sanitize.flags(ctx, flags)
672 }
Colin Crossca860ac2016-01-04 14:34:37 -0800673 for _, feature := range c.features {
674 flags = feature.flags(ctx, flags)
675 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800676 if ctx.Failed() {
677 return
678 }
679
Colin Crossca860ac2016-01-04 14:34:37 -0800680 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
681 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
682 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800683
Colin Crossca860ac2016-01-04 14:34:37 -0800684 // Optimization to reduce size of build.ninja
685 // Replace the long list of flags for each file with a module-local variable
686 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
687 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
688 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
689 flags.CFlags = []string{"$cflags"}
690 flags.CppFlags = []string{"$cppflags"}
691 flags.AsFlags = []string{"$asflags"}
692
Colin Crossc99deeb2016-04-11 15:06:20 -0700693 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800694 if ctx.Failed() {
695 return
696 }
697
Colin Cross28344522015-04-22 13:07:53 -0700698 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700699
Colin Crossca860ac2016-01-04 14:34:37 -0800700 var objFiles common.Paths
701 if c.compiler != nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700702 objFiles = c.compiler.compile(ctx, flags, deps)
Colin Crossca860ac2016-01-04 14:34:37 -0800703 if ctx.Failed() {
704 return
705 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800706 }
707
Colin Crossca860ac2016-01-04 14:34:37 -0800708 if c.linker != nil {
709 outputFile := c.linker.link(ctx, flags, deps, objFiles)
710 if ctx.Failed() {
711 return
712 }
713 c.outputFile = common.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700714
Colin Crossc99deeb2016-04-11 15:06:20 -0700715 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800716 c.installer.install(ctx, outputFile)
717 if ctx.Failed() {
718 return
719 }
720 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700721 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800722}
723
Colin Crossca860ac2016-01-04 14:34:37 -0800724func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
725 if c.cachedToolchain == nil {
726 arch := ctx.Arch()
727 hod := ctx.HostOrDevice()
728 ht := ctx.HostType()
729 factory := toolchainFactories[hod][ht][arch.ArchType]
730 if factory == nil {
731 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
732 return nil
733 }
734 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800735 }
Colin Crossca860ac2016-01-04 14:34:37 -0800736 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800737}
738
Colin Crossca860ac2016-01-04 14:34:37 -0800739func (c *Module) begin(ctx BaseModuleContext) {
740 if c.compiler != nil {
741 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700742 }
Colin Crossca860ac2016-01-04 14:34:37 -0800743 if c.linker != nil {
744 c.linker.begin(ctx)
745 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700746 if c.stl != nil {
747 c.stl.begin(ctx)
748 }
Colin Cross16b23492016-01-06 14:41:07 -0800749 if c.sanitize != nil {
750 c.sanitize.begin(ctx)
751 }
Colin Crossca860ac2016-01-04 14:34:37 -0800752 for _, feature := range c.features {
753 feature.begin(ctx)
754 }
755}
756
Colin Crossc99deeb2016-04-11 15:06:20 -0700757func (c *Module) deps(ctx BaseModuleContext) Deps {
758 deps := Deps{}
759
760 if c.compiler != nil {
761 deps = c.compiler.deps(ctx, deps)
762 }
763 if c.linker != nil {
764 deps = c.linker.deps(ctx, deps)
765 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700766 if c.stl != nil {
767 deps = c.stl.deps(ctx, deps)
768 }
Colin Cross16b23492016-01-06 14:41:07 -0800769 if c.sanitize != nil {
770 deps = c.sanitize.deps(ctx, deps)
771 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700772 for _, feature := range c.features {
773 deps = feature.deps(ctx, deps)
774 }
775
776 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
777 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
778 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
779 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
780 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
781
782 return deps
783}
784
Colin Crossca860ac2016-01-04 14:34:37 -0800785func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
786 ctx := &baseModuleContext{
787 AndroidBaseContext: actx,
788 moduleContextImpl: moduleContextImpl{
789 mod: c,
790 },
791 }
792 ctx.ctx = ctx
793
794 if c.customizer != nil {
795 c.customizer.CustomizeProperties(ctx)
796 }
797
798 c.begin(ctx)
799
Colin Crossc99deeb2016-04-11 15:06:20 -0700800 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800801
Colin Crossc99deeb2016-04-11 15:06:20 -0700802 c.Properties.AndroidMkSharedLibs = deps.SharedLibs
803
804 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
805 deps.WholeStaticLibs...)
806
807 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticDepTag,
808 deps.StaticLibs...)
809
810 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
811 deps.LateStaticLibs...)
812
813 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedDepTag,
814 deps.SharedLibs...)
815
816 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
817 deps.LateSharedLibs...)
818
Dan Willemsenb40aab62016-04-20 14:21:14 -0700819 actx.AddDependency(ctx.module(), genSourceDepTag, deps.GeneratedSources...)
820 actx.AddDependency(ctx.module(), genHeaderDepTag, deps.GeneratedHeaders...)
821
Colin Crossc99deeb2016-04-11 15:06:20 -0700822 actx.AddDependency(ctx.module(), objDepTag, deps.ObjFiles...)
823
824 if deps.CrtBegin != "" {
825 actx.AddDependency(ctx.module(), crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800826 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700827 if deps.CrtEnd != "" {
828 actx.AddDependency(ctx.module(), crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700829 }
Colin Cross6362e272015-10-29 15:25:03 -0700830}
Colin Cross21b9a242015-03-24 14:15:58 -0700831
Colin Cross6362e272015-10-29 15:25:03 -0700832func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800833 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700834 c.depsMutator(ctx)
835 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800836}
837
Colin Crossca860ac2016-01-04 14:34:37 -0800838func (c *Module) clang(ctx BaseModuleContext) bool {
839 clang := Bool(c.Properties.Clang)
840
841 if c.Properties.Clang == nil {
842 if ctx.Host() {
843 clang = true
844 }
845
846 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
847 clang = true
848 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800849 }
Colin Cross28344522015-04-22 13:07:53 -0700850
Colin Crossca860ac2016-01-04 14:34:37 -0800851 if !c.toolchain(ctx).ClangSupported() {
852 clang = false
853 }
854
855 return clang
856}
857
Colin Crossc99deeb2016-04-11 15:06:20 -0700858// Convert dependencies to paths. Returns a PathDeps containing paths
859func (c *Module) depsToPaths(ctx common.AndroidModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800860 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800861
Colin Crossc99deeb2016-04-11 15:06:20 -0700862 ctx.VisitDirectDeps(func(m blueprint.Module) {
863 name := ctx.OtherModuleName(m)
864 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800865
Colin Crossc99deeb2016-04-11 15:06:20 -0700866 a, _ := m.(common.AndroidModule)
867 if a == nil {
868 ctx.ModuleErrorf("module %q not an android module", name)
869 return
Colin Crossca860ac2016-01-04 14:34:37 -0800870 }
Colin Crossca860ac2016-01-04 14:34:37 -0800871
Colin Crossc99deeb2016-04-11 15:06:20 -0700872 c, _ := m.(*Module)
873 if c == nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700874 switch tag {
875 case common.DefaultsDepTag:
876 case genSourceDepTag:
877 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
878 depPaths.GeneratedSources = append(depPaths.GeneratedSources,
879 genRule.GeneratedSourceFiles()...)
880 } else {
881 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
882 }
883 case genHeaderDepTag:
884 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
885 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
886 genRule.GeneratedSourceFiles()...)
887 depPaths.Cflags = append(depPaths.Cflags,
888 includeDirsToFlags(common.Paths{genRule.GeneratedHeaderDir()}))
889 } else {
890 ctx.ModuleErrorf("module %q is not a genrule", name)
891 }
892 default:
Colin Crossc99deeb2016-04-11 15:06:20 -0700893 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -0800894 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700895 return
896 }
897
898 if !a.Enabled() {
899 ctx.ModuleErrorf("depends on disabled module %q", name)
900 return
901 }
902
903 if a.HostOrDevice() != ctx.HostOrDevice() {
904 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(), name)
905 return
906 }
907
908 if !c.outputFile.Valid() {
909 ctx.ModuleErrorf("module %q missing output file", name)
910 return
911 }
912
913 if tag == reuseObjTag {
914 depPaths.ObjFiles = append(depPaths.ObjFiles,
915 c.compiler.(*libraryCompiler).reuseObjFiles...)
916 return
917 }
918
919 var cflags []string
920 if t, _ := tag.(dependencyTag); t.library {
921 if i, ok := c.linker.(exportedFlagsProducer); ok {
922 cflags = i.exportedFlags()
923 depPaths.Cflags = append(depPaths.Cflags, cflags...)
924 }
925 }
926
927 var depPtr *common.Paths
928
929 switch tag {
930 case sharedDepTag:
931 depPtr = &depPaths.SharedLibs
932 case lateSharedDepTag:
933 depPtr = &depPaths.LateSharedLibs
934 case staticDepTag:
935 depPtr = &depPaths.StaticLibs
936 case lateStaticDepTag:
937 depPtr = &depPaths.LateStaticLibs
938 case wholeStaticDepTag:
939 depPtr = &depPaths.WholeStaticLibs
940 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, cflags...)
941 staticLib, _ := c.linker.(*libraryLinker)
942 if staticLib == nil || !staticLib.static() {
943 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
944 return
945 }
946
947 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
948 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
949 for i := range missingDeps {
950 missingDeps[i] += postfix
951 }
952 ctx.AddMissingDependencies(missingDeps)
953 }
954 depPaths.WholeStaticLibObjFiles =
955 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
956 case objDepTag:
957 depPtr = &depPaths.ObjFiles
958 case crtBeginDepTag:
959 depPaths.CrtBegin = c.outputFile
960 case crtEndDepTag:
961 depPaths.CrtEnd = c.outputFile
962 default:
963 panic(fmt.Errorf("unknown dependency tag: %s", ctx.OtherModuleDependencyTag(m)))
964 }
965
966 if depPtr != nil {
967 *depPtr = append(*depPtr, c.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -0800968 }
969 })
970
971 return depPaths
972}
973
974func (c *Module) InstallInData() bool {
975 if c.installer == nil {
976 return false
977 }
978 return c.installer.inData()
979}
980
Colin Cross16b23492016-01-06 14:41:07 -0800981type appendVariantName interface {
982 appendVariantName(string)
983}
984
985func (c *Module) appendVariantName(name string) {
986 if c.linker == nil {
987 return
988 }
989
990 if l, ok := c.linker.(appendVariantName); ok {
991 l.appendVariantName(name)
992 }
993}
994
Colin Crossca860ac2016-01-04 14:34:37 -0800995// Compiler
996
997type baseCompiler struct {
998 Properties BaseCompilerProperties
999}
1000
1001var _ compiler = (*baseCompiler)(nil)
1002
1003func (compiler *baseCompiler) props() []interface{} {
1004 return []interface{}{&compiler.Properties}
1005}
1006
Dan Willemsenb40aab62016-04-20 14:21:14 -07001007func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
1008
1009func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
1010 deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
1011 deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
1012
1013 return deps
1014}
Colin Crossca860ac2016-01-04 14:34:37 -08001015
1016// Create a Flags struct that collects the compile flags from global values,
1017// per-target values, module type values, and per-module Blueprints properties
1018func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1019 toolchain := ctx.toolchain()
1020
1021 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
1022 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
1023 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
1024 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
1025 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
1026
Colin Cross28344522015-04-22 13:07:53 -07001027 // Include dir cflags
Colin Crossca860ac2016-01-04 14:34:37 -08001028 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
1029 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -07001030 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -07001031 includeDirsToFlags(localIncludeDirs),
1032 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -07001033
Colin Crossca860ac2016-01-04 14:34:37 -08001034 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
1035 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -07001036
1037 flags.GlobalFlags = append(flags.GlobalFlags,
1038 includeFilesToFlags(rootIncludeFiles),
1039 includeFilesToFlags(localIncludeFiles))
1040
Colin Crossca860ac2016-01-04 14:34:37 -08001041 if !ctx.noDefaultCompilerFlags() {
1042 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -07001043 flags.GlobalFlags = append(flags.GlobalFlags,
1044 "${commonGlobalIncludes}",
1045 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -08001046 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -07001047 }
1048
1049 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001050 "-I" + common.PathForModuleSrc(ctx).String(),
1051 "-I" + common.PathForModuleOut(ctx).String(),
1052 "-I" + common.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -07001053 }...)
1054 }
1055
Colin Crossca860ac2016-01-04 14:34:37 -08001056 instructionSet := compiler.Properties.Instruction_set
1057 if flags.RequiredInstructionSet != "" {
1058 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -08001059 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001060 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
1061 if flags.Clang {
1062 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
1063 }
1064 if err != nil {
1065 ctx.ModuleErrorf("%s", err)
1066 }
1067
1068 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -08001069 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001070
Colin Cross97ba0732015-03-23 17:50:24 -07001071 if flags.Clang {
1072 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001073 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
1074 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -07001075 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
1076 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
1077 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001078
1079 target := "-target " + toolchain.ClangTriple()
1080 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
1081
Colin Cross97ba0732015-03-23 17:50:24 -07001082 flags.CFlags = append(flags.CFlags, target, gccPrefix)
1083 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
1084 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -08001085 }
1086
Colin Crossca860ac2016-01-04 14:34:37 -08001087 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001088 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1089
Colin Cross97ba0732015-03-23 17:50:24 -07001090 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001091 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001092 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001093 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001094 toolchain.ClangCflags(),
1095 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001096 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001097
1098 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001099 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001100 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001101 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001102 toolchain.Cflags(),
1103 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001104 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001105 }
1106
Colin Cross7b66f152015-12-15 16:07:43 -08001107 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1108 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1109 }
1110
Colin Crossf6566ed2015-03-24 11:13:38 -07001111 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001112 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001113 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001114 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001115 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001116 }
1117 }
1118
Colin Cross97ba0732015-03-23 17:50:24 -07001119 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001120
Colin Cross97ba0732015-03-23 17:50:24 -07001121 if flags.Clang {
1122 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001123 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001124 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001125 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001126 }
1127
Colin Crossc4bde762015-11-23 16:11:30 -08001128 if flags.Clang {
1129 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1130 } else {
1131 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001132 }
1133
Colin Crossca860ac2016-01-04 14:34:37 -08001134 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001135 if ctx.Host() && !flags.Clang {
1136 // The host GCC doesn't support C++14 (and is deprecated, so likely
1137 // never will). Build these modules with C++11.
1138 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1139 } else {
1140 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1141 }
1142 }
1143
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001144 // We can enforce some rules more strictly in the code we own. strict
1145 // indicates if this is code that we can be stricter with. If we have
1146 // rules that we want to apply to *our* code (but maybe can't for
1147 // vendor/device specific things), we could extend this to be a ternary
1148 // value.
1149 strict := true
1150 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1151 strict = false
1152 }
1153
1154 // Can be used to make some annotations stricter for code we can fix
1155 // (such as when we mark functions as deprecated).
1156 if strict {
1157 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1158 }
1159
Colin Cross3f40fa42015-01-30 17:27:36 -08001160 return flags
1161}
1162
Dan Willemsenb40aab62016-04-20 14:21:14 -07001163func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001164 // Compile files listed in c.Properties.Srcs into objects
Dan Willemsenb40aab62016-04-20 14:21:14 -07001165 objFiles := compiler.compileObjs(ctx, flags, "",
1166 compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
1167 deps.GeneratedSources, deps.GeneratedHeaders)
1168
Colin Crossca860ac2016-01-04 14:34:37 -08001169 if ctx.Failed() {
1170 return nil
1171 }
1172
Colin Crossca860ac2016-01-04 14:34:37 -08001173 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001174}
1175
1176// Compile a list of source files into objects a specified subdirectory
Colin Crossca860ac2016-01-04 14:34:37 -08001177func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001178 subdir string, srcFiles, excludes []string, extraSrcs, deps common.Paths) common.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001179
Colin Crossca860ac2016-01-04 14:34:37 -08001180 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001181
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001182 inputFiles := ctx.ExpandSources(srcFiles, excludes)
Dan Willemsenb40aab62016-04-20 14:21:14 -07001183 inputFiles = append(inputFiles, extraSrcs...)
1184 srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)
1185
1186 deps = append(deps, gendeps...)
Colin Cross16b23492016-01-06 14:41:07 -08001187 deps = append(deps, flags.CFlagsDeps...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001188
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001189 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001190}
1191
Colin Crossca860ac2016-01-04 14:34:37 -08001192// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1193type baseLinker struct {
1194 Properties BaseLinkerProperties
1195 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001196 VariantIsShared bool `blueprint:"mutated"`
1197 VariantIsStatic bool `blueprint:"mutated"`
1198 VariantIsStaticBinary bool `blueprint:"mutated"`
1199 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001200 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001201}
1202
Dan Willemsend30e6102016-03-30 17:35:50 -07001203func (linker *baseLinker) begin(ctx BaseModuleContext) {
1204 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001205 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001206 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001207 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001208 }
1209}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001210
Colin Crossca860ac2016-01-04 14:34:37 -08001211func (linker *baseLinker) props() []interface{} {
1212 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001213}
1214
Colin Crossca860ac2016-01-04 14:34:37 -08001215func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1216 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1217 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1218 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001219
Colin Cross74d1ec02015-04-28 13:30:13 -07001220 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001221 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001222 }
1223
Colin Crossf6566ed2015-03-24 11:13:38 -07001224 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001225 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001226 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1227 if !Bool(linker.Properties.No_libgcc) {
1228 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001229 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001230
Colin Crossca860ac2016-01-04 14:34:37 -08001231 if !linker.static() {
1232 if linker.Properties.System_shared_libs != nil {
1233 deps.LateSharedLibs = append(deps.LateSharedLibs,
1234 linker.Properties.System_shared_libs...)
1235 } else if !ctx.sdk() {
1236 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1237 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001238 }
Colin Cross577f6e42015-03-27 18:23:34 -07001239
Colin Crossca860ac2016-01-04 14:34:37 -08001240 if ctx.sdk() {
1241 version := ctx.sdkVersion()
1242 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001243 "ndk_libc."+version,
1244 "ndk_libm."+version,
1245 )
1246 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001247 }
1248
Colin Crossca860ac2016-01-04 14:34:37 -08001249 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001250}
1251
Colin Crossca860ac2016-01-04 14:34:37 -08001252func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1253 toolchain := ctx.toolchain()
1254
1255 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1256
1257 if !ctx.noDefaultCompilerFlags() {
1258 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1259 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1260 }
1261
1262 if flags.Clang {
1263 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1264 } else {
1265 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1266 }
1267
1268 if ctx.Host() {
1269 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1270 }
1271 }
1272
Dan Willemsend30e6102016-03-30 17:35:50 -07001273 if ctx.Host() && !linker.static() {
1274 rpath_prefix := `\$$ORIGIN/`
1275 if ctx.Darwin() {
1276 rpath_prefix = "@loader_path/"
1277 }
1278
Colin Crossc99deeb2016-04-11 15:06:20 -07001279 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001280 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1281 }
1282 }
1283
Dan Willemsene7174922016-03-30 17:33:52 -07001284 if flags.Clang {
1285 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1286 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001287 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1288 }
1289
1290 return flags
1291}
1292
1293func (linker *baseLinker) static() bool {
1294 return linker.dynamicProperties.VariantIsStatic
1295}
1296
1297func (linker *baseLinker) staticBinary() bool {
1298 return linker.dynamicProperties.VariantIsStaticBinary
1299}
1300
1301func (linker *baseLinker) setStatic(static bool) {
1302 linker.dynamicProperties.VariantIsStatic = static
1303}
1304
Colin Cross16b23492016-01-06 14:41:07 -08001305func (linker *baseLinker) isDependencyRoot() bool {
1306 return false
1307}
1308
Colin Crossca860ac2016-01-04 14:34:37 -08001309type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001310 // Returns true if the build options for the module have selected a static or shared build
1311 buildStatic() bool
1312 buildShared() bool
1313
1314 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001315 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001316
Colin Cross18b6dc52015-04-28 13:20:37 -07001317 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001318 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001319
1320 // Returns whether a module is a static binary
1321 staticBinary() bool
Colin Cross16b23492016-01-06 14:41:07 -08001322
1323 // Returns true for dependency roots (binaries)
1324 // TODO(ccross): also handle dlopenable libraries
1325 isDependencyRoot() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001326}
1327
Colin Crossca860ac2016-01-04 14:34:37 -08001328type baseInstaller struct {
1329 Properties InstallerProperties
1330
1331 dir string
1332 dir64 string
1333 data bool
1334
Colin Crossa2344662016-03-24 13:14:12 -07001335 path common.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001336}
1337
1338var _ installer = (*baseInstaller)(nil)
1339
1340func (installer *baseInstaller) props() []interface{} {
1341 return []interface{}{&installer.Properties}
1342}
1343
1344func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1345 subDir := installer.dir
1346 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1347 subDir = installer.dir64
1348 }
1349 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1350 installer.path = ctx.InstallFile(dir, file)
1351}
1352
1353func (installer *baseInstaller) inData() bool {
1354 return installer.data
1355}
1356
Colin Cross3f40fa42015-01-30 17:27:36 -08001357//
1358// Combined static+shared libraries
1359//
1360
Colin Cross919281a2016-04-05 16:42:05 -07001361type flagExporter struct {
1362 Properties FlagExporterProperties
1363
1364 flags []string
1365}
1366
1367func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
1368 includeDirs := common.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
1369 f.flags = append(f.flags, common.JoinWithPrefix(includeDirs.Strings(), inc))
1370}
1371
1372func (f *flagExporter) reexportFlags(flags []string) {
1373 f.flags = append(f.flags, flags...)
1374}
1375
1376func (f *flagExporter) exportedFlags() []string {
1377 return f.flags
1378}
1379
1380type exportedFlagsProducer interface {
1381 exportedFlags() []string
1382}
1383
1384var _ exportedFlagsProducer = (*flagExporter)(nil)
1385
Colin Crossca860ac2016-01-04 14:34:37 -08001386type libraryCompiler struct {
1387 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001388
Colin Crossca860ac2016-01-04 14:34:37 -08001389 linker *libraryLinker
1390 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001391
Colin Crossca860ac2016-01-04 14:34:37 -08001392 // For reusing static library objects for shared library
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001393 reuseObjFiles common.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001394}
1395
Colin Crossca860ac2016-01-04 14:34:37 -08001396var _ compiler = (*libraryCompiler)(nil)
1397
1398func (library *libraryCompiler) props() []interface{} {
1399 props := library.baseCompiler.props()
1400 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001401}
1402
Colin Crossca860ac2016-01-04 14:34:37 -08001403func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1404 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001405
Dan Willemsen490fd492015-11-24 17:53:15 -08001406 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1407 // all code is position independent, and then those warnings get promoted to
1408 // errors.
1409 if ctx.HostType() != common.Windows {
1410 flags.CFlags = append(flags.CFlags, "-fPIC")
1411 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001412
Colin Crossca860ac2016-01-04 14:34:37 -08001413 if library.linker.static() {
1414 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001415 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001416 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001417 }
1418
Colin Crossca860ac2016-01-04 14:34:37 -08001419 return flags
1420}
1421
Dan Willemsenb40aab62016-04-20 14:21:14 -07001422func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001423 var objFiles common.Paths
1424
Dan Willemsenb40aab62016-04-20 14:21:14 -07001425 objFiles = library.baseCompiler.compile(ctx, flags, deps)
Colin Crossc99deeb2016-04-11 15:06:20 -07001426 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001427
1428 if library.linker.static() {
1429 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001430 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
1431 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001432 } else {
1433 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001434 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
1435 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001436 }
1437
1438 return objFiles
1439}
1440
1441type libraryLinker struct {
1442 baseLinker
Colin Cross919281a2016-04-05 16:42:05 -07001443 flagExporter
Colin Crossca860ac2016-01-04 14:34:37 -08001444
1445 Properties LibraryLinkerProperties
1446
1447 dynamicProperties struct {
1448 BuildStatic bool `blueprint:"mutated"`
1449 BuildShared bool `blueprint:"mutated"`
1450 }
1451
Colin Crossca860ac2016-01-04 14:34:37 -08001452 // If we're used as a whole_static_lib, our missing dependencies need
1453 // to be given
1454 wholeStaticMissingDeps []string
1455
1456 // For whole_static_libs
1457 objFiles common.Paths
1458}
1459
1460var _ linker = (*libraryLinker)(nil)
Colin Cross16b23492016-01-06 14:41:07 -08001461var _ appendVariantName = (*libraryLinker)(nil)
Colin Crossca860ac2016-01-04 14:34:37 -08001462
1463func (library *libraryLinker) props() []interface{} {
1464 props := library.baseLinker.props()
Colin Cross919281a2016-04-05 16:42:05 -07001465 return append(props,
1466 &library.Properties,
1467 &library.dynamicProperties,
1468 &library.flagExporter.Properties)
Colin Crossca860ac2016-01-04 14:34:37 -08001469}
1470
1471func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1472 flags = library.baseLinker.flags(ctx, flags)
1473
1474 flags.Nocrt = Bool(library.Properties.Nocrt)
1475
1476 if !library.static() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001477 libName := ctx.ModuleName()
1478 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1479 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001480 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001481 sharedFlag = "-shared"
1482 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001483 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001484 flags.LdFlags = append(flags.LdFlags,
1485 "-nostdlib",
1486 "-Wl,--gc-sections",
1487 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001488 }
Colin Cross97ba0732015-03-23 17:50:24 -07001489
Colin Cross0af4b842015-04-30 16:36:18 -07001490 if ctx.Darwin() {
1491 flags.LdFlags = append(flags.LdFlags,
1492 "-dynamiclib",
1493 "-single_module",
1494 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001495 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001496 )
1497 } else {
1498 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001499 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001500 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001501 )
1502 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001503 }
Colin Cross97ba0732015-03-23 17:50:24 -07001504
1505 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001506}
1507
Colin Crossca860ac2016-01-04 14:34:37 -08001508func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1509 deps = library.baseLinker.deps(ctx, deps)
1510 if library.static() {
1511 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1512 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1513 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1514 } else {
1515 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1516 if !ctx.sdk() {
1517 deps.CrtBegin = "crtbegin_so"
1518 deps.CrtEnd = "crtend_so"
1519 } else {
1520 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1521 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1522 }
1523 }
1524 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1525 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1526 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1527 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001528
Colin Crossca860ac2016-01-04 14:34:37 -08001529 return deps
1530}
Colin Cross3f40fa42015-01-30 17:27:36 -08001531
Colin Crossca860ac2016-01-04 14:34:37 -08001532func (library *libraryLinker) linkStatic(ctx ModuleContext,
1533 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1534
Colin Cross21b9a242015-03-24 14:15:58 -07001535 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
Colin Crossca860ac2016-01-04 14:34:37 -08001536 library.objFiles = objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001537
Colin Cross16b23492016-01-06 14:41:07 -08001538 outputFile := common.PathForModuleOut(ctx,
1539 ctx.ModuleName()+library.Properties.VariantName+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001540
Colin Cross0af4b842015-04-30 16:36:18 -07001541 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001542 TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001543 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001544 TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001545 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001546
Colin Crossca860ac2016-01-04 14:34:37 -08001547 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001548
1549 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001550
1551 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001552}
1553
Colin Crossca860ac2016-01-04 14:34:37 -08001554func (library *libraryLinker) linkShared(ctx ModuleContext,
1555 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001556
Colin Cross16b23492016-01-06 14:41:07 -08001557 outputFile := common.PathForModuleOut(ctx,
1558 ctx.ModuleName()+library.Properties.VariantName+flags.Toolchain.ShlibSuffix())
Colin Cross3f40fa42015-01-30 17:27:36 -08001559
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001560 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001561
Colin Crossca860ac2016-01-04 14:34:37 -08001562 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1563 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1564 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1565 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001566 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001567 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001568 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001569 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001570 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001571 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001572 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1573 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001574 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001575 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1576 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001577 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001578 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1579 }
1580 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001581 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001582 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1583 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001584 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001585 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001586 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001587 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001588 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001589 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001590 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001591 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001592 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001593 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001594 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001595 }
Colin Crossaee540a2015-07-06 17:48:31 -07001596 }
1597
Colin Crossca860ac2016-01-04 14:34:37 -08001598 sharedLibs := deps.SharedLibs
1599 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001600
Colin Crossca860ac2016-01-04 14:34:37 -08001601 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1602 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
1603 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile)
1604
1605 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001606}
1607
Colin Crossca860ac2016-01-04 14:34:37 -08001608func (library *libraryLinker) link(ctx ModuleContext,
1609 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001610
Colin Crossc99deeb2016-04-11 15:06:20 -07001611 objFiles = append(objFiles, deps.ObjFiles...)
1612
Colin Crossca860ac2016-01-04 14:34:37 -08001613 var out common.Path
1614 if library.static() {
1615 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001616 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001617 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001618 }
1619
Colin Cross919281a2016-04-05 16:42:05 -07001620 library.exportIncludes(ctx, "-I")
1621 library.reexportFlags(deps.ReexportedCflags)
Colin Crossca860ac2016-01-04 14:34:37 -08001622
1623 return out
1624}
1625
1626func (library *libraryLinker) buildStatic() bool {
1627 return library.dynamicProperties.BuildStatic
1628}
1629
1630func (library *libraryLinker) buildShared() bool {
1631 return library.dynamicProperties.BuildShared
1632}
1633
1634func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1635 return library.wholeStaticMissingDeps
1636}
1637
Colin Crossc99deeb2016-04-11 15:06:20 -07001638func (library *libraryLinker) installable() bool {
1639 return !library.static()
1640}
1641
Colin Cross16b23492016-01-06 14:41:07 -08001642func (library *libraryLinker) appendVariantName(variant string) {
1643 library.Properties.VariantName += variant
1644}
1645
Colin Crossca860ac2016-01-04 14:34:37 -08001646type libraryInstaller struct {
1647 baseInstaller
1648
1649 linker *libraryLinker
1650}
1651
1652func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1653 if !library.linker.static() {
1654 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001655 }
1656}
1657
Colin Crossca860ac2016-01-04 14:34:37 -08001658func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1659 module := newModule(hod, common.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001660
Colin Crossca860ac2016-01-04 14:34:37 -08001661 linker := &libraryLinker{}
1662 linker.dynamicProperties.BuildShared = shared
1663 linker.dynamicProperties.BuildStatic = static
1664 module.linker = linker
1665
1666 module.compiler = &libraryCompiler{
1667 linker: linker,
1668 }
1669 module.installer = &libraryInstaller{
1670 baseInstaller: baseInstaller{
1671 dir: "lib",
1672 dir64: "lib64",
1673 },
1674 linker: linker,
Dan Albertc403f7c2015-03-18 14:01:18 -07001675 }
1676
Colin Crossca860ac2016-01-04 14:34:37 -08001677 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001678}
1679
Colin Crossca860ac2016-01-04 14:34:37 -08001680func libraryFactory() (blueprint.Module, []interface{}) {
1681 module := NewLibrary(common.HostAndDeviceSupported, true, true)
1682 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001683}
1684
Colin Cross3f40fa42015-01-30 17:27:36 -08001685//
1686// Objects (for crt*.o)
1687//
1688
Colin Crossca860ac2016-01-04 14:34:37 -08001689type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001690 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001691}
1692
Colin Crossca860ac2016-01-04 14:34:37 -08001693func objectFactory() (blueprint.Module, []interface{}) {
1694 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1695 module.compiler = &baseCompiler{}
1696 module.linker = &objectLinker{}
1697 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001698}
1699
Colin Cross81413472016-04-11 14:37:39 -07001700func (object *objectLinker) props() []interface{} {
1701 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001702}
1703
Colin Crossca860ac2016-01-04 14:34:37 -08001704func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001705
Colin Cross81413472016-04-11 14:37:39 -07001706func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1707 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001708 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001709}
1710
Colin Crossca860ac2016-01-04 14:34:37 -08001711func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001712 if flags.Clang {
1713 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1714 } else {
1715 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1716 }
1717
Colin Crossca860ac2016-01-04 14:34:37 -08001718 return flags
1719}
1720
1721func (object *objectLinker) link(ctx ModuleContext,
1722 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001723
Colin Cross97ba0732015-03-23 17:50:24 -07001724 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001725
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001726 var outputFile common.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001727 if len(objFiles) == 1 {
1728 outputFile = objFiles[0]
1729 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001730 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001731 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001732 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001733 }
1734
Colin Cross3f40fa42015-01-30 17:27:36 -08001735 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001736 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001737}
1738
Colin Crossc99deeb2016-04-11 15:06:20 -07001739func (*objectLinker) installable() bool {
1740 return false
1741}
1742
Colin Cross3f40fa42015-01-30 17:27:36 -08001743//
1744// Executables
1745//
1746
Colin Crossca860ac2016-01-04 14:34:37 -08001747type binaryLinker struct {
1748 baseLinker
Colin Cross7d5136f2015-05-11 13:39:40 -07001749
Colin Crossca860ac2016-01-04 14:34:37 -08001750 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001751
Colin Crossca860ac2016-01-04 14:34:37 -08001752 hostToolPath common.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001753}
1754
Colin Crossca860ac2016-01-04 14:34:37 -08001755var _ linker = (*binaryLinker)(nil)
1756
1757func (binary *binaryLinker) props() []interface{} {
1758 return append(binary.baseLinker.props(), &binary.Properties)
Colin Cross3f40fa42015-01-30 17:27:36 -08001759}
1760
Colin Crossca860ac2016-01-04 14:34:37 -08001761func (binary *binaryLinker) buildStatic() bool {
1762 return Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001763}
1764
Colin Crossca860ac2016-01-04 14:34:37 -08001765func (binary *binaryLinker) buildShared() bool {
1766 return !Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001767}
1768
Colin Crossca860ac2016-01-04 14:34:37 -08001769func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001770 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001771 if binary.Properties.Stem != "" {
1772 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001773 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001774
Colin Crossca860ac2016-01-04 14:34:37 -08001775 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001776}
1777
Colin Crossca860ac2016-01-04 14:34:37 -08001778func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1779 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001780 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001781 if !ctx.sdk() {
1782 if Bool(binary.Properties.Static_executable) {
1783 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001784 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001785 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001786 }
Colin Crossca860ac2016-01-04 14:34:37 -08001787 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001788 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001789 if Bool(binary.Properties.Static_executable) {
1790 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001791 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001792 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001793 }
Colin Crossca860ac2016-01-04 14:34:37 -08001794 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001795 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001796
Colin Crossca860ac2016-01-04 14:34:37 -08001797 if Bool(binary.Properties.Static_executable) {
1798 if inList("libc++_static", deps.StaticLibs) {
1799 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001800 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001801 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1802 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1803 // move them to the beginning of deps.LateStaticLibs
1804 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001805 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001806 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001807 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001808 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001809 }
Colin Crossca860ac2016-01-04 14:34:37 -08001810
1811 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1812 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1813 "from static libs or set static_executable: true")
1814 }
1815 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001816}
1817
Colin Crossc99deeb2016-04-11 15:06:20 -07001818func (*binaryLinker) installable() bool {
1819 return true
1820}
1821
Colin Cross16b23492016-01-06 14:41:07 -08001822func (binary *binaryLinker) isDependencyRoot() bool {
1823 return true
1824}
1825
Colin Crossca860ac2016-01-04 14:34:37 -08001826func NewBinary(hod common.HostOrDeviceSupported) *Module {
1827 module := newModule(hod, common.MultilibFirst)
1828 module.compiler = &baseCompiler{}
1829 module.linker = &binaryLinker{}
1830 module.installer = &baseInstaller{
1831 dir: "bin",
1832 }
1833 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001834}
1835
Colin Crossca860ac2016-01-04 14:34:37 -08001836func binaryFactory() (blueprint.Module, []interface{}) {
1837 module := NewBinary(common.HostAndDeviceSupported)
1838 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001839}
1840
Colin Crossca860ac2016-01-04 14:34:37 -08001841func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001842 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001843 binary.Properties.Static_executable = proptools.BoolPtr(false)
Colin Cross0af4b842015-04-30 16:36:18 -07001844 }
Colin Crossca860ac2016-01-04 14:34:37 -08001845 if Bool(binary.Properties.Static_executable) {
1846 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001847 }
1848}
1849
Colin Crossca860ac2016-01-04 14:34:37 -08001850func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1851 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001852
Dan Willemsen490fd492015-11-24 17:53:15 -08001853 if ctx.Host() {
1854 flags.LdFlags = append(flags.LdFlags, "-pie")
1855 if ctx.HostType() == common.Windows {
1856 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1857 }
1858 }
1859
1860 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1861 // all code is position independent, and then those warnings get promoted to
1862 // errors.
1863 if ctx.HostType() != common.Windows {
1864 flags.CFlags = append(flags.CFlags, "-fpie")
1865 }
Colin Cross97ba0732015-03-23 17:50:24 -07001866
Colin Crossf6566ed2015-03-24 11:13:38 -07001867 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001868 if Bool(binary.Properties.Static_executable) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001869 // Clang driver needs -static to create static executable.
1870 // However, bionic/linker uses -shared to overwrite.
1871 // Linker for x86 targets does not allow coexistance of -static and -shared,
1872 // so we add -static only if -shared is not used.
1873 if !inList("-shared", flags.LdFlags) {
1874 flags.LdFlags = append(flags.LdFlags, "-static")
1875 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001876
Colin Crossed4cf0b2015-03-26 14:43:45 -07001877 flags.LdFlags = append(flags.LdFlags,
1878 "-nostdlib",
1879 "-Bstatic",
1880 "-Wl,--gc-sections",
1881 )
1882
1883 } else {
Colin Cross16b23492016-01-06 14:41:07 -08001884 if flags.DynamicLinker == "" {
1885 flags.DynamicLinker = "/system/bin/linker"
1886 if flags.Toolchain.Is64Bit() {
1887 flags.DynamicLinker += "64"
1888 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001889 }
1890
1891 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001892 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001893 "-nostdlib",
1894 "-Bdynamic",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001895 "-Wl,--gc-sections",
1896 "-Wl,-z,nocopyreloc",
1897 )
1898 }
Colin Cross0af4b842015-04-30 16:36:18 -07001899 } else if ctx.Darwin() {
1900 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001901 }
1902
Colin Cross97ba0732015-03-23 17:50:24 -07001903 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001904}
1905
Colin Crossca860ac2016-01-04 14:34:37 -08001906func (binary *binaryLinker) link(ctx ModuleContext,
1907 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001908
Colin Crossca860ac2016-01-04 14:34:37 -08001909 outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
1910 if ctx.HostOrDevice().Host() {
1911 binary.hostToolPath = common.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001912 }
Colin Crossca860ac2016-01-04 14:34:37 -08001913 ret := outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001914
Colin Crossca860ac2016-01-04 14:34:37 -08001915 if binary.Properties.Prefix_symbols != "" {
Colin Crossbfae8852015-03-26 14:44:11 -07001916 afterPrefixSymbols := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001917 outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate")
1918 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1919 flagsToBuilderFlags(flags), afterPrefixSymbols)
Colin Crossbfae8852015-03-26 14:44:11 -07001920 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001921
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001922 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001923
Colin Crossca860ac2016-01-04 14:34:37 -08001924 sharedLibs := deps.SharedLibs
1925 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1926
Colin Cross16b23492016-01-06 14:41:07 -08001927 if flags.DynamicLinker != "" {
1928 flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
1929 }
1930
Colin Crossca860ac2016-01-04 14:34:37 -08001931 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001932 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Crossca860ac2016-01-04 14:34:37 -08001933 flagsToBuilderFlags(flags), outputFile)
1934
1935 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001936}
Colin Cross3f40fa42015-01-30 17:27:36 -08001937
Colin Crossca860ac2016-01-04 14:34:37 -08001938func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1939 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001940}
1941
Colin Cross6362e272015-10-29 15:25:03 -07001942func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08001943 if m, ok := mctx.Module().(*Module); ok {
1944 if test, ok := m.linker.(*testLinker); ok {
1945 if Bool(test.Properties.Test_per_src) {
1946 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
1947 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1948 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
1949 }
1950 tests := mctx.CreateLocalVariations(testNames...)
1951 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
1952 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
1953 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
1954 }
Colin Cross6002e052015-09-16 16:00:08 -07001955 }
1956 }
1957 }
Colin Cross7d5136f2015-05-11 13:39:40 -07001958}
1959
Colin Crossca860ac2016-01-04 14:34:37 -08001960type testLinker struct {
1961 binaryLinker
1962 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001963}
1964
Dan Willemsend30e6102016-03-30 17:35:50 -07001965func (test *testLinker) begin(ctx BaseModuleContext) {
1966 test.binaryLinker.begin(ctx)
1967
1968 runpath := "../../lib"
1969 if ctx.toolchain().Is64Bit() {
1970 runpath += "64"
1971 }
Colin Crossc99deeb2016-04-11 15:06:20 -07001972 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
Dan Willemsend30e6102016-03-30 17:35:50 -07001973}
1974
Colin Crossca860ac2016-01-04 14:34:37 -08001975func (test *testLinker) props() []interface{} {
1976 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07001977}
1978
Colin Crossca860ac2016-01-04 14:34:37 -08001979func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
1980 flags = test.binaryLinker.flags(ctx, flags)
1981
1982 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001983 return flags
1984 }
Dan Albertc403f7c2015-03-18 14:01:18 -07001985
Colin Cross97ba0732015-03-23 17:50:24 -07001986 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07001987 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07001988 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08001989
1990 if ctx.HostType() == common.Windows {
1991 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
1992 } else {
1993 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
1994 flags.LdFlags = append(flags.LdFlags, "-lpthread")
1995 }
1996 } else {
1997 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07001998 }
1999
Colin Cross21b9a242015-03-24 14:15:58 -07002000 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07002001}
2002
Colin Crossca860ac2016-01-04 14:34:37 -08002003func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2004 if test.Properties.Gtest {
2005 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002006 }
Colin Crossca860ac2016-01-04 14:34:37 -08002007 deps = test.binaryLinker.deps(ctx, deps)
2008 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07002009}
2010
Colin Crossca860ac2016-01-04 14:34:37 -08002011type testInstaller struct {
2012 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08002013}
2014
Colin Crossca860ac2016-01-04 14:34:37 -08002015func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
2016 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
2017 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
2018 installer.baseInstaller.install(ctx, file)
2019}
2020
2021func NewTest(hod common.HostOrDeviceSupported) *Module {
2022 module := newModule(hod, common.MultilibBoth)
2023 module.compiler = &baseCompiler{}
2024 linker := &testLinker{}
2025 linker.Properties.Gtest = true
2026 module.linker = linker
2027 module.installer = &testInstaller{
2028 baseInstaller: baseInstaller{
2029 dir: "nativetest",
2030 dir64: "nativetest64",
2031 data: true,
2032 },
Dan Albertc403f7c2015-03-18 14:01:18 -07002033 }
Colin Crossca860ac2016-01-04 14:34:37 -08002034 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002035}
2036
Colin Crossca860ac2016-01-04 14:34:37 -08002037func testFactory() (blueprint.Module, []interface{}) {
2038 module := NewTest(common.HostAndDeviceSupported)
2039 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07002040}
2041
Colin Crossca860ac2016-01-04 14:34:37 -08002042type benchmarkLinker struct {
2043 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07002044}
2045
Colin Crossca860ac2016-01-04 14:34:37 -08002046func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2047 deps = benchmark.binaryLinker.deps(ctx, deps)
2048 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
2049 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07002050}
2051
Colin Crossca860ac2016-01-04 14:34:37 -08002052func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
2053 module := newModule(hod, common.MultilibFirst)
2054 module.compiler = &baseCompiler{}
2055 module.linker = &benchmarkLinker{}
2056 module.installer = &baseInstaller{
2057 dir: "nativetest",
2058 dir64: "nativetest64",
2059 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07002060 }
Colin Crossca860ac2016-01-04 14:34:37 -08002061 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07002062}
2063
Colin Crossca860ac2016-01-04 14:34:37 -08002064func benchmarkFactory() (blueprint.Module, []interface{}) {
2065 module := NewBenchmark(common.HostAndDeviceSupported)
2066 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002067}
2068
Colin Cross3f40fa42015-01-30 17:27:36 -08002069//
2070// Static library
2071//
2072
Colin Crossca860ac2016-01-04 14:34:37 -08002073func libraryStaticFactory() (blueprint.Module, []interface{}) {
2074 module := NewLibrary(common.HostAndDeviceSupported, false, true)
2075 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002076}
2077
2078//
2079// Shared libraries
2080//
2081
Colin Crossca860ac2016-01-04 14:34:37 -08002082func librarySharedFactory() (blueprint.Module, []interface{}) {
2083 module := NewLibrary(common.HostAndDeviceSupported, true, false)
2084 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002085}
2086
2087//
2088// Host static library
2089//
2090
Colin Crossca860ac2016-01-04 14:34:37 -08002091func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
2092 module := NewLibrary(common.HostSupported, false, true)
2093 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002094}
2095
2096//
2097// Host Shared libraries
2098//
2099
Colin Crossca860ac2016-01-04 14:34:37 -08002100func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
2101 module := NewLibrary(common.HostSupported, true, false)
2102 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002103}
2104
2105//
2106// Host Binaries
2107//
2108
Colin Crossca860ac2016-01-04 14:34:37 -08002109func binaryHostFactory() (blueprint.Module, []interface{}) {
2110 module := NewBinary(common.HostSupported)
2111 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002112}
2113
2114//
Colin Cross1f8f2342015-03-26 16:09:47 -07002115// Host Tests
2116//
2117
Colin Crossca860ac2016-01-04 14:34:37 -08002118func testHostFactory() (blueprint.Module, []interface{}) {
2119 module := NewTest(common.HostSupported)
2120 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07002121}
2122
2123//
Colin Cross2ba19d92015-05-07 15:44:20 -07002124// Host Benchmarks
2125//
2126
Colin Crossca860ac2016-01-04 14:34:37 -08002127func benchmarkHostFactory() (blueprint.Module, []interface{}) {
2128 module := NewBenchmark(common.HostSupported)
2129 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002130}
2131
2132//
Colin Crosscfad1192015-11-02 16:43:11 -08002133// Defaults
2134//
Colin Crossca860ac2016-01-04 14:34:37 -08002135type Defaults struct {
Colin Crosscfad1192015-11-02 16:43:11 -08002136 common.AndroidModuleBase
2137 common.DefaultsModule
2138}
2139
Colin Crossca860ac2016-01-04 14:34:37 -08002140func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002141}
2142
Colin Crossca860ac2016-01-04 14:34:37 -08002143func defaultsFactory() (blueprint.Module, []interface{}) {
2144 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002145
2146 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002147 &BaseProperties{},
2148 &BaseCompilerProperties{},
2149 &BaseLinkerProperties{},
2150 &LibraryCompilerProperties{},
Colin Cross919281a2016-04-05 16:42:05 -07002151 &FlagExporterProperties{},
Colin Crossca860ac2016-01-04 14:34:37 -08002152 &LibraryLinkerProperties{},
2153 &BinaryLinkerProperties{},
2154 &TestLinkerProperties{},
2155 &UnusedProperties{},
2156 &StlProperties{},
Colin Cross16b23492016-01-06 14:41:07 -08002157 &SanitizeProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002158 }
2159
Dan Willemsen218f6562015-07-08 18:13:11 -07002160 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
2161 common.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002162
2163 return common.InitDefaultsModule(module, module, propertyStructs...)
2164}
2165
2166//
Colin Cross3f40fa42015-01-30 17:27:36 -08002167// Device libraries shipped with gcc
2168//
2169
Colin Crossca860ac2016-01-04 14:34:37 -08002170type toolchainLibraryLinker struct {
2171 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002172}
2173
Colin Crossca860ac2016-01-04 14:34:37 -08002174var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2175
2176func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002177 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002178 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002179}
2180
Colin Crossca860ac2016-01-04 14:34:37 -08002181func (*toolchainLibraryLinker) buildStatic() bool {
2182 return true
2183}
Colin Cross3f40fa42015-01-30 17:27:36 -08002184
Colin Crossca860ac2016-01-04 14:34:37 -08002185func (*toolchainLibraryLinker) buildShared() bool {
2186 return false
2187}
2188
2189func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
2190 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2191 module.compiler = &baseCompiler{}
2192 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002193 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002194 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002195}
2196
Colin Crossca860ac2016-01-04 14:34:37 -08002197func (library *toolchainLibraryLinker) link(ctx ModuleContext,
2198 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002199
2200 libName := ctx.ModuleName() + staticLibraryExtension
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002201 outputFile := common.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002202
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002203 if flags.Clang {
2204 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2205 }
2206
Colin Crossca860ac2016-01-04 14:34:37 -08002207 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002208
2209 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002210
Colin Crossca860ac2016-01-04 14:34:37 -08002211 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002212}
2213
Colin Crossc99deeb2016-04-11 15:06:20 -07002214func (*toolchainLibraryLinker) installable() bool {
2215 return false
2216}
2217
Dan Albertbe961682015-03-18 23:38:50 -07002218// NDK prebuilt libraries.
2219//
2220// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2221// either (with the exception of the shared STLs, which are installed to the app's directory rather
2222// than to the system image).
2223
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002224func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2225 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2226 version, toolchain.Name()))
Dan Albertbe961682015-03-18 23:38:50 -07002227}
2228
Dan Albertc3144b12015-04-28 18:17:56 -07002229func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002230 ext string, version string) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002231
2232 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2233 // We want to translate to just NAME.EXT
2234 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2235 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002236 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002237}
2238
Colin Crossca860ac2016-01-04 14:34:37 -08002239type ndkPrebuiltObjectLinker struct {
2240 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002241}
2242
Colin Crossca860ac2016-01-04 14:34:37 -08002243func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002244 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002245 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002246}
2247
Colin Crossca860ac2016-01-04 14:34:37 -08002248func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2249 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2250 module.linker = &ndkPrebuiltObjectLinker{}
2251 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002252}
2253
Colin Crossca860ac2016-01-04 14:34:37 -08002254func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2255 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002256 // A null build step, but it sets up the output path.
2257 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2258 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2259 }
2260
Colin Crossca860ac2016-01-04 14:34:37 -08002261 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002262}
2263
Colin Crossca860ac2016-01-04 14:34:37 -08002264type ndkPrebuiltLibraryLinker struct {
2265 libraryLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002266}
2267
Colin Crossca860ac2016-01-04 14:34:37 -08002268var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2269var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002270
Colin Crossca860ac2016-01-04 14:34:37 -08002271func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Cross919281a2016-04-05 16:42:05 -07002272 return append(ndk.libraryLinker.props(), &ndk.Properties, &ndk.flagExporter.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002273}
2274
Colin Crossca860ac2016-01-04 14:34:37 -08002275func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002276 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002277 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002278}
2279
Colin Crossca860ac2016-01-04 14:34:37 -08002280func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2281 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2282 linker := &ndkPrebuiltLibraryLinker{}
2283 linker.dynamicProperties.BuildShared = true
2284 module.linker = linker
2285 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002286}
2287
Colin Crossca860ac2016-01-04 14:34:37 -08002288func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2289 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002290 // A null build step, but it sets up the output path.
2291 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2292 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2293 }
2294
Colin Cross919281a2016-04-05 16:42:05 -07002295 ndk.exportIncludes(ctx, "-isystem")
Dan Albertbe961682015-03-18 23:38:50 -07002296
Colin Crossca860ac2016-01-04 14:34:37 -08002297 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2298 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002299}
2300
2301// The NDK STLs are slightly different from the prebuilt system libraries:
2302// * Are not specific to each platform version.
2303// * The libraries are not in a predictable location for each STL.
2304
Colin Crossca860ac2016-01-04 14:34:37 -08002305type ndkPrebuiltStlLinker struct {
2306 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002307}
2308
Colin Crossca860ac2016-01-04 14:34:37 -08002309func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2310 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2311 linker := &ndkPrebuiltStlLinker{}
2312 linker.dynamicProperties.BuildShared = true
2313 module.linker = linker
2314 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002315}
2316
Colin Crossca860ac2016-01-04 14:34:37 -08002317func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2318 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2319 linker := &ndkPrebuiltStlLinker{}
2320 linker.dynamicProperties.BuildStatic = true
2321 module.linker = linker
2322 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002323}
2324
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002325func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002326 gccVersion := toolchain.GccVersion()
2327 var libDir string
2328 switch stl {
2329 case "libstlport":
2330 libDir = "cxx-stl/stlport/libs"
2331 case "libc++":
2332 libDir = "cxx-stl/llvm-libc++/libs"
2333 case "libgnustl":
2334 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2335 }
2336
2337 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002338 ndkSrcRoot := "prebuilts/ndk/current/sources"
2339 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002340 }
2341
2342 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002343 return common.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002344}
2345
Colin Crossca860ac2016-01-04 14:34:37 -08002346func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2347 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002348 // A null build step, but it sets up the output path.
2349 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2350 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2351 }
2352
Colin Cross919281a2016-04-05 16:42:05 -07002353 ndk.exportIncludes(ctx, "-I")
Dan Albertbe961682015-03-18 23:38:50 -07002354
2355 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002356 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002357 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002358 libExt = staticLibraryExtension
2359 }
2360
2361 stlName := strings.TrimSuffix(libName, "_shared")
2362 stlName = strings.TrimSuffix(stlName, "_static")
2363 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002364 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002365}
2366
Colin Cross6362e272015-10-29 15:25:03 -07002367func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002368 if m, ok := mctx.Module().(*Module); ok {
2369 if m.linker != nil {
2370 if linker, ok := m.linker.(baseLinkerInterface); ok {
2371 var modules []blueprint.Module
2372 if linker.buildStatic() && linker.buildShared() {
2373 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002374 static := modules[0].(*Module)
2375 shared := modules[1].(*Module)
2376
2377 static.linker.(baseLinkerInterface).setStatic(true)
2378 shared.linker.(baseLinkerInterface).setStatic(false)
2379
2380 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2381 sharedCompiler := shared.compiler.(*libraryCompiler)
2382 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2383 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2384 // Optimize out compiling common .o files twice for static+shared libraries
2385 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2386 sharedCompiler.baseCompiler.Properties.Srcs = nil
2387 }
2388 }
Colin Crossca860ac2016-01-04 14:34:37 -08002389 } else if linker.buildStatic() {
2390 modules = mctx.CreateLocalVariations("static")
2391 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2392 } else if linker.buildShared() {
2393 modules = mctx.CreateLocalVariations("shared")
2394 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2395 } else {
2396 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2397 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002398 }
2399 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002400 }
2401}
Colin Cross74d1ec02015-04-28 13:30:13 -07002402
2403// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2404// modifies the slice contents in place, and returns a subslice of the original slice
2405func lastUniqueElements(list []string) []string {
2406 totalSkip := 0
2407 for i := len(list) - 1; i >= totalSkip; i-- {
2408 skip := 0
2409 for j := i - 1; j >= totalSkip; j-- {
2410 if list[i] == list[j] {
2411 skip++
2412 } else {
2413 list[j+skip] = list[j]
2414 }
2415 }
2416 totalSkip += skip
2417 }
2418 return list[totalSkip:]
2419}
Colin Cross06a931b2015-10-28 17:23:31 -07002420
2421var Bool = proptools.Bool