blob: e65043549810e0b166a759984967fb91791be886 [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.
Colin Cross6ee75b62016-05-05 15:57:15 -0700309 Whole_static_libs []string `android:"arch_variant,variant_prepend"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700310
311 // list of modules that should be statically linked into this module.
Colin Cross6ee75b62016-05-05 15:57:15 -0700312 Static_libs []string `android:"arch_variant,variant_prepend"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700313
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 Cross665dce92016-04-28 14:50:03 -0700437type StripProperties struct {
438 Strip struct {
439 None bool
440 Keep_symbols bool
441 }
442}
443
Colin Crossca860ac2016-01-04 14:34:37 -0800444type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700445 Native_coverage *bool
446 Required []string
Colin Cross21b481b2016-04-15 16:27:17 -0700447 Tags []string
Colin Crosscfad1192015-11-02 16:43:11 -0800448}
449
Colin Crossca860ac2016-01-04 14:34:37 -0800450type ModuleContextIntf interface {
451 module() *Module
452 static() bool
453 staticBinary() bool
454 clang() bool
455 toolchain() Toolchain
456 noDefaultCompilerFlags() bool
457 sdk() bool
458 sdkVersion() string
459}
460
461type ModuleContext interface {
462 common.AndroidModuleContext
463 ModuleContextIntf
464}
465
466type BaseModuleContext interface {
467 common.AndroidBaseContext
468 ModuleContextIntf
469}
470
471type Customizer interface {
472 CustomizeProperties(BaseModuleContext)
473 Properties() []interface{}
474}
475
476type feature interface {
477 begin(ctx BaseModuleContext)
478 deps(ctx BaseModuleContext, deps Deps) Deps
479 flags(ctx ModuleContext, flags Flags) Flags
480 props() []interface{}
481}
482
483type compiler interface {
484 feature
Dan Willemsenb40aab62016-04-20 14:21:14 -0700485 compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800486}
487
488type linker interface {
489 feature
490 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path
Colin Crossc99deeb2016-04-11 15:06:20 -0700491 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800492}
493
494type installer interface {
495 props() []interface{}
496 install(ctx ModuleContext, path common.Path)
497 inData() bool
498}
499
Colin Crossc99deeb2016-04-11 15:06:20 -0700500type dependencyTag struct {
501 blueprint.BaseDependencyTag
502 name string
503 library bool
504}
505
506var (
507 sharedDepTag = dependencyTag{name: "shared", library: true}
508 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
509 staticDepTag = dependencyTag{name: "static", library: true}
510 lateStaticDepTag = dependencyTag{name: "late static", library: true}
511 wholeStaticDepTag = dependencyTag{name: "whole static", library: true}
Dan Willemsenb40aab62016-04-20 14:21:14 -0700512 genSourceDepTag = dependencyTag{name: "gen source"}
513 genHeaderDepTag = dependencyTag{name: "gen header"}
Colin Crossc99deeb2016-04-11 15:06:20 -0700514 objDepTag = dependencyTag{name: "obj"}
515 crtBeginDepTag = dependencyTag{name: "crtbegin"}
516 crtEndDepTag = dependencyTag{name: "crtend"}
517 reuseObjTag = dependencyTag{name: "reuse objects"}
518)
519
Colin Crossca860ac2016-01-04 14:34:37 -0800520// Module contains the properties and members used by all C/C++ module types, and implements
521// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
522// to construct the output file. Behavior can be customized with a Customizer interface
523type Module struct {
Colin Crossc472d572015-03-17 15:06:21 -0700524 common.AndroidModuleBase
Colin Crosscfad1192015-11-02 16:43:11 -0800525 common.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700526
Colin Crossca860ac2016-01-04 14:34:37 -0800527 Properties BaseProperties
528 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700529
Colin Crossca860ac2016-01-04 14:34:37 -0800530 // initialize before calling Init
531 hod common.HostOrDeviceSupported
532 multilib common.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700533
Colin Crossca860ac2016-01-04 14:34:37 -0800534 // delegates, initialize before calling Init
535 customizer Customizer
536 features []feature
537 compiler compiler
538 linker linker
539 installer installer
Colin Crossa8e07cc2016-04-04 15:07:06 -0700540 stl *stl
Colin Cross16b23492016-01-06 14:41:07 -0800541 sanitize *sanitize
542
543 androidMkSharedLibDeps []string
Colin Cross74d1ec02015-04-28 13:30:13 -0700544
Colin Crossca860ac2016-01-04 14:34:37 -0800545 outputFile common.OptionalPath
546
547 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700548}
549
Colin Crossca860ac2016-01-04 14:34:37 -0800550func (c *Module) Init() (blueprint.Module, []interface{}) {
551 props := []interface{}{&c.Properties, &c.unused}
552 if c.customizer != nil {
553 props = append(props, c.customizer.Properties()...)
554 }
555 if c.compiler != nil {
556 props = append(props, c.compiler.props()...)
557 }
558 if c.linker != nil {
559 props = append(props, c.linker.props()...)
560 }
561 if c.installer != nil {
562 props = append(props, c.installer.props()...)
563 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700564 if c.stl != nil {
565 props = append(props, c.stl.props()...)
566 }
Colin Cross16b23492016-01-06 14:41:07 -0800567 if c.sanitize != nil {
568 props = append(props, c.sanitize.props()...)
569 }
Colin Crossca860ac2016-01-04 14:34:37 -0800570 for _, feature := range c.features {
571 props = append(props, feature.props()...)
572 }
Colin Crossc472d572015-03-17 15:06:21 -0700573
Colin Crossca860ac2016-01-04 14:34:37 -0800574 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700575
Colin Crossca860ac2016-01-04 14:34:37 -0800576 return common.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700577}
578
Colin Crossca860ac2016-01-04 14:34:37 -0800579type baseModuleContext struct {
580 common.AndroidBaseContext
581 moduleContextImpl
582}
583
584type moduleContext struct {
585 common.AndroidModuleContext
586 moduleContextImpl
587}
588
589type moduleContextImpl struct {
590 mod *Module
591 ctx BaseModuleContext
592}
593
594func (ctx *moduleContextImpl) module() *Module {
595 return ctx.mod
596}
597
598func (ctx *moduleContextImpl) clang() bool {
599 return ctx.mod.clang(ctx.ctx)
600}
601
602func (ctx *moduleContextImpl) toolchain() Toolchain {
603 return ctx.mod.toolchain(ctx.ctx)
604}
605
606func (ctx *moduleContextImpl) static() bool {
607 if ctx.mod.linker == nil {
608 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
609 }
610 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
611 return linker.static()
612 } else {
613 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
614 }
615}
616
617func (ctx *moduleContextImpl) staticBinary() bool {
618 if ctx.mod.linker == nil {
619 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
620 }
621 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
622 return linker.staticBinary()
623 } else {
624 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
625 }
626}
627
628func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
629 return Bool(ctx.mod.Properties.No_default_compiler_flags)
630}
631
632func (ctx *moduleContextImpl) sdk() bool {
633 return ctx.mod.Properties.Sdk_version != ""
634}
635
636func (ctx *moduleContextImpl) sdkVersion() string {
637 return ctx.mod.Properties.Sdk_version
638}
639
640func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
641 return &Module{
642 hod: hod,
643 multilib: multilib,
644 }
645}
646
647func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module {
648 module := newBaseModule(hod, multilib)
Colin Crossa8e07cc2016-04-04 15:07:06 -0700649 module.stl = &stl{}
Colin Cross16b23492016-01-06 14:41:07 -0800650 module.sanitize = &sanitize{}
Colin Crossca860ac2016-01-04 14:34:37 -0800651 return module
652}
653
654func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) {
655 ctx := &moduleContext{
656 AndroidModuleContext: actx,
657 moduleContextImpl: moduleContextImpl{
658 mod: c,
659 },
660 }
661 ctx.ctx = ctx
662
663 flags := Flags{
664 Toolchain: c.toolchain(ctx),
665 Clang: c.clang(ctx),
666 }
Colin Crossca860ac2016-01-04 14:34:37 -0800667 if c.compiler != nil {
668 flags = c.compiler.flags(ctx, flags)
669 }
670 if c.linker != nil {
671 flags = c.linker.flags(ctx, flags)
672 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700673 if c.stl != nil {
674 flags = c.stl.flags(ctx, flags)
675 }
Colin Cross16b23492016-01-06 14:41:07 -0800676 if c.sanitize != nil {
677 flags = c.sanitize.flags(ctx, flags)
678 }
Colin Crossca860ac2016-01-04 14:34:37 -0800679 for _, feature := range c.features {
680 flags = feature.flags(ctx, flags)
681 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800682 if ctx.Failed() {
683 return
684 }
685
Colin Crossca860ac2016-01-04 14:34:37 -0800686 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
687 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
688 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800689
Colin Crossca860ac2016-01-04 14:34:37 -0800690 // Optimization to reduce size of build.ninja
691 // Replace the long list of flags for each file with a module-local variable
692 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
693 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
694 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
695 flags.CFlags = []string{"$cflags"}
696 flags.CppFlags = []string{"$cppflags"}
697 flags.AsFlags = []string{"$asflags"}
698
Colin Crossc99deeb2016-04-11 15:06:20 -0700699 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800700 if ctx.Failed() {
701 return
702 }
703
Colin Cross28344522015-04-22 13:07:53 -0700704 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700705
Colin Crossca860ac2016-01-04 14:34:37 -0800706 var objFiles common.Paths
707 if c.compiler != nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700708 objFiles = c.compiler.compile(ctx, flags, deps)
Colin Crossca860ac2016-01-04 14:34:37 -0800709 if ctx.Failed() {
710 return
711 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800712 }
713
Colin Crossca860ac2016-01-04 14:34:37 -0800714 if c.linker != nil {
715 outputFile := c.linker.link(ctx, flags, deps, objFiles)
716 if ctx.Failed() {
717 return
718 }
719 c.outputFile = common.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700720
Colin Crossc99deeb2016-04-11 15:06:20 -0700721 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800722 c.installer.install(ctx, outputFile)
723 if ctx.Failed() {
724 return
725 }
726 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700727 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800728}
729
Colin Crossca860ac2016-01-04 14:34:37 -0800730func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
731 if c.cachedToolchain == nil {
732 arch := ctx.Arch()
733 hod := ctx.HostOrDevice()
734 ht := ctx.HostType()
735 factory := toolchainFactories[hod][ht][arch.ArchType]
736 if factory == nil {
737 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
738 return nil
739 }
740 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800741 }
Colin Crossca860ac2016-01-04 14:34:37 -0800742 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800743}
744
Colin Crossca860ac2016-01-04 14:34:37 -0800745func (c *Module) begin(ctx BaseModuleContext) {
746 if c.compiler != nil {
747 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700748 }
Colin Crossca860ac2016-01-04 14:34:37 -0800749 if c.linker != nil {
750 c.linker.begin(ctx)
751 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700752 if c.stl != nil {
753 c.stl.begin(ctx)
754 }
Colin Cross16b23492016-01-06 14:41:07 -0800755 if c.sanitize != nil {
756 c.sanitize.begin(ctx)
757 }
Colin Crossca860ac2016-01-04 14:34:37 -0800758 for _, feature := range c.features {
759 feature.begin(ctx)
760 }
761}
762
Colin Crossc99deeb2016-04-11 15:06:20 -0700763func (c *Module) deps(ctx BaseModuleContext) Deps {
764 deps := Deps{}
765
766 if c.compiler != nil {
767 deps = c.compiler.deps(ctx, deps)
768 }
769 if c.linker != nil {
770 deps = c.linker.deps(ctx, deps)
771 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700772 if c.stl != nil {
773 deps = c.stl.deps(ctx, deps)
774 }
Colin Cross16b23492016-01-06 14:41:07 -0800775 if c.sanitize != nil {
776 deps = c.sanitize.deps(ctx, deps)
777 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700778 for _, feature := range c.features {
779 deps = feature.deps(ctx, deps)
780 }
781
782 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
783 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
784 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
785 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
786 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
787
788 return deps
789}
790
Colin Crossca860ac2016-01-04 14:34:37 -0800791func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) {
792 ctx := &baseModuleContext{
793 AndroidBaseContext: actx,
794 moduleContextImpl: moduleContextImpl{
795 mod: c,
796 },
797 }
798 ctx.ctx = ctx
799
800 if c.customizer != nil {
801 c.customizer.CustomizeProperties(ctx)
802 }
803
804 c.begin(ctx)
805
Colin Crossc99deeb2016-04-11 15:06:20 -0700806 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800807
Colin Crossc99deeb2016-04-11 15:06:20 -0700808 c.Properties.AndroidMkSharedLibs = deps.SharedLibs
809
810 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
811 deps.WholeStaticLibs...)
812
813 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticDepTag,
814 deps.StaticLibs...)
815
816 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
817 deps.LateStaticLibs...)
818
819 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedDepTag,
820 deps.SharedLibs...)
821
822 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
823 deps.LateSharedLibs...)
824
Dan Willemsenb40aab62016-04-20 14:21:14 -0700825 actx.AddDependency(ctx.module(), genSourceDepTag, deps.GeneratedSources...)
826 actx.AddDependency(ctx.module(), genHeaderDepTag, deps.GeneratedHeaders...)
827
Colin Crossc99deeb2016-04-11 15:06:20 -0700828 actx.AddDependency(ctx.module(), objDepTag, deps.ObjFiles...)
829
830 if deps.CrtBegin != "" {
831 actx.AddDependency(ctx.module(), crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800832 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700833 if deps.CrtEnd != "" {
834 actx.AddDependency(ctx.module(), crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700835 }
Colin Cross6362e272015-10-29 15:25:03 -0700836}
Colin Cross21b9a242015-03-24 14:15:58 -0700837
Colin Cross6362e272015-10-29 15:25:03 -0700838func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800839 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700840 c.depsMutator(ctx)
841 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800842}
843
Colin Crossca860ac2016-01-04 14:34:37 -0800844func (c *Module) clang(ctx BaseModuleContext) bool {
845 clang := Bool(c.Properties.Clang)
846
847 if c.Properties.Clang == nil {
848 if ctx.Host() {
849 clang = true
850 }
851
852 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
853 clang = true
854 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800855 }
Colin Cross28344522015-04-22 13:07:53 -0700856
Colin Crossca860ac2016-01-04 14:34:37 -0800857 if !c.toolchain(ctx).ClangSupported() {
858 clang = false
859 }
860
861 return clang
862}
863
Colin Crossc99deeb2016-04-11 15:06:20 -0700864// Convert dependencies to paths. Returns a PathDeps containing paths
865func (c *Module) depsToPaths(ctx common.AndroidModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800866 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800867
Colin Crossc99deeb2016-04-11 15:06:20 -0700868 ctx.VisitDirectDeps(func(m blueprint.Module) {
869 name := ctx.OtherModuleName(m)
870 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800871
Colin Crossc99deeb2016-04-11 15:06:20 -0700872 a, _ := m.(common.AndroidModule)
873 if a == nil {
874 ctx.ModuleErrorf("module %q not an android module", name)
875 return
Colin Crossca860ac2016-01-04 14:34:37 -0800876 }
Colin Crossca860ac2016-01-04 14:34:37 -0800877
Colin Crossc99deeb2016-04-11 15:06:20 -0700878 c, _ := m.(*Module)
879 if c == nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700880 switch tag {
881 case common.DefaultsDepTag:
882 case genSourceDepTag:
883 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
884 depPaths.GeneratedSources = append(depPaths.GeneratedSources,
885 genRule.GeneratedSourceFiles()...)
886 } else {
887 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
888 }
889 case genHeaderDepTag:
890 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
891 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
892 genRule.GeneratedSourceFiles()...)
893 depPaths.Cflags = append(depPaths.Cflags,
894 includeDirsToFlags(common.Paths{genRule.GeneratedHeaderDir()}))
895 } else {
896 ctx.ModuleErrorf("module %q is not a genrule", name)
897 }
898 default:
Colin Crossc99deeb2016-04-11 15:06:20 -0700899 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -0800900 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700901 return
902 }
903
904 if !a.Enabled() {
905 ctx.ModuleErrorf("depends on disabled module %q", name)
906 return
907 }
908
909 if a.HostOrDevice() != ctx.HostOrDevice() {
910 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(), name)
911 return
912 }
913
914 if !c.outputFile.Valid() {
915 ctx.ModuleErrorf("module %q missing output file", name)
916 return
917 }
918
919 if tag == reuseObjTag {
920 depPaths.ObjFiles = append(depPaths.ObjFiles,
921 c.compiler.(*libraryCompiler).reuseObjFiles...)
922 return
923 }
924
925 var cflags []string
926 if t, _ := tag.(dependencyTag); t.library {
927 if i, ok := c.linker.(exportedFlagsProducer); ok {
928 cflags = i.exportedFlags()
929 depPaths.Cflags = append(depPaths.Cflags, cflags...)
930 }
931 }
932
933 var depPtr *common.Paths
934
935 switch tag {
936 case sharedDepTag:
937 depPtr = &depPaths.SharedLibs
938 case lateSharedDepTag:
939 depPtr = &depPaths.LateSharedLibs
940 case staticDepTag:
941 depPtr = &depPaths.StaticLibs
942 case lateStaticDepTag:
943 depPtr = &depPaths.LateStaticLibs
944 case wholeStaticDepTag:
945 depPtr = &depPaths.WholeStaticLibs
946 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, cflags...)
947 staticLib, _ := c.linker.(*libraryLinker)
948 if staticLib == nil || !staticLib.static() {
949 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
950 return
951 }
952
953 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
954 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
955 for i := range missingDeps {
956 missingDeps[i] += postfix
957 }
958 ctx.AddMissingDependencies(missingDeps)
959 }
960 depPaths.WholeStaticLibObjFiles =
961 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
962 case objDepTag:
963 depPtr = &depPaths.ObjFiles
964 case crtBeginDepTag:
965 depPaths.CrtBegin = c.outputFile
966 case crtEndDepTag:
967 depPaths.CrtEnd = c.outputFile
968 default:
969 panic(fmt.Errorf("unknown dependency tag: %s", ctx.OtherModuleDependencyTag(m)))
970 }
971
972 if depPtr != nil {
973 *depPtr = append(*depPtr, c.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -0800974 }
975 })
976
977 return depPaths
978}
979
980func (c *Module) InstallInData() bool {
981 if c.installer == nil {
982 return false
983 }
984 return c.installer.inData()
985}
986
Colin Cross16b23492016-01-06 14:41:07 -0800987type appendVariantName interface {
988 appendVariantName(string)
989}
990
991func (c *Module) appendVariantName(name string) {
992 if c.linker == nil {
993 return
994 }
995
996 if l, ok := c.linker.(appendVariantName); ok {
997 l.appendVariantName(name)
998 }
999}
1000
Colin Crossca860ac2016-01-04 14:34:37 -08001001// Compiler
1002
1003type baseCompiler struct {
1004 Properties BaseCompilerProperties
1005}
1006
1007var _ compiler = (*baseCompiler)(nil)
1008
1009func (compiler *baseCompiler) props() []interface{} {
1010 return []interface{}{&compiler.Properties}
1011}
1012
Dan Willemsenb40aab62016-04-20 14:21:14 -07001013func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
1014
1015func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
1016 deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
1017 deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
1018
1019 return deps
1020}
Colin Crossca860ac2016-01-04 14:34:37 -08001021
1022// Create a Flags struct that collects the compile flags from global values,
1023// per-target values, module type values, and per-module Blueprints properties
1024func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1025 toolchain := ctx.toolchain()
1026
1027 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
1028 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
1029 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
1030 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
1031 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
1032
Colin Cross28344522015-04-22 13:07:53 -07001033 // Include dir cflags
Colin Crossca860ac2016-01-04 14:34:37 -08001034 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs)
1035 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -07001036 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -07001037 includeDirsToFlags(localIncludeDirs),
1038 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -07001039
Colin Crossca860ac2016-01-04 14:34:37 -08001040 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files)
1041 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -07001042
1043 flags.GlobalFlags = append(flags.GlobalFlags,
1044 includeFilesToFlags(rootIncludeFiles),
1045 includeFilesToFlags(localIncludeFiles))
1046
Colin Crossca860ac2016-01-04 14:34:37 -08001047 if !ctx.noDefaultCompilerFlags() {
1048 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -07001049 flags.GlobalFlags = append(flags.GlobalFlags,
1050 "${commonGlobalIncludes}",
1051 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -08001052 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -07001053 }
1054
1055 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001056 "-I" + common.PathForModuleSrc(ctx).String(),
1057 "-I" + common.PathForModuleOut(ctx).String(),
1058 "-I" + common.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -07001059 }...)
1060 }
1061
Colin Crossca860ac2016-01-04 14:34:37 -08001062 instructionSet := compiler.Properties.Instruction_set
1063 if flags.RequiredInstructionSet != "" {
1064 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -08001065 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001066 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
1067 if flags.Clang {
1068 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
1069 }
1070 if err != nil {
1071 ctx.ModuleErrorf("%s", err)
1072 }
1073
1074 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -08001075 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001076
Colin Cross97ba0732015-03-23 17:50:24 -07001077 if flags.Clang {
1078 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001079 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
1080 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -07001081 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
1082 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
1083 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001084
1085 target := "-target " + toolchain.ClangTriple()
1086 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
1087
Colin Cross97ba0732015-03-23 17:50:24 -07001088 flags.CFlags = append(flags.CFlags, target, gccPrefix)
1089 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
1090 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -08001091 }
1092
Colin Crossca860ac2016-01-04 14:34:37 -08001093 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001094 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1095
Colin Cross97ba0732015-03-23 17:50:24 -07001096 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001097 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001098 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001099 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001100 toolchain.ClangCflags(),
1101 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001102 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001103
1104 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001105 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001106 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001107 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001108 toolchain.Cflags(),
1109 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001110 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001111 }
1112
Colin Cross7b66f152015-12-15 16:07:43 -08001113 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1114 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1115 }
1116
Colin Crossf6566ed2015-03-24 11:13:38 -07001117 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001118 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001119 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001120 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001121 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001122 }
1123 }
1124
Colin Cross97ba0732015-03-23 17:50:24 -07001125 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001126
Colin Cross97ba0732015-03-23 17:50:24 -07001127 if flags.Clang {
1128 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001129 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001130 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001131 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001132 }
1133
Colin Crossc4bde762015-11-23 16:11:30 -08001134 if flags.Clang {
1135 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1136 } else {
1137 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001138 }
1139
Colin Crossca860ac2016-01-04 14:34:37 -08001140 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001141 if ctx.Host() && !flags.Clang {
1142 // The host GCC doesn't support C++14 (and is deprecated, so likely
1143 // never will). Build these modules with C++11.
1144 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1145 } else {
1146 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1147 }
1148 }
1149
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001150 // We can enforce some rules more strictly in the code we own. strict
1151 // indicates if this is code that we can be stricter with. If we have
1152 // rules that we want to apply to *our* code (but maybe can't for
1153 // vendor/device specific things), we could extend this to be a ternary
1154 // value.
1155 strict := true
1156 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") {
1157 strict = false
1158 }
1159
1160 // Can be used to make some annotations stricter for code we can fix
1161 // (such as when we mark functions as deprecated).
1162 if strict {
1163 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1164 }
1165
Colin Cross3f40fa42015-01-30 17:27:36 -08001166 return flags
1167}
1168
Dan Willemsenb40aab62016-04-20 14:21:14 -07001169func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001170 // Compile files listed in c.Properties.Srcs into objects
Dan Willemsenb40aab62016-04-20 14:21:14 -07001171 objFiles := compiler.compileObjs(ctx, flags, "",
1172 compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
1173 deps.GeneratedSources, deps.GeneratedHeaders)
1174
Colin Crossca860ac2016-01-04 14:34:37 -08001175 if ctx.Failed() {
1176 return nil
1177 }
1178
Colin Crossca860ac2016-01-04 14:34:37 -08001179 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001180}
1181
1182// Compile a list of source files into objects a specified subdirectory
Colin Crossca860ac2016-01-04 14:34:37 -08001183func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001184 subdir string, srcFiles, excludes []string, extraSrcs, deps common.Paths) common.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001185
Colin Crossca860ac2016-01-04 14:34:37 -08001186 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001187
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001188 inputFiles := ctx.ExpandSources(srcFiles, excludes)
Dan Willemsenb40aab62016-04-20 14:21:14 -07001189 inputFiles = append(inputFiles, extraSrcs...)
1190 srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)
1191
1192 deps = append(deps, gendeps...)
Colin Cross16b23492016-01-06 14:41:07 -08001193 deps = append(deps, flags.CFlagsDeps...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001194
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001195 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001196}
1197
Colin Crossca860ac2016-01-04 14:34:37 -08001198// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1199type baseLinker struct {
1200 Properties BaseLinkerProperties
1201 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001202 VariantIsShared bool `blueprint:"mutated"`
1203 VariantIsStatic bool `blueprint:"mutated"`
1204 VariantIsStaticBinary bool `blueprint:"mutated"`
1205 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001206 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001207}
1208
Dan Willemsend30e6102016-03-30 17:35:50 -07001209func (linker *baseLinker) begin(ctx BaseModuleContext) {
1210 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001211 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001212 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001213 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001214 }
1215}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001216
Colin Crossca860ac2016-01-04 14:34:37 -08001217func (linker *baseLinker) props() []interface{} {
1218 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001219}
1220
Colin Crossca860ac2016-01-04 14:34:37 -08001221func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1222 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1223 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1224 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001225
Colin Cross74d1ec02015-04-28 13:30:13 -07001226 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001227 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001228 }
1229
Colin Crossf6566ed2015-03-24 11:13:38 -07001230 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001231 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001232 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1233 if !Bool(linker.Properties.No_libgcc) {
1234 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001235 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001236
Colin Crossca860ac2016-01-04 14:34:37 -08001237 if !linker.static() {
1238 if linker.Properties.System_shared_libs != nil {
1239 deps.LateSharedLibs = append(deps.LateSharedLibs,
1240 linker.Properties.System_shared_libs...)
1241 } else if !ctx.sdk() {
1242 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1243 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001244 }
Colin Cross577f6e42015-03-27 18:23:34 -07001245
Colin Crossca860ac2016-01-04 14:34:37 -08001246 if ctx.sdk() {
1247 version := ctx.sdkVersion()
1248 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001249 "ndk_libc."+version,
1250 "ndk_libm."+version,
1251 )
1252 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001253 }
1254
Colin Crossca860ac2016-01-04 14:34:37 -08001255 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001256}
1257
Colin Crossca860ac2016-01-04 14:34:37 -08001258func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1259 toolchain := ctx.toolchain()
1260
Colin Crossca860ac2016-01-04 14:34:37 -08001261 if !ctx.noDefaultCompilerFlags() {
1262 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1263 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1264 }
1265
1266 if flags.Clang {
1267 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1268 } else {
1269 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1270 }
1271
1272 if ctx.Host() {
1273 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1274 }
1275 }
1276
Dan Willemsen00ced762016-05-10 17:31:21 -07001277 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1278
Dan Willemsend30e6102016-03-30 17:35:50 -07001279 if ctx.Host() && !linker.static() {
1280 rpath_prefix := `\$$ORIGIN/`
1281 if ctx.Darwin() {
1282 rpath_prefix = "@loader_path/"
1283 }
1284
Colin Crossc99deeb2016-04-11 15:06:20 -07001285 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001286 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1287 }
1288 }
1289
Dan Willemsene7174922016-03-30 17:33:52 -07001290 if flags.Clang {
1291 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1292 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001293 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1294 }
1295
1296 return flags
1297}
1298
1299func (linker *baseLinker) static() bool {
1300 return linker.dynamicProperties.VariantIsStatic
1301}
1302
1303func (linker *baseLinker) staticBinary() bool {
1304 return linker.dynamicProperties.VariantIsStaticBinary
1305}
1306
1307func (linker *baseLinker) setStatic(static bool) {
1308 linker.dynamicProperties.VariantIsStatic = static
1309}
1310
Colin Cross16b23492016-01-06 14:41:07 -08001311func (linker *baseLinker) isDependencyRoot() bool {
1312 return false
1313}
1314
Colin Crossca860ac2016-01-04 14:34:37 -08001315type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001316 // Returns true if the build options for the module have selected a static or shared build
1317 buildStatic() bool
1318 buildShared() bool
1319
1320 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001321 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001322
Colin Cross18b6dc52015-04-28 13:20:37 -07001323 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001324 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001325
1326 // Returns whether a module is a static binary
1327 staticBinary() bool
Colin Cross16b23492016-01-06 14:41:07 -08001328
1329 // Returns true for dependency roots (binaries)
1330 // TODO(ccross): also handle dlopenable libraries
1331 isDependencyRoot() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001332}
1333
Colin Crossca860ac2016-01-04 14:34:37 -08001334type baseInstaller struct {
1335 Properties InstallerProperties
1336
1337 dir string
1338 dir64 string
1339 data bool
1340
Colin Crossa2344662016-03-24 13:14:12 -07001341 path common.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001342}
1343
1344var _ installer = (*baseInstaller)(nil)
1345
1346func (installer *baseInstaller) props() []interface{} {
1347 return []interface{}{&installer.Properties}
1348}
1349
1350func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) {
1351 subDir := installer.dir
1352 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1353 subDir = installer.dir64
1354 }
1355 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
1356 installer.path = ctx.InstallFile(dir, file)
1357}
1358
1359func (installer *baseInstaller) inData() bool {
1360 return installer.data
1361}
1362
Colin Cross3f40fa42015-01-30 17:27:36 -08001363//
1364// Combined static+shared libraries
1365//
1366
Colin Cross919281a2016-04-05 16:42:05 -07001367type flagExporter struct {
1368 Properties FlagExporterProperties
1369
1370 flags []string
1371}
1372
1373func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
1374 includeDirs := common.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
1375 f.flags = append(f.flags, common.JoinWithPrefix(includeDirs.Strings(), inc))
1376}
1377
1378func (f *flagExporter) reexportFlags(flags []string) {
1379 f.flags = append(f.flags, flags...)
1380}
1381
1382func (f *flagExporter) exportedFlags() []string {
1383 return f.flags
1384}
1385
1386type exportedFlagsProducer interface {
1387 exportedFlags() []string
1388}
1389
1390var _ exportedFlagsProducer = (*flagExporter)(nil)
1391
Colin Crossca860ac2016-01-04 14:34:37 -08001392type libraryCompiler struct {
1393 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001394
Colin Crossca860ac2016-01-04 14:34:37 -08001395 linker *libraryLinker
1396 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001397
Colin Crossca860ac2016-01-04 14:34:37 -08001398 // For reusing static library objects for shared library
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001399 reuseObjFiles common.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001400}
1401
Colin Crossca860ac2016-01-04 14:34:37 -08001402var _ compiler = (*libraryCompiler)(nil)
1403
1404func (library *libraryCompiler) props() []interface{} {
1405 props := library.baseCompiler.props()
1406 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001407}
1408
Colin Crossca860ac2016-01-04 14:34:37 -08001409func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1410 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001411
Dan Willemsen490fd492015-11-24 17:53:15 -08001412 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1413 // all code is position independent, and then those warnings get promoted to
1414 // errors.
1415 if ctx.HostType() != common.Windows {
1416 flags.CFlags = append(flags.CFlags, "-fPIC")
1417 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001418
Colin Crossca860ac2016-01-04 14:34:37 -08001419 if library.linker.static() {
1420 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001421 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001422 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001423 }
1424
Colin Crossca860ac2016-01-04 14:34:37 -08001425 return flags
1426}
1427
Dan Willemsenb40aab62016-04-20 14:21:14 -07001428func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) common.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001429 var objFiles common.Paths
1430
Dan Willemsenb40aab62016-04-20 14:21:14 -07001431 objFiles = library.baseCompiler.compile(ctx, flags, deps)
Colin Crossc99deeb2016-04-11 15:06:20 -07001432 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001433
1434 if library.linker.static() {
1435 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001436 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
1437 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001438 } else {
1439 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001440 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
1441 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001442 }
1443
1444 return objFiles
1445}
1446
1447type libraryLinker struct {
1448 baseLinker
Colin Cross919281a2016-04-05 16:42:05 -07001449 flagExporter
Colin Cross665dce92016-04-28 14:50:03 -07001450 stripper
Colin Crossca860ac2016-01-04 14:34:37 -08001451
1452 Properties LibraryLinkerProperties
1453
1454 dynamicProperties struct {
1455 BuildStatic bool `blueprint:"mutated"`
1456 BuildShared bool `blueprint:"mutated"`
1457 }
1458
Colin Crossca860ac2016-01-04 14:34:37 -08001459 // If we're used as a whole_static_lib, our missing dependencies need
1460 // to be given
1461 wholeStaticMissingDeps []string
1462
1463 // For whole_static_libs
1464 objFiles common.Paths
1465}
1466
1467var _ linker = (*libraryLinker)(nil)
Colin Cross16b23492016-01-06 14:41:07 -08001468var _ appendVariantName = (*libraryLinker)(nil)
Colin Crossca860ac2016-01-04 14:34:37 -08001469
1470func (library *libraryLinker) props() []interface{} {
1471 props := library.baseLinker.props()
Colin Cross919281a2016-04-05 16:42:05 -07001472 return append(props,
1473 &library.Properties,
1474 &library.dynamicProperties,
Colin Cross665dce92016-04-28 14:50:03 -07001475 &library.flagExporter.Properties,
1476 &library.stripper.StripProperties)
Colin Crossca860ac2016-01-04 14:34:37 -08001477}
1478
1479func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1480 flags = library.baseLinker.flags(ctx, flags)
1481
1482 flags.Nocrt = Bool(library.Properties.Nocrt)
1483
1484 if !library.static() {
Colin Cross30d5f512016-05-03 18:02:42 -07001485 libName := ctx.ModuleName() + library.Properties.VariantName
Colin Cross3f40fa42015-01-30 17:27:36 -08001486 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1487 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001488 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001489 sharedFlag = "-shared"
1490 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001491 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001492 flags.LdFlags = append(flags.LdFlags,
1493 "-nostdlib",
1494 "-Wl,--gc-sections",
1495 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001496 }
Colin Cross97ba0732015-03-23 17:50:24 -07001497
Colin Cross0af4b842015-04-30 16:36:18 -07001498 if ctx.Darwin() {
1499 flags.LdFlags = append(flags.LdFlags,
1500 "-dynamiclib",
1501 "-single_module",
1502 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001503 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001504 )
1505 } else {
1506 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001507 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001508 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001509 )
1510 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001511 }
Colin Cross97ba0732015-03-23 17:50:24 -07001512
1513 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001514}
1515
Colin Crossca860ac2016-01-04 14:34:37 -08001516func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1517 deps = library.baseLinker.deps(ctx, deps)
1518 if library.static() {
1519 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1520 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1521 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1522 } else {
1523 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1524 if !ctx.sdk() {
1525 deps.CrtBegin = "crtbegin_so"
1526 deps.CrtEnd = "crtend_so"
1527 } else {
1528 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1529 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1530 }
1531 }
1532 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1533 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1534 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1535 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001536
Colin Crossca860ac2016-01-04 14:34:37 -08001537 return deps
1538}
Colin Cross3f40fa42015-01-30 17:27:36 -08001539
Colin Crossca860ac2016-01-04 14:34:37 -08001540func (library *libraryLinker) linkStatic(ctx ModuleContext,
1541 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
1542
Dan Willemsen025b4802016-05-11 17:25:48 -07001543 library.objFiles = append(common.Paths{}, deps.WholeStaticLibObjFiles...)
1544 library.objFiles = append(library.objFiles, objFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001545
Colin Cross16b23492016-01-06 14:41:07 -08001546 outputFile := common.PathForModuleOut(ctx,
1547 ctx.ModuleName()+library.Properties.VariantName+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001548
Colin Cross0af4b842015-04-30 16:36:18 -07001549 if ctx.Darwin() {
Dan Willemsen025b4802016-05-11 17:25:48 -07001550 TransformDarwinObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001551 } else {
Dan Willemsen025b4802016-05-11 17:25:48 -07001552 TransformObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001553 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001554
Colin Crossca860ac2016-01-04 14:34:37 -08001555 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001556
1557 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001558
1559 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001560}
1561
Colin Crossca860ac2016-01-04 14:34:37 -08001562func (library *libraryLinker) linkShared(ctx ModuleContext,
1563 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001564
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001565 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001566
Colin Crossca860ac2016-01-04 14:34:37 -08001567 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1568 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1569 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1570 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001571 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001572 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001573 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001574 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001575 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001576 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001577 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1578 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001579 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001580 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1581 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001582 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001583 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1584 }
1585 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001586 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001587 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1588 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001589 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001590 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001591 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001592 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001593 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001594 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001595 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001596 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001597 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001598 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001599 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001600 }
Colin Crossaee540a2015-07-06 17:48:31 -07001601 }
1602
Colin Cross665dce92016-04-28 14:50:03 -07001603 fileName := ctx.ModuleName() + library.Properties.VariantName + flags.Toolchain.ShlibSuffix()
1604 outputFile := common.PathForModuleOut(ctx, fileName)
1605 ret := outputFile
1606
1607 builderFlags := flagsToBuilderFlags(flags)
1608
1609 if library.stripper.needsStrip(ctx) {
1610 strippedOutputFile := outputFile
1611 outputFile = common.PathForModuleOut(ctx, "unstripped", fileName)
1612 library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
1613 }
1614
Colin Crossca860ac2016-01-04 14:34:37 -08001615 sharedLibs := deps.SharedLibs
1616 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001617
Colin Crossca860ac2016-01-04 14:34:37 -08001618 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1619 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
Colin Cross665dce92016-04-28 14:50:03 -07001620 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001621
Colin Cross665dce92016-04-28 14:50:03 -07001622 return ret
Colin Cross3f40fa42015-01-30 17:27:36 -08001623}
1624
Colin Crossca860ac2016-01-04 14:34:37 -08001625func (library *libraryLinker) link(ctx ModuleContext,
1626 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001627
Colin Crossc99deeb2016-04-11 15:06:20 -07001628 objFiles = append(objFiles, deps.ObjFiles...)
1629
Colin Crossca860ac2016-01-04 14:34:37 -08001630 var out common.Path
1631 if library.static() {
1632 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001633 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001634 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001635 }
1636
Colin Cross919281a2016-04-05 16:42:05 -07001637 library.exportIncludes(ctx, "-I")
1638 library.reexportFlags(deps.ReexportedCflags)
Colin Crossca860ac2016-01-04 14:34:37 -08001639
1640 return out
1641}
1642
1643func (library *libraryLinker) buildStatic() bool {
1644 return library.dynamicProperties.BuildStatic
1645}
1646
1647func (library *libraryLinker) buildShared() bool {
1648 return library.dynamicProperties.BuildShared
1649}
1650
1651func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1652 return library.wholeStaticMissingDeps
1653}
1654
Colin Crossc99deeb2016-04-11 15:06:20 -07001655func (library *libraryLinker) installable() bool {
1656 return !library.static()
1657}
1658
Colin Cross16b23492016-01-06 14:41:07 -08001659func (library *libraryLinker) appendVariantName(variant string) {
1660 library.Properties.VariantName += variant
1661}
1662
Colin Crossca860ac2016-01-04 14:34:37 -08001663type libraryInstaller struct {
1664 baseInstaller
1665
Colin Cross30d5f512016-05-03 18:02:42 -07001666 linker *libraryLinker
1667 sanitize *sanitize
Colin Crossca860ac2016-01-04 14:34:37 -08001668}
1669
1670func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) {
1671 if !library.linker.static() {
1672 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001673 }
1674}
1675
Colin Cross30d5f512016-05-03 18:02:42 -07001676func (library *libraryInstaller) inData() bool {
1677 return library.baseInstaller.inData() || library.sanitize.inData()
1678}
1679
Colin Crossca860ac2016-01-04 14:34:37 -08001680func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module {
1681 module := newModule(hod, common.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001682
Colin Crossca860ac2016-01-04 14:34:37 -08001683 linker := &libraryLinker{}
1684 linker.dynamicProperties.BuildShared = shared
1685 linker.dynamicProperties.BuildStatic = static
1686 module.linker = linker
1687
1688 module.compiler = &libraryCompiler{
1689 linker: linker,
1690 }
1691 module.installer = &libraryInstaller{
1692 baseInstaller: baseInstaller{
1693 dir: "lib",
1694 dir64: "lib64",
1695 },
Colin Cross30d5f512016-05-03 18:02:42 -07001696 linker: linker,
1697 sanitize: module.sanitize,
Dan Albertc403f7c2015-03-18 14:01:18 -07001698 }
1699
Colin Crossca860ac2016-01-04 14:34:37 -08001700 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001701}
1702
Colin Crossca860ac2016-01-04 14:34:37 -08001703func libraryFactory() (blueprint.Module, []interface{}) {
1704 module := NewLibrary(common.HostAndDeviceSupported, true, true)
1705 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001706}
1707
Colin Cross3f40fa42015-01-30 17:27:36 -08001708//
1709// Objects (for crt*.o)
1710//
1711
Colin Crossca860ac2016-01-04 14:34:37 -08001712type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001713 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001714}
1715
Colin Crossca860ac2016-01-04 14:34:37 -08001716func objectFactory() (blueprint.Module, []interface{}) {
1717 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
1718 module.compiler = &baseCompiler{}
1719 module.linker = &objectLinker{}
1720 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001721}
1722
Colin Cross81413472016-04-11 14:37:39 -07001723func (object *objectLinker) props() []interface{} {
1724 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001725}
1726
Colin Crossca860ac2016-01-04 14:34:37 -08001727func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001728
Colin Cross81413472016-04-11 14:37:39 -07001729func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1730 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001731 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001732}
1733
Colin Crossca860ac2016-01-04 14:34:37 -08001734func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001735 if flags.Clang {
1736 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1737 } else {
1738 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1739 }
1740
Colin Crossca860ac2016-01-04 14:34:37 -08001741 return flags
1742}
1743
1744func (object *objectLinker) link(ctx ModuleContext,
1745 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001746
Colin Cross97ba0732015-03-23 17:50:24 -07001747 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001748
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001749 var outputFile common.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001750 if len(objFiles) == 1 {
1751 outputFile = objFiles[0]
1752 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001753 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001754 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001755 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001756 }
1757
Colin Cross3f40fa42015-01-30 17:27:36 -08001758 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001759 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001760}
1761
Colin Crossc99deeb2016-04-11 15:06:20 -07001762func (*objectLinker) installable() bool {
1763 return false
1764}
1765
Colin Cross3f40fa42015-01-30 17:27:36 -08001766//
1767// Executables
1768//
1769
Colin Crossca860ac2016-01-04 14:34:37 -08001770type binaryLinker struct {
1771 baseLinker
Colin Cross665dce92016-04-28 14:50:03 -07001772 stripper
Colin Cross7d5136f2015-05-11 13:39:40 -07001773
Colin Crossca860ac2016-01-04 14:34:37 -08001774 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001775
Colin Crossca860ac2016-01-04 14:34:37 -08001776 hostToolPath common.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001777}
1778
Colin Crossca860ac2016-01-04 14:34:37 -08001779var _ linker = (*binaryLinker)(nil)
1780
1781func (binary *binaryLinker) props() []interface{} {
Colin Cross665dce92016-04-28 14:50:03 -07001782 return append(binary.baseLinker.props(),
1783 &binary.Properties,
1784 &binary.stripper.StripProperties)
1785
Colin Cross3f40fa42015-01-30 17:27:36 -08001786}
1787
Colin Crossca860ac2016-01-04 14:34:37 -08001788func (binary *binaryLinker) buildStatic() bool {
1789 return Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001790}
1791
Colin Crossca860ac2016-01-04 14:34:37 -08001792func (binary *binaryLinker) buildShared() bool {
1793 return !Bool(binary.Properties.Static_executable)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001794}
1795
Colin Crossca860ac2016-01-04 14:34:37 -08001796func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001797 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001798 if binary.Properties.Stem != "" {
1799 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001800 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001801
Colin Crossca860ac2016-01-04 14:34:37 -08001802 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001803}
1804
Colin Crossca860ac2016-01-04 14:34:37 -08001805func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1806 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001807 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001808 if !ctx.sdk() {
1809 if Bool(binary.Properties.Static_executable) {
1810 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001811 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001812 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001813 }
Colin Crossca860ac2016-01-04 14:34:37 -08001814 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001815 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001816 if Bool(binary.Properties.Static_executable) {
1817 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001818 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001819 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001820 }
Colin Crossca860ac2016-01-04 14:34:37 -08001821 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001822 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001823
Colin Crossca860ac2016-01-04 14:34:37 -08001824 if Bool(binary.Properties.Static_executable) {
1825 if inList("libc++_static", deps.StaticLibs) {
1826 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001827 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001828 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1829 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1830 // move them to the beginning of deps.LateStaticLibs
1831 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001832 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001833 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001834 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001835 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001836 }
Colin Crossca860ac2016-01-04 14:34:37 -08001837
1838 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) {
1839 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1840 "from static libs or set static_executable: true")
1841 }
1842 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001843}
1844
Colin Crossc99deeb2016-04-11 15:06:20 -07001845func (*binaryLinker) installable() bool {
1846 return true
1847}
1848
Colin Cross16b23492016-01-06 14:41:07 -08001849func (binary *binaryLinker) isDependencyRoot() bool {
1850 return true
1851}
1852
Colin Crossca860ac2016-01-04 14:34:37 -08001853func NewBinary(hod common.HostOrDeviceSupported) *Module {
1854 module := newModule(hod, common.MultilibFirst)
1855 module.compiler = &baseCompiler{}
1856 module.linker = &binaryLinker{}
1857 module.installer = &baseInstaller{
1858 dir: "bin",
1859 }
1860 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001861}
1862
Colin Crossca860ac2016-01-04 14:34:37 -08001863func binaryFactory() (blueprint.Module, []interface{}) {
1864 module := NewBinary(common.HostAndDeviceSupported)
1865 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001866}
1867
Colin Crossca860ac2016-01-04 14:34:37 -08001868func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) {
Colin Cross0af4b842015-04-30 16:36:18 -07001869 if ctx.Darwin() {
Colin Crossca860ac2016-01-04 14:34:37 -08001870 binary.Properties.Static_executable = proptools.BoolPtr(false)
Colin Cross0af4b842015-04-30 16:36:18 -07001871 }
Colin Crossca860ac2016-01-04 14:34:37 -08001872 if Bool(binary.Properties.Static_executable) {
1873 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001874 }
1875}
1876
Colin Crossca860ac2016-01-04 14:34:37 -08001877func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1878 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001879
Dan Willemsen490fd492015-11-24 17:53:15 -08001880 if ctx.Host() {
1881 flags.LdFlags = append(flags.LdFlags, "-pie")
1882 if ctx.HostType() == common.Windows {
1883 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1884 }
1885 }
1886
1887 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1888 // all code is position independent, and then those warnings get promoted to
1889 // errors.
1890 if ctx.HostType() != common.Windows {
1891 flags.CFlags = append(flags.CFlags, "-fpie")
1892 }
Colin Cross97ba0732015-03-23 17:50:24 -07001893
Colin Crossf6566ed2015-03-24 11:13:38 -07001894 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001895 if Bool(binary.Properties.Static_executable) {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001896 // Clang driver needs -static to create static executable.
1897 // However, bionic/linker uses -shared to overwrite.
1898 // Linker for x86 targets does not allow coexistance of -static and -shared,
1899 // so we add -static only if -shared is not used.
1900 if !inList("-shared", flags.LdFlags) {
1901 flags.LdFlags = append(flags.LdFlags, "-static")
1902 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001903
Colin Crossed4cf0b2015-03-26 14:43:45 -07001904 flags.LdFlags = append(flags.LdFlags,
1905 "-nostdlib",
1906 "-Bstatic",
1907 "-Wl,--gc-sections",
1908 )
1909
1910 } else {
Colin Cross16b23492016-01-06 14:41:07 -08001911 if flags.DynamicLinker == "" {
1912 flags.DynamicLinker = "/system/bin/linker"
1913 if flags.Toolchain.Is64Bit() {
1914 flags.DynamicLinker += "64"
1915 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001916 }
1917
1918 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001919 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001920 "-nostdlib",
1921 "-Bdynamic",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001922 "-Wl,--gc-sections",
1923 "-Wl,-z,nocopyreloc",
1924 )
1925 }
Colin Cross0af4b842015-04-30 16:36:18 -07001926 } else if ctx.Darwin() {
1927 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
Colin Cross3f40fa42015-01-30 17:27:36 -08001928 }
1929
Colin Cross97ba0732015-03-23 17:50:24 -07001930 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001931}
1932
Colin Crossca860ac2016-01-04 14:34:37 -08001933func (binary *binaryLinker) link(ctx ModuleContext,
1934 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001935
Colin Cross665dce92016-04-28 14:50:03 -07001936 fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
1937 outputFile := common.PathForModuleOut(ctx, fileName)
1938 ret := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001939 if ctx.HostOrDevice().Host() {
1940 binary.hostToolPath = common.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001941 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001942
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001943 var linkerDeps common.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001944
Colin Crossca860ac2016-01-04 14:34:37 -08001945 sharedLibs := deps.SharedLibs
1946 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1947
Colin Cross16b23492016-01-06 14:41:07 -08001948 if flags.DynamicLinker != "" {
1949 flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
1950 }
1951
Colin Cross665dce92016-04-28 14:50:03 -07001952 builderFlags := flagsToBuilderFlags(flags)
1953
1954 if binary.stripper.needsStrip(ctx) {
1955 strippedOutputFile := outputFile
1956 outputFile = common.PathForModuleOut(ctx, "unstripped", fileName)
1957 binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
1958 }
1959
1960 if binary.Properties.Prefix_symbols != "" {
1961 afterPrefixSymbols := outputFile
1962 outputFile = common.PathForModuleOut(ctx, "unprefixed", fileName)
1963 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1964 flagsToBuilderFlags(flags), afterPrefixSymbols)
1965 }
1966
Colin Crossca860ac2016-01-04 14:34:37 -08001967 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001968 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Cross665dce92016-04-28 14:50:03 -07001969 builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001970
1971 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001972}
Colin Cross3f40fa42015-01-30 17:27:36 -08001973
Colin Crossca860ac2016-01-04 14:34:37 -08001974func (binary *binaryLinker) HostToolPath() common.OptionalPath {
1975 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001976}
1977
Colin Cross665dce92016-04-28 14:50:03 -07001978type stripper struct {
1979 StripProperties StripProperties
1980}
1981
1982func (stripper *stripper) needsStrip(ctx ModuleContext) bool {
1983 return !ctx.AConfig().EmbeddedInMake() && !stripper.StripProperties.Strip.None
1984}
1985
1986func (stripper *stripper) strip(ctx ModuleContext, in, out common.ModuleOutPath,
1987 flags builderFlags) {
Colin Crossb8ecdfe2016-05-03 15:10:29 -07001988 if ctx.Darwin() {
1989 TransformDarwinStrip(ctx, in, out)
1990 } else {
1991 flags.stripKeepSymbols = stripper.StripProperties.Strip.Keep_symbols
1992 // TODO(ccross): don't add gnu debuglink for user builds
1993 flags.stripAddGnuDebuglink = true
1994 TransformStrip(ctx, in, out, flags)
1995 }
Colin Cross665dce92016-04-28 14:50:03 -07001996}
1997
Colin Cross6362e272015-10-29 15:25:03 -07001998func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08001999 if m, ok := mctx.Module().(*Module); ok {
2000 if test, ok := m.linker.(*testLinker); ok {
2001 if Bool(test.Properties.Test_per_src) {
2002 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
2003 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2004 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
2005 }
2006 tests := mctx.CreateLocalVariations(testNames...)
2007 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2008 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
2009 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
2010 }
Colin Cross6002e052015-09-16 16:00:08 -07002011 }
2012 }
2013 }
Colin Cross7d5136f2015-05-11 13:39:40 -07002014}
2015
Colin Crossca860ac2016-01-04 14:34:37 -08002016type testLinker struct {
2017 binaryLinker
2018 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002019}
2020
Dan Willemsend30e6102016-03-30 17:35:50 -07002021func (test *testLinker) begin(ctx BaseModuleContext) {
2022 test.binaryLinker.begin(ctx)
2023
2024 runpath := "../../lib"
2025 if ctx.toolchain().Is64Bit() {
2026 runpath += "64"
2027 }
Colin Crossc99deeb2016-04-11 15:06:20 -07002028 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
Dan Willemsend30e6102016-03-30 17:35:50 -07002029}
2030
Colin Crossca860ac2016-01-04 14:34:37 -08002031func (test *testLinker) props() []interface{} {
2032 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07002033}
2034
Colin Crossca860ac2016-01-04 14:34:37 -08002035func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
2036 flags = test.binaryLinker.flags(ctx, flags)
2037
2038 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002039 return flags
2040 }
Dan Albertc403f7c2015-03-18 14:01:18 -07002041
Colin Cross97ba0732015-03-23 17:50:24 -07002042 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07002043 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07002044 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002045
2046 if ctx.HostType() == common.Windows {
2047 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
2048 } else {
2049 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
2050 flags.LdFlags = append(flags.LdFlags, "-lpthread")
2051 }
2052 } else {
2053 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07002054 }
2055
Colin Cross21b9a242015-03-24 14:15:58 -07002056 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07002057}
2058
Colin Crossca860ac2016-01-04 14:34:37 -08002059func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2060 if test.Properties.Gtest {
2061 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002062 }
Colin Crossca860ac2016-01-04 14:34:37 -08002063 deps = test.binaryLinker.deps(ctx, deps)
2064 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07002065}
2066
Colin Crossca860ac2016-01-04 14:34:37 -08002067type testInstaller struct {
2068 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08002069}
2070
Colin Crossca860ac2016-01-04 14:34:37 -08002071func (installer *testInstaller) install(ctx ModuleContext, file common.Path) {
2072 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
2073 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
2074 installer.baseInstaller.install(ctx, file)
2075}
2076
2077func NewTest(hod common.HostOrDeviceSupported) *Module {
2078 module := newModule(hod, common.MultilibBoth)
2079 module.compiler = &baseCompiler{}
2080 linker := &testLinker{}
2081 linker.Properties.Gtest = true
2082 module.linker = linker
2083 module.installer = &testInstaller{
2084 baseInstaller: baseInstaller{
2085 dir: "nativetest",
2086 dir64: "nativetest64",
2087 data: true,
2088 },
Dan Albertc403f7c2015-03-18 14:01:18 -07002089 }
Colin Crossca860ac2016-01-04 14:34:37 -08002090 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002091}
2092
Colin Crossca860ac2016-01-04 14:34:37 -08002093func testFactory() (blueprint.Module, []interface{}) {
2094 module := NewTest(common.HostAndDeviceSupported)
2095 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07002096}
2097
Colin Crossca860ac2016-01-04 14:34:37 -08002098type benchmarkLinker struct {
2099 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07002100}
2101
Colin Crossca860ac2016-01-04 14:34:37 -08002102func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2103 deps = benchmark.binaryLinker.deps(ctx, deps)
2104 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
2105 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07002106}
2107
Colin Crossca860ac2016-01-04 14:34:37 -08002108func NewBenchmark(hod common.HostOrDeviceSupported) *Module {
2109 module := newModule(hod, common.MultilibFirst)
2110 module.compiler = &baseCompiler{}
2111 module.linker = &benchmarkLinker{}
2112 module.installer = &baseInstaller{
2113 dir: "nativetest",
2114 dir64: "nativetest64",
2115 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07002116 }
Colin Crossca860ac2016-01-04 14:34:37 -08002117 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07002118}
2119
Colin Crossca860ac2016-01-04 14:34:37 -08002120func benchmarkFactory() (blueprint.Module, []interface{}) {
2121 module := NewBenchmark(common.HostAndDeviceSupported)
2122 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002123}
2124
Colin Cross3f40fa42015-01-30 17:27:36 -08002125//
2126// Static library
2127//
2128
Colin Crossca860ac2016-01-04 14:34:37 -08002129func libraryStaticFactory() (blueprint.Module, []interface{}) {
2130 module := NewLibrary(common.HostAndDeviceSupported, false, true)
2131 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002132}
2133
2134//
2135// Shared libraries
2136//
2137
Colin Crossca860ac2016-01-04 14:34:37 -08002138func librarySharedFactory() (blueprint.Module, []interface{}) {
2139 module := NewLibrary(common.HostAndDeviceSupported, true, false)
2140 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002141}
2142
2143//
2144// Host static library
2145//
2146
Colin Crossca860ac2016-01-04 14:34:37 -08002147func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
2148 module := NewLibrary(common.HostSupported, false, true)
2149 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002150}
2151
2152//
2153// Host Shared libraries
2154//
2155
Colin Crossca860ac2016-01-04 14:34:37 -08002156func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
2157 module := NewLibrary(common.HostSupported, true, false)
2158 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002159}
2160
2161//
2162// Host Binaries
2163//
2164
Colin Crossca860ac2016-01-04 14:34:37 -08002165func binaryHostFactory() (blueprint.Module, []interface{}) {
2166 module := NewBinary(common.HostSupported)
2167 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002168}
2169
2170//
Colin Cross1f8f2342015-03-26 16:09:47 -07002171// Host Tests
2172//
2173
Colin Crossca860ac2016-01-04 14:34:37 -08002174func testHostFactory() (blueprint.Module, []interface{}) {
2175 module := NewTest(common.HostSupported)
2176 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07002177}
2178
2179//
Colin Cross2ba19d92015-05-07 15:44:20 -07002180// Host Benchmarks
2181//
2182
Colin Crossca860ac2016-01-04 14:34:37 -08002183func benchmarkHostFactory() (blueprint.Module, []interface{}) {
2184 module := NewBenchmark(common.HostSupported)
2185 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002186}
2187
2188//
Colin Crosscfad1192015-11-02 16:43:11 -08002189// Defaults
2190//
Colin Crossca860ac2016-01-04 14:34:37 -08002191type Defaults struct {
Colin Crosscfad1192015-11-02 16:43:11 -08002192 common.AndroidModuleBase
2193 common.DefaultsModule
2194}
2195
Colin Crossca860ac2016-01-04 14:34:37 -08002196func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002197}
2198
Colin Crossca860ac2016-01-04 14:34:37 -08002199func defaultsFactory() (blueprint.Module, []interface{}) {
2200 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002201
2202 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002203 &BaseProperties{},
2204 &BaseCompilerProperties{},
2205 &BaseLinkerProperties{},
2206 &LibraryCompilerProperties{},
Colin Cross919281a2016-04-05 16:42:05 -07002207 &FlagExporterProperties{},
Colin Crossca860ac2016-01-04 14:34:37 -08002208 &LibraryLinkerProperties{},
2209 &BinaryLinkerProperties{},
2210 &TestLinkerProperties{},
2211 &UnusedProperties{},
2212 &StlProperties{},
Colin Cross16b23492016-01-06 14:41:07 -08002213 &SanitizeProperties{},
Colin Cross665dce92016-04-28 14:50:03 -07002214 &StripProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002215 }
2216
Dan Willemsen218f6562015-07-08 18:13:11 -07002217 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault,
2218 common.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002219
2220 return common.InitDefaultsModule(module, module, propertyStructs...)
2221}
2222
2223//
Colin Cross3f40fa42015-01-30 17:27:36 -08002224// Device libraries shipped with gcc
2225//
2226
Colin Crossca860ac2016-01-04 14:34:37 -08002227type toolchainLibraryLinker struct {
2228 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002229}
2230
Colin Crossca860ac2016-01-04 14:34:37 -08002231var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2232
2233func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002234 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002235 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002236}
2237
Colin Crossca860ac2016-01-04 14:34:37 -08002238func (*toolchainLibraryLinker) buildStatic() bool {
2239 return true
2240}
Colin Cross3f40fa42015-01-30 17:27:36 -08002241
Colin Crossca860ac2016-01-04 14:34:37 -08002242func (*toolchainLibraryLinker) buildShared() bool {
2243 return false
2244}
2245
2246func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
2247 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2248 module.compiler = &baseCompiler{}
2249 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002250 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002251 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002252}
2253
Colin Crossca860ac2016-01-04 14:34:37 -08002254func (library *toolchainLibraryLinker) link(ctx ModuleContext,
2255 flags Flags, deps PathDeps, objFiles common.Paths) common.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002256
2257 libName := ctx.ModuleName() + staticLibraryExtension
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002258 outputFile := common.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002259
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002260 if flags.Clang {
2261 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2262 }
2263
Colin Crossca860ac2016-01-04 14:34:37 -08002264 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002265
2266 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002267
Colin Crossca860ac2016-01-04 14:34:37 -08002268 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002269}
2270
Colin Crossc99deeb2016-04-11 15:06:20 -07002271func (*toolchainLibraryLinker) installable() bool {
2272 return false
2273}
2274
Dan Albertbe961682015-03-18 23:38:50 -07002275// NDK prebuilt libraries.
2276//
2277// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2278// either (with the exception of the shared STLs, which are installed to the app's directory rather
2279// than to the system image).
2280
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002281func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
2282 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
2283 version, toolchain.Name()))
Dan Albertbe961682015-03-18 23:38:50 -07002284}
2285
Dan Albertc3144b12015-04-28 18:17:56 -07002286func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002287 ext string, version string) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002288
2289 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2290 // We want to translate to just NAME.EXT
2291 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2292 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002293 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002294}
2295
Colin Crossca860ac2016-01-04 14:34:37 -08002296type ndkPrebuiltObjectLinker struct {
2297 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002298}
2299
Colin Crossca860ac2016-01-04 14:34:37 -08002300func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002301 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002302 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002303}
2304
Colin Crossca860ac2016-01-04 14:34:37 -08002305func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
2306 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2307 module.linker = &ndkPrebuiltObjectLinker{}
2308 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002309}
2310
Colin Crossca860ac2016-01-04 14:34:37 -08002311func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
2312 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002313 // A null build step, but it sets up the output path.
2314 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2315 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2316 }
2317
Colin Crossca860ac2016-01-04 14:34:37 -08002318 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002319}
2320
Colin Crossca860ac2016-01-04 14:34:37 -08002321type ndkPrebuiltLibraryLinker struct {
2322 libraryLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002323}
2324
Colin Crossca860ac2016-01-04 14:34:37 -08002325var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2326var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002327
Colin Crossca860ac2016-01-04 14:34:37 -08002328func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Cross919281a2016-04-05 16:42:05 -07002329 return append(ndk.libraryLinker.props(), &ndk.Properties, &ndk.flagExporter.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002330}
2331
Colin Crossca860ac2016-01-04 14:34:37 -08002332func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002333 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002334 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002335}
2336
Colin Crossca860ac2016-01-04 14:34:37 -08002337func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
2338 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2339 linker := &ndkPrebuiltLibraryLinker{}
2340 linker.dynamicProperties.BuildShared = true
2341 module.linker = linker
2342 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002343}
2344
Colin Crossca860ac2016-01-04 14:34:37 -08002345func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
2346 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002347 // A null build step, but it sets up the output path.
2348 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2349 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2350 }
2351
Colin Cross919281a2016-04-05 16:42:05 -07002352 ndk.exportIncludes(ctx, "-isystem")
Dan Albertbe961682015-03-18 23:38:50 -07002353
Colin Crossca860ac2016-01-04 14:34:37 -08002354 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2355 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002356}
2357
2358// The NDK STLs are slightly different from the prebuilt system libraries:
2359// * Are not specific to each platform version.
2360// * The libraries are not in a predictable location for each STL.
2361
Colin Crossca860ac2016-01-04 14:34:37 -08002362type ndkPrebuiltStlLinker struct {
2363 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002364}
2365
Colin Crossca860ac2016-01-04 14:34:37 -08002366func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
2367 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2368 linker := &ndkPrebuiltStlLinker{}
2369 linker.dynamicProperties.BuildShared = true
2370 module.linker = linker
2371 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002372}
2373
Colin Crossca860ac2016-01-04 14:34:37 -08002374func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
2375 module := newBaseModule(common.DeviceSupported, common.MultilibBoth)
2376 linker := &ndkPrebuiltStlLinker{}
2377 linker.dynamicProperties.BuildStatic = true
2378 module.linker = linker
2379 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002380}
2381
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002382func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002383 gccVersion := toolchain.GccVersion()
2384 var libDir string
2385 switch stl {
2386 case "libstlport":
2387 libDir = "cxx-stl/stlport/libs"
2388 case "libc++":
2389 libDir = "cxx-stl/llvm-libc++/libs"
2390 case "libgnustl":
2391 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2392 }
2393
2394 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002395 ndkSrcRoot := "prebuilts/ndk/current/sources"
2396 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002397 }
2398
2399 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002400 return common.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002401}
2402
Colin Crossca860ac2016-01-04 14:34:37 -08002403func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
2404 deps PathDeps, objFiles common.Paths) common.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002405 // A null build step, but it sets up the output path.
2406 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2407 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2408 }
2409
Colin Cross919281a2016-04-05 16:42:05 -07002410 ndk.exportIncludes(ctx, "-I")
Dan Albertbe961682015-03-18 23:38:50 -07002411
2412 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002413 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002414 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002415 libExt = staticLibraryExtension
2416 }
2417
2418 stlName := strings.TrimSuffix(libName, "_shared")
2419 stlName = strings.TrimSuffix(stlName, "_static")
2420 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002421 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002422}
2423
Colin Cross6362e272015-10-29 15:25:03 -07002424func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002425 if m, ok := mctx.Module().(*Module); ok {
2426 if m.linker != nil {
2427 if linker, ok := m.linker.(baseLinkerInterface); ok {
2428 var modules []blueprint.Module
2429 if linker.buildStatic() && linker.buildShared() {
2430 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002431 static := modules[0].(*Module)
2432 shared := modules[1].(*Module)
2433
2434 static.linker.(baseLinkerInterface).setStatic(true)
2435 shared.linker.(baseLinkerInterface).setStatic(false)
2436
2437 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2438 sharedCompiler := shared.compiler.(*libraryCompiler)
2439 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2440 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2441 // Optimize out compiling common .o files twice for static+shared libraries
2442 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2443 sharedCompiler.baseCompiler.Properties.Srcs = nil
2444 }
2445 }
Colin Crossca860ac2016-01-04 14:34:37 -08002446 } else if linker.buildStatic() {
2447 modules = mctx.CreateLocalVariations("static")
2448 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2449 } else if linker.buildShared() {
2450 modules = mctx.CreateLocalVariations("shared")
2451 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2452 } else {
2453 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2454 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002455 }
2456 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002457 }
2458}
Colin Cross74d1ec02015-04-28 13:30:13 -07002459
2460// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2461// modifies the slice contents in place, and returns a subslice of the original slice
2462func lastUniqueElements(list []string) []string {
2463 totalSkip := 0
2464 for i := len(list) - 1; i >= totalSkip; i-- {
2465 skip := 0
2466 for j := i - 1; j >= totalSkip; j-- {
2467 if list[i] == list[j] {
2468 skip++
2469 } else {
2470 list[j+skip] = list[j]
2471 }
2472 }
2473 totalSkip += skip
2474 }
2475 return list[totalSkip:]
2476}
Colin Cross06a931b2015-10-28 17:23:31 -07002477
2478var Bool = proptools.Bool