blob: 0fa3ca9755fa49958239491196ece2293d8326e1 [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 Cross635c3b02016-05-18 15:37:25 -070030 "android/soong/android"
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 Cross635c3b02016-05-18 15:37:25 -070059 android.RegisterBottomUpMutator("link", linkageMutator)
60 android.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
61 android.RegisterBottomUpMutator("deps", depsMutator)
Colin Cross16b23492016-01-06 14:41:07 -080062
Colin Cross635c3b02016-05-18 15:37:25 -070063 android.RegisterTopDownMutator("asan_deps", sanitizerDepsMutator(asan))
64 android.RegisterBottomUpMutator("asan", sanitizerMutator(asan))
Colin Cross16b23492016-01-06 14:41:07 -080065
Colin Cross635c3b02016-05-18 15:37:25 -070066 android.RegisterTopDownMutator("tsan_deps", sanitizerDepsMutator(tsan))
67 android.RegisterBottomUpMutator("tsan", sanitizerMutator(tsan))
Colin Cross463a90e2015-06-17 14:20:06 -070068}
69
Colin Cross3f40fa42015-01-30 17:27:36 -080070var (
Colin Cross635c3b02016-05-18 15:37:25 -070071 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.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() {
Colin Cross635c3b02016-05-18 15:37:25 -0700121 if android.CurrentHostType() == android.Linux {
Dan Willemsen0c38c5e2016-03-29 17:31:57 -0700122 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) {
Colin Cross635c3b02016-05-18 15:37:25 -0700166 if override := config.(android.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700167 return override, nil
168 }
169 return "${clangDefaultBase}", nil
170 })
171 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
Colin Cross635c3b02016-05-18 15:37:25 -0700172 if override := config.(android.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700173 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 {
Colin Cross635c3b02016-05-18 15:37:25 -0700196 SharedLibs, LateSharedLibs android.Paths
197 StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700198
Colin Cross635c3b02016-05-18 15:37:25 -0700199 ObjFiles android.Paths
200 WholeStaticLibObjFiles android.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700201
Colin Cross635c3b02016-05-18 15:37:25 -0700202 GeneratedSources android.Paths
203 GeneratedHeaders android.Paths
Dan Willemsenb40aab62016-04-20 14:21:14 -0700204
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700205 Cflags, ReexportedCflags []string
206
Colin Cross635c3b02016-05-18 15:37:25 -0700207 CrtBegin, CrtEnd android.OptionalPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700208}
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
Colin Cross635c3b02016-05-18 15:37:25 -0700227 CFlagsDeps android.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 Crossbc6fb162016-05-24 15:39:04 -0700430 HideFromMake bool `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800431}
432
433type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700434 // install to a subdirectory of the default install path for the module
435 Relative_install_path string
436}
437
Colin Cross665dce92016-04-28 14:50:03 -0700438type StripProperties struct {
439 Strip struct {
440 None bool
441 Keep_symbols bool
442 }
443}
444
Colin Crossca860ac2016-01-04 14:34:37 -0800445type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700446 Native_coverage *bool
447 Required []string
Colin Cross21b481b2016-04-15 16:27:17 -0700448 Tags []string
Colin Crosscfad1192015-11-02 16:43:11 -0800449}
450
Colin Crossca860ac2016-01-04 14:34:37 -0800451type ModuleContextIntf interface {
452 module() *Module
453 static() bool
454 staticBinary() bool
455 clang() bool
456 toolchain() Toolchain
457 noDefaultCompilerFlags() bool
458 sdk() bool
459 sdkVersion() string
Dan Willemsen8146b2f2016-03-30 21:00:30 -0700460 selectedStl() string
Colin Crossca860ac2016-01-04 14:34:37 -0800461}
462
463type ModuleContext interface {
Colin Cross635c3b02016-05-18 15:37:25 -0700464 android.ModuleContext
Colin Crossca860ac2016-01-04 14:34:37 -0800465 ModuleContextIntf
466}
467
468type BaseModuleContext interface {
Colin Cross635c3b02016-05-18 15:37:25 -0700469 android.BaseContext
Colin Crossca860ac2016-01-04 14:34:37 -0800470 ModuleContextIntf
471}
472
473type Customizer interface {
474 CustomizeProperties(BaseModuleContext)
475 Properties() []interface{}
476}
477
478type feature interface {
479 begin(ctx BaseModuleContext)
480 deps(ctx BaseModuleContext, deps Deps) Deps
481 flags(ctx ModuleContext, flags Flags) Flags
482 props() []interface{}
483}
484
485type compiler interface {
486 feature
Colin Cross635c3b02016-05-18 15:37:25 -0700487 compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800488}
489
490type linker interface {
491 feature
Colin Cross635c3b02016-05-18 15:37:25 -0700492 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles android.Paths) android.Path
Colin Crossc99deeb2016-04-11 15:06:20 -0700493 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800494}
495
496type installer interface {
497 props() []interface{}
Colin Cross635c3b02016-05-18 15:37:25 -0700498 install(ctx ModuleContext, path android.Path)
Colin Crossca860ac2016-01-04 14:34:37 -0800499 inData() bool
500}
501
Colin Crossc99deeb2016-04-11 15:06:20 -0700502type dependencyTag struct {
503 blueprint.BaseDependencyTag
504 name string
505 library bool
506}
507
508var (
509 sharedDepTag = dependencyTag{name: "shared", library: true}
510 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
511 staticDepTag = dependencyTag{name: "static", library: true}
512 lateStaticDepTag = dependencyTag{name: "late static", library: true}
513 wholeStaticDepTag = dependencyTag{name: "whole static", library: true}
Dan Willemsenb40aab62016-04-20 14:21:14 -0700514 genSourceDepTag = dependencyTag{name: "gen source"}
515 genHeaderDepTag = dependencyTag{name: "gen header"}
Colin Crossc99deeb2016-04-11 15:06:20 -0700516 objDepTag = dependencyTag{name: "obj"}
517 crtBeginDepTag = dependencyTag{name: "crtbegin"}
518 crtEndDepTag = dependencyTag{name: "crtend"}
519 reuseObjTag = dependencyTag{name: "reuse objects"}
520)
521
Colin Crossca860ac2016-01-04 14:34:37 -0800522// Module contains the properties and members used by all C/C++ module types, and implements
523// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
524// to construct the output file. Behavior can be customized with a Customizer interface
525type Module struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700526 android.ModuleBase
527 android.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700528
Colin Crossca860ac2016-01-04 14:34:37 -0800529 Properties BaseProperties
530 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700531
Colin Crossca860ac2016-01-04 14:34:37 -0800532 // initialize before calling Init
Colin Cross635c3b02016-05-18 15:37:25 -0700533 hod android.HostOrDeviceSupported
534 multilib android.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700535
Colin Crossca860ac2016-01-04 14:34:37 -0800536 // delegates, initialize before calling Init
537 customizer Customizer
538 features []feature
539 compiler compiler
540 linker linker
541 installer installer
Colin Crossa8e07cc2016-04-04 15:07:06 -0700542 stl *stl
Colin Cross16b23492016-01-06 14:41:07 -0800543 sanitize *sanitize
544
545 androidMkSharedLibDeps []string
Colin Cross74d1ec02015-04-28 13:30:13 -0700546
Colin Cross635c3b02016-05-18 15:37:25 -0700547 outputFile android.OptionalPath
Colin Crossca860ac2016-01-04 14:34:37 -0800548
549 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700550}
551
Colin Crossca860ac2016-01-04 14:34:37 -0800552func (c *Module) Init() (blueprint.Module, []interface{}) {
553 props := []interface{}{&c.Properties, &c.unused}
554 if c.customizer != nil {
555 props = append(props, c.customizer.Properties()...)
556 }
557 if c.compiler != nil {
558 props = append(props, c.compiler.props()...)
559 }
560 if c.linker != nil {
561 props = append(props, c.linker.props()...)
562 }
563 if c.installer != nil {
564 props = append(props, c.installer.props()...)
565 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700566 if c.stl != nil {
567 props = append(props, c.stl.props()...)
568 }
Colin Cross16b23492016-01-06 14:41:07 -0800569 if c.sanitize != nil {
570 props = append(props, c.sanitize.props()...)
571 }
Colin Crossca860ac2016-01-04 14:34:37 -0800572 for _, feature := range c.features {
573 props = append(props, feature.props()...)
574 }
Colin Crossc472d572015-03-17 15:06:21 -0700575
Colin Cross635c3b02016-05-18 15:37:25 -0700576 _, props = android.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700577
Colin Cross635c3b02016-05-18 15:37:25 -0700578 return android.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700579}
580
Colin Crossca860ac2016-01-04 14:34:37 -0800581type baseModuleContext struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700582 android.BaseContext
Colin Crossca860ac2016-01-04 14:34:37 -0800583 moduleContextImpl
584}
585
586type moduleContext struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700587 android.ModuleContext
Colin Crossca860ac2016-01-04 14:34:37 -0800588 moduleContextImpl
589}
590
591type moduleContextImpl struct {
592 mod *Module
593 ctx BaseModuleContext
594}
595
596func (ctx *moduleContextImpl) module() *Module {
597 return ctx.mod
598}
599
600func (ctx *moduleContextImpl) clang() bool {
601 return ctx.mod.clang(ctx.ctx)
602}
603
604func (ctx *moduleContextImpl) toolchain() Toolchain {
605 return ctx.mod.toolchain(ctx.ctx)
606}
607
608func (ctx *moduleContextImpl) static() bool {
609 if ctx.mod.linker == nil {
610 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
611 }
612 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
613 return linker.static()
614 } else {
615 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
616 }
617}
618
619func (ctx *moduleContextImpl) staticBinary() bool {
620 if ctx.mod.linker == nil {
621 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
622 }
623 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
624 return linker.staticBinary()
625 } else {
626 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
627 }
628}
629
630func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
631 return Bool(ctx.mod.Properties.No_default_compiler_flags)
632}
633
634func (ctx *moduleContextImpl) sdk() bool {
635 return ctx.mod.Properties.Sdk_version != ""
636}
637
638func (ctx *moduleContextImpl) sdkVersion() string {
639 return ctx.mod.Properties.Sdk_version
640}
641
Dan Willemsen8146b2f2016-03-30 21:00:30 -0700642func (ctx *moduleContextImpl) selectedStl() string {
643 if stl := ctx.mod.stl; stl != nil {
644 return stl.Properties.SelectedStl
645 }
646 return ""
647}
648
Colin Cross635c3b02016-05-18 15:37:25 -0700649func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
Colin Crossca860ac2016-01-04 14:34:37 -0800650 return &Module{
651 hod: hod,
652 multilib: multilib,
653 }
654}
655
Colin Cross635c3b02016-05-18 15:37:25 -0700656func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
Colin Crossca860ac2016-01-04 14:34:37 -0800657 module := newBaseModule(hod, multilib)
Colin Crossa8e07cc2016-04-04 15:07:06 -0700658 module.stl = &stl{}
Colin Cross16b23492016-01-06 14:41:07 -0800659 module.sanitize = &sanitize{}
Colin Crossca860ac2016-01-04 14:34:37 -0800660 return module
661}
662
Colin Cross635c3b02016-05-18 15:37:25 -0700663func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800664 ctx := &moduleContext{
Colin Cross635c3b02016-05-18 15:37:25 -0700665 ModuleContext: actx,
Colin Crossca860ac2016-01-04 14:34:37 -0800666 moduleContextImpl: moduleContextImpl{
667 mod: c,
668 },
669 }
670 ctx.ctx = ctx
671
672 flags := Flags{
673 Toolchain: c.toolchain(ctx),
674 Clang: c.clang(ctx),
675 }
Colin Crossca860ac2016-01-04 14:34:37 -0800676 if c.compiler != nil {
677 flags = c.compiler.flags(ctx, flags)
678 }
679 if c.linker != nil {
680 flags = c.linker.flags(ctx, flags)
681 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700682 if c.stl != nil {
683 flags = c.stl.flags(ctx, flags)
684 }
Colin Cross16b23492016-01-06 14:41:07 -0800685 if c.sanitize != nil {
686 flags = c.sanitize.flags(ctx, flags)
687 }
Colin Crossca860ac2016-01-04 14:34:37 -0800688 for _, feature := range c.features {
689 flags = feature.flags(ctx, flags)
690 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800691 if ctx.Failed() {
692 return
693 }
694
Colin Crossca860ac2016-01-04 14:34:37 -0800695 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
696 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
697 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800698
Colin Crossca860ac2016-01-04 14:34:37 -0800699 // Optimization to reduce size of build.ninja
700 // Replace the long list of flags for each file with a module-local variable
701 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
702 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
703 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
704 flags.CFlags = []string{"$cflags"}
705 flags.CppFlags = []string{"$cppflags"}
706 flags.AsFlags = []string{"$asflags"}
707
Colin Crossc99deeb2016-04-11 15:06:20 -0700708 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800709 if ctx.Failed() {
710 return
711 }
712
Colin Cross28344522015-04-22 13:07:53 -0700713 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700714
Colin Cross635c3b02016-05-18 15:37:25 -0700715 var objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800716 if c.compiler != nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700717 objFiles = c.compiler.compile(ctx, flags, deps)
Colin Crossca860ac2016-01-04 14:34:37 -0800718 if ctx.Failed() {
719 return
720 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800721 }
722
Colin Crossca860ac2016-01-04 14:34:37 -0800723 if c.linker != nil {
724 outputFile := c.linker.link(ctx, flags, deps, objFiles)
725 if ctx.Failed() {
726 return
727 }
Colin Cross635c3b02016-05-18 15:37:25 -0700728 c.outputFile = android.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700729
Colin Crossc99deeb2016-04-11 15:06:20 -0700730 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800731 c.installer.install(ctx, outputFile)
732 if ctx.Failed() {
733 return
734 }
735 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700736 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800737}
738
Colin Crossca860ac2016-01-04 14:34:37 -0800739func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
740 if c.cachedToolchain == nil {
741 arch := ctx.Arch()
742 hod := ctx.HostOrDevice()
743 ht := ctx.HostType()
744 factory := toolchainFactories[hod][ht][arch.ArchType]
745 if factory == nil {
746 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
747 return nil
748 }
749 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800750 }
Colin Crossca860ac2016-01-04 14:34:37 -0800751 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800752}
753
Colin Crossca860ac2016-01-04 14:34:37 -0800754func (c *Module) begin(ctx BaseModuleContext) {
755 if c.compiler != nil {
756 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700757 }
Colin Crossca860ac2016-01-04 14:34:37 -0800758 if c.linker != nil {
759 c.linker.begin(ctx)
760 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700761 if c.stl != nil {
762 c.stl.begin(ctx)
763 }
Colin Cross16b23492016-01-06 14:41:07 -0800764 if c.sanitize != nil {
765 c.sanitize.begin(ctx)
766 }
Colin Crossca860ac2016-01-04 14:34:37 -0800767 for _, feature := range c.features {
768 feature.begin(ctx)
769 }
770}
771
Colin Crossc99deeb2016-04-11 15:06:20 -0700772func (c *Module) deps(ctx BaseModuleContext) Deps {
773 deps := Deps{}
774
775 if c.compiler != nil {
776 deps = c.compiler.deps(ctx, deps)
777 }
778 if c.linker != nil {
779 deps = c.linker.deps(ctx, deps)
780 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700781 if c.stl != nil {
782 deps = c.stl.deps(ctx, deps)
783 }
Colin Cross16b23492016-01-06 14:41:07 -0800784 if c.sanitize != nil {
785 deps = c.sanitize.deps(ctx, deps)
786 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700787 for _, feature := range c.features {
788 deps = feature.deps(ctx, deps)
789 }
790
791 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
792 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
793 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
794 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
795 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
796
797 return deps
798}
799
Colin Cross635c3b02016-05-18 15:37:25 -0700800func (c *Module) depsMutator(actx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800801 ctx := &baseModuleContext{
Colin Cross635c3b02016-05-18 15:37:25 -0700802 BaseContext: actx,
Colin Crossca860ac2016-01-04 14:34:37 -0800803 moduleContextImpl: moduleContextImpl{
804 mod: c,
805 },
806 }
807 ctx.ctx = ctx
808
809 if c.customizer != nil {
810 c.customizer.CustomizeProperties(ctx)
811 }
812
813 c.begin(ctx)
814
Colin Crossc99deeb2016-04-11 15:06:20 -0700815 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800816
Colin Crossc99deeb2016-04-11 15:06:20 -0700817 c.Properties.AndroidMkSharedLibs = deps.SharedLibs
818
819 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
820 deps.WholeStaticLibs...)
821
822 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticDepTag,
823 deps.StaticLibs...)
824
825 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
826 deps.LateStaticLibs...)
827
828 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedDepTag,
829 deps.SharedLibs...)
830
831 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
832 deps.LateSharedLibs...)
833
Dan Willemsenb40aab62016-04-20 14:21:14 -0700834 actx.AddDependency(ctx.module(), genSourceDepTag, deps.GeneratedSources...)
835 actx.AddDependency(ctx.module(), genHeaderDepTag, deps.GeneratedHeaders...)
836
Colin Crossc99deeb2016-04-11 15:06:20 -0700837 actx.AddDependency(ctx.module(), objDepTag, deps.ObjFiles...)
838
839 if deps.CrtBegin != "" {
840 actx.AddDependency(ctx.module(), crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800841 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700842 if deps.CrtEnd != "" {
843 actx.AddDependency(ctx.module(), crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700844 }
Colin Cross6362e272015-10-29 15:25:03 -0700845}
Colin Cross21b9a242015-03-24 14:15:58 -0700846
Colin Cross635c3b02016-05-18 15:37:25 -0700847func depsMutator(ctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800848 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700849 c.depsMutator(ctx)
850 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800851}
852
Colin Crossca860ac2016-01-04 14:34:37 -0800853func (c *Module) clang(ctx BaseModuleContext) bool {
854 clang := Bool(c.Properties.Clang)
855
856 if c.Properties.Clang == nil {
857 if ctx.Host() {
858 clang = true
859 }
860
861 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
862 clang = true
863 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800864 }
Colin Cross28344522015-04-22 13:07:53 -0700865
Colin Crossca860ac2016-01-04 14:34:37 -0800866 if !c.toolchain(ctx).ClangSupported() {
867 clang = false
868 }
869
870 return clang
871}
872
Colin Crossc99deeb2016-04-11 15:06:20 -0700873// Convert dependencies to paths. Returns a PathDeps containing paths
Colin Cross635c3b02016-05-18 15:37:25 -0700874func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800875 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800876
Colin Crossc99deeb2016-04-11 15:06:20 -0700877 ctx.VisitDirectDeps(func(m blueprint.Module) {
878 name := ctx.OtherModuleName(m)
879 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800880
Colin Cross635c3b02016-05-18 15:37:25 -0700881 a, _ := m.(android.Module)
Colin Crossc99deeb2016-04-11 15:06:20 -0700882 if a == nil {
883 ctx.ModuleErrorf("module %q not an android module", name)
884 return
Colin Crossca860ac2016-01-04 14:34:37 -0800885 }
Colin Crossca860ac2016-01-04 14:34:37 -0800886
Colin Crossc99deeb2016-04-11 15:06:20 -0700887 c, _ := m.(*Module)
888 if c == nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700889 switch tag {
Colin Cross635c3b02016-05-18 15:37:25 -0700890 case android.DefaultsDepTag:
Dan Willemsenb40aab62016-04-20 14:21:14 -0700891 case genSourceDepTag:
892 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
893 depPaths.GeneratedSources = append(depPaths.GeneratedSources,
894 genRule.GeneratedSourceFiles()...)
895 } else {
896 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
897 }
898 case genHeaderDepTag:
899 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
900 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
901 genRule.GeneratedSourceFiles()...)
902 depPaths.Cflags = append(depPaths.Cflags,
Colin Cross635c3b02016-05-18 15:37:25 -0700903 includeDirsToFlags(android.Paths{genRule.GeneratedHeaderDir()}))
Dan Willemsenb40aab62016-04-20 14:21:14 -0700904 } else {
905 ctx.ModuleErrorf("module %q is not a genrule", name)
906 }
907 default:
Colin Crossc99deeb2016-04-11 15:06:20 -0700908 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -0800909 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700910 return
911 }
912
913 if !a.Enabled() {
914 ctx.ModuleErrorf("depends on disabled module %q", name)
915 return
916 }
917
918 if a.HostOrDevice() != ctx.HostOrDevice() {
919 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(), name)
920 return
921 }
922
923 if !c.outputFile.Valid() {
924 ctx.ModuleErrorf("module %q missing output file", name)
925 return
926 }
927
928 if tag == reuseObjTag {
929 depPaths.ObjFiles = append(depPaths.ObjFiles,
930 c.compiler.(*libraryCompiler).reuseObjFiles...)
931 return
932 }
933
934 var cflags []string
935 if t, _ := tag.(dependencyTag); t.library {
936 if i, ok := c.linker.(exportedFlagsProducer); ok {
937 cflags = i.exportedFlags()
938 depPaths.Cflags = append(depPaths.Cflags, cflags...)
939 }
940 }
941
Colin Cross635c3b02016-05-18 15:37:25 -0700942 var depPtr *android.Paths
Colin Crossc99deeb2016-04-11 15:06:20 -0700943
944 switch tag {
945 case sharedDepTag:
946 depPtr = &depPaths.SharedLibs
947 case lateSharedDepTag:
948 depPtr = &depPaths.LateSharedLibs
949 case staticDepTag:
950 depPtr = &depPaths.StaticLibs
951 case lateStaticDepTag:
952 depPtr = &depPaths.LateStaticLibs
953 case wholeStaticDepTag:
954 depPtr = &depPaths.WholeStaticLibs
955 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, cflags...)
956 staticLib, _ := c.linker.(*libraryLinker)
957 if staticLib == nil || !staticLib.static() {
958 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
959 return
960 }
961
962 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
963 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
964 for i := range missingDeps {
965 missingDeps[i] += postfix
966 }
967 ctx.AddMissingDependencies(missingDeps)
968 }
969 depPaths.WholeStaticLibObjFiles =
970 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
971 case objDepTag:
972 depPtr = &depPaths.ObjFiles
973 case crtBeginDepTag:
974 depPaths.CrtBegin = c.outputFile
975 case crtEndDepTag:
976 depPaths.CrtEnd = c.outputFile
977 default:
978 panic(fmt.Errorf("unknown dependency tag: %s", ctx.OtherModuleDependencyTag(m)))
979 }
980
981 if depPtr != nil {
982 *depPtr = append(*depPtr, c.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -0800983 }
984 })
985
986 return depPaths
987}
988
989func (c *Module) InstallInData() bool {
990 if c.installer == nil {
991 return false
992 }
993 return c.installer.inData()
994}
995
996// Compiler
997
998type baseCompiler struct {
999 Properties BaseCompilerProperties
1000}
1001
1002var _ compiler = (*baseCompiler)(nil)
1003
1004func (compiler *baseCompiler) props() []interface{} {
1005 return []interface{}{&compiler.Properties}
1006}
1007
Dan Willemsenb40aab62016-04-20 14:21:14 -07001008func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
1009
1010func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
1011 deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
1012 deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
1013
1014 return deps
1015}
Colin Crossca860ac2016-01-04 14:34:37 -08001016
1017// Create a Flags struct that collects the compile flags from global values,
1018// per-target values, module type values, and per-module Blueprints properties
1019func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1020 toolchain := ctx.toolchain()
1021
1022 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
1023 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
1024 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
1025 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
1026 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
1027
Colin Cross28344522015-04-22 13:07:53 -07001028 // Include dir cflags
Colin Cross635c3b02016-05-18 15:37:25 -07001029 rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
1030 localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -07001031 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -07001032 includeDirsToFlags(localIncludeDirs),
1033 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -07001034
Colin Cross635c3b02016-05-18 15:37:25 -07001035 rootIncludeFiles := android.PathsForSource(ctx, compiler.Properties.Include_files)
1036 localIncludeFiles := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files)
Colin Cross39d97f22015-09-14 12:30:50 -07001037
1038 flags.GlobalFlags = append(flags.GlobalFlags,
1039 includeFilesToFlags(rootIncludeFiles),
1040 includeFilesToFlags(localIncludeFiles))
1041
Colin Crossca860ac2016-01-04 14:34:37 -08001042 if !ctx.noDefaultCompilerFlags() {
1043 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -07001044 flags.GlobalFlags = append(flags.GlobalFlags,
1045 "${commonGlobalIncludes}",
1046 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -08001047 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -07001048 }
1049
1050 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Colin Cross635c3b02016-05-18 15:37:25 -07001051 "-I" + android.PathForModuleSrc(ctx).String(),
1052 "-I" + android.PathForModuleOut(ctx).String(),
1053 "-I" + android.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -07001054 }...)
1055 }
1056
Colin Crossca860ac2016-01-04 14:34:37 -08001057 instructionSet := compiler.Properties.Instruction_set
1058 if flags.RequiredInstructionSet != "" {
1059 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -08001060 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001061 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
1062 if flags.Clang {
1063 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
1064 }
1065 if err != nil {
1066 ctx.ModuleErrorf("%s", err)
1067 }
1068
1069 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -08001070 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001071
Colin Cross97ba0732015-03-23 17:50:24 -07001072 if flags.Clang {
1073 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001074 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
1075 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -07001076 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
1077 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
1078 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001079
1080 target := "-target " + toolchain.ClangTriple()
Dan Willemsen3772da12016-05-16 18:01:46 -07001081 var gccPrefix string
1082 if !ctx.Darwin() {
1083 gccPrefix = "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
1084 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001085
Colin Cross97ba0732015-03-23 17:50:24 -07001086 flags.CFlags = append(flags.CFlags, target, gccPrefix)
1087 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
1088 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -08001089 }
1090
Colin Crossca860ac2016-01-04 14:34:37 -08001091 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001092 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1093
Colin Cross97ba0732015-03-23 17:50:24 -07001094 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001095 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001096 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001097 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001098 toolchain.ClangCflags(),
1099 "${commonClangGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001100 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001101
1102 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001103 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001104 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001105 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001106 toolchain.Cflags(),
1107 "${commonGlobalCflags}",
Colin Crossd3ba0392015-05-07 14:11:29 -07001108 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
Colin Cross3f40fa42015-01-30 17:27:36 -08001109 }
1110
Colin Cross7b66f152015-12-15 16:07:43 -08001111 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1112 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1113 }
1114
Colin Crossf6566ed2015-03-24 11:13:38 -07001115 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001116 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001117 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001118 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001119 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001120 }
1121 }
1122
Colin Cross97ba0732015-03-23 17:50:24 -07001123 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001124
Colin Cross97ba0732015-03-23 17:50:24 -07001125 if flags.Clang {
1126 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001127 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001128 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001129 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001130 }
1131
Colin Crossc4bde762015-11-23 16:11:30 -08001132 if flags.Clang {
1133 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1134 } else {
1135 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001136 }
1137
Colin Crossca860ac2016-01-04 14:34:37 -08001138 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001139 if ctx.Host() && !flags.Clang {
1140 // The host GCC doesn't support C++14 (and is deprecated, so likely
1141 // never will). Build these modules with C++11.
1142 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1143 } else {
1144 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1145 }
1146 }
1147
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001148 // We can enforce some rules more strictly in the code we own. strict
1149 // indicates if this is code that we can be stricter with. If we have
1150 // rules that we want to apply to *our* code (but maybe can't for
1151 // vendor/device specific things), we could extend this to be a ternary
1152 // value.
1153 strict := true
Colin Cross635c3b02016-05-18 15:37:25 -07001154 if strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "external/") {
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001155 strict = false
1156 }
1157
1158 // Can be used to make some annotations stricter for code we can fix
1159 // (such as when we mark functions as deprecated).
1160 if strict {
1161 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1162 }
1163
Colin Cross3f40fa42015-01-30 17:27:36 -08001164 return flags
1165}
1166
Colin Cross635c3b02016-05-18 15:37:25 -07001167func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001168 // Compile files listed in c.Properties.Srcs into objects
Dan Willemsenb40aab62016-04-20 14:21:14 -07001169 objFiles := compiler.compileObjs(ctx, flags, "",
1170 compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
1171 deps.GeneratedSources, deps.GeneratedHeaders)
1172
Colin Crossca860ac2016-01-04 14:34:37 -08001173 if ctx.Failed() {
1174 return nil
1175 }
1176
Colin Crossca860ac2016-01-04 14:34:37 -08001177 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001178}
1179
1180// Compile a list of source files into objects a specified subdirectory
Colin Cross635c3b02016-05-18 15:37:25 -07001181func (compiler *baseCompiler) compileObjs(ctx android.ModuleContext, flags Flags,
1182 subdir string, srcFiles, excludes []string, extraSrcs, deps android.Paths) android.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001183
Colin Crossca860ac2016-01-04 14:34:37 -08001184 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001185
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001186 inputFiles := ctx.ExpandSources(srcFiles, excludes)
Dan Willemsenb40aab62016-04-20 14:21:14 -07001187 inputFiles = append(inputFiles, extraSrcs...)
1188 srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)
1189
1190 deps = append(deps, gendeps...)
Colin Cross16b23492016-01-06 14:41:07 -08001191 deps = append(deps, flags.CFlagsDeps...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001192
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001193 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001194}
1195
Colin Crossca860ac2016-01-04 14:34:37 -08001196// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1197type baseLinker struct {
1198 Properties BaseLinkerProperties
1199 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001200 VariantIsShared bool `blueprint:"mutated"`
1201 VariantIsStatic bool `blueprint:"mutated"`
1202 VariantIsStaticBinary bool `blueprint:"mutated"`
1203 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001204 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001205}
1206
Dan Willemsend30e6102016-03-30 17:35:50 -07001207func (linker *baseLinker) begin(ctx BaseModuleContext) {
1208 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001209 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001210 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001211 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001212 }
1213}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001214
Colin Crossca860ac2016-01-04 14:34:37 -08001215func (linker *baseLinker) props() []interface{} {
1216 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001217}
1218
Colin Crossca860ac2016-01-04 14:34:37 -08001219func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1220 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1221 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1222 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001223
Colin Cross74d1ec02015-04-28 13:30:13 -07001224 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001225 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001226 }
1227
Colin Crossf6566ed2015-03-24 11:13:38 -07001228 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001229 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001230 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1231 if !Bool(linker.Properties.No_libgcc) {
1232 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001233 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001234
Colin Crossca860ac2016-01-04 14:34:37 -08001235 if !linker.static() {
1236 if linker.Properties.System_shared_libs != nil {
1237 deps.LateSharedLibs = append(deps.LateSharedLibs,
1238 linker.Properties.System_shared_libs...)
1239 } else if !ctx.sdk() {
1240 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1241 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001242 }
Colin Cross577f6e42015-03-27 18:23:34 -07001243
Colin Crossca860ac2016-01-04 14:34:37 -08001244 if ctx.sdk() {
1245 version := ctx.sdkVersion()
1246 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001247 "ndk_libc."+version,
1248 "ndk_libm."+version,
1249 )
1250 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001251 }
1252
Colin Crossca860ac2016-01-04 14:34:37 -08001253 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001254}
1255
Colin Crossca860ac2016-01-04 14:34:37 -08001256func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1257 toolchain := ctx.toolchain()
1258
Colin Crossca860ac2016-01-04 14:34:37 -08001259 if !ctx.noDefaultCompilerFlags() {
1260 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1261 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1262 }
1263
1264 if flags.Clang {
1265 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1266 } else {
1267 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1268 }
1269
1270 if ctx.Host() {
1271 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1272 }
1273 }
1274
Dan Willemsen00ced762016-05-10 17:31:21 -07001275 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1276
Dan Willemsend30e6102016-03-30 17:35:50 -07001277 if ctx.Host() && !linker.static() {
1278 rpath_prefix := `\$$ORIGIN/`
1279 if ctx.Darwin() {
1280 rpath_prefix = "@loader_path/"
1281 }
1282
Colin Crossc99deeb2016-04-11 15:06:20 -07001283 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001284 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1285 }
1286 }
1287
Dan Willemsene7174922016-03-30 17:33:52 -07001288 if flags.Clang {
1289 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1290 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001291 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1292 }
1293
1294 return flags
1295}
1296
1297func (linker *baseLinker) static() bool {
1298 return linker.dynamicProperties.VariantIsStatic
1299}
1300
1301func (linker *baseLinker) staticBinary() bool {
1302 return linker.dynamicProperties.VariantIsStaticBinary
1303}
1304
1305func (linker *baseLinker) setStatic(static bool) {
1306 linker.dynamicProperties.VariantIsStatic = static
1307}
1308
Colin Cross16b23492016-01-06 14:41:07 -08001309func (linker *baseLinker) isDependencyRoot() bool {
1310 return false
1311}
1312
Colin Crossca860ac2016-01-04 14:34:37 -08001313type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001314 // Returns true if the build options for the module have selected a static or shared build
1315 buildStatic() bool
1316 buildShared() bool
1317
1318 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001319 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001320
Colin Cross18b6dc52015-04-28 13:20:37 -07001321 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001322 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001323
1324 // Returns whether a module is a static binary
1325 staticBinary() bool
Colin Cross16b23492016-01-06 14:41:07 -08001326
1327 // Returns true for dependency roots (binaries)
1328 // TODO(ccross): also handle dlopenable libraries
1329 isDependencyRoot() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001330}
1331
Colin Crossca860ac2016-01-04 14:34:37 -08001332type baseInstaller struct {
1333 Properties InstallerProperties
1334
1335 dir string
1336 dir64 string
1337 data bool
1338
Colin Cross635c3b02016-05-18 15:37:25 -07001339 path android.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001340}
1341
1342var _ installer = (*baseInstaller)(nil)
1343
1344func (installer *baseInstaller) props() []interface{} {
1345 return []interface{}{&installer.Properties}
1346}
1347
Colin Cross635c3b02016-05-18 15:37:25 -07001348func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08001349 subDir := installer.dir
1350 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1351 subDir = installer.dir64
1352 }
Colin Cross635c3b02016-05-18 15:37:25 -07001353 dir := android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
Colin Crossca860ac2016-01-04 14:34:37 -08001354 installer.path = ctx.InstallFile(dir, file)
1355}
1356
1357func (installer *baseInstaller) inData() bool {
1358 return installer.data
1359}
1360
Colin Cross3f40fa42015-01-30 17:27:36 -08001361//
1362// Combined static+shared libraries
1363//
1364
Colin Cross919281a2016-04-05 16:42:05 -07001365type flagExporter struct {
1366 Properties FlagExporterProperties
1367
1368 flags []string
1369}
1370
1371func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
Colin Cross635c3b02016-05-18 15:37:25 -07001372 includeDirs := android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
1373 f.flags = append(f.flags, android.JoinWithPrefix(includeDirs.Strings(), inc))
Colin Cross919281a2016-04-05 16:42:05 -07001374}
1375
1376func (f *flagExporter) reexportFlags(flags []string) {
1377 f.flags = append(f.flags, flags...)
1378}
1379
1380func (f *flagExporter) exportedFlags() []string {
1381 return f.flags
1382}
1383
1384type exportedFlagsProducer interface {
1385 exportedFlags() []string
1386}
1387
1388var _ exportedFlagsProducer = (*flagExporter)(nil)
1389
Colin Crossca860ac2016-01-04 14:34:37 -08001390type libraryCompiler struct {
1391 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001392
Colin Crossca860ac2016-01-04 14:34:37 -08001393 linker *libraryLinker
1394 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001395
Colin Crossca860ac2016-01-04 14:34:37 -08001396 // For reusing static library objects for shared library
Colin Cross635c3b02016-05-18 15:37:25 -07001397 reuseObjFiles android.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001398}
1399
Colin Crossca860ac2016-01-04 14:34:37 -08001400var _ compiler = (*libraryCompiler)(nil)
1401
1402func (library *libraryCompiler) props() []interface{} {
1403 props := library.baseCompiler.props()
1404 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001405}
1406
Colin Crossca860ac2016-01-04 14:34:37 -08001407func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1408 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001409
Dan Willemsen490fd492015-11-24 17:53:15 -08001410 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1411 // all code is position independent, and then those warnings get promoted to
1412 // errors.
Colin Cross635c3b02016-05-18 15:37:25 -07001413 if ctx.HostType() != android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08001414 flags.CFlags = append(flags.CFlags, "-fPIC")
1415 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001416
Colin Crossca860ac2016-01-04 14:34:37 -08001417 if library.linker.static() {
1418 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001419 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001420 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001421 }
1422
Colin Crossca860ac2016-01-04 14:34:37 -08001423 return flags
1424}
1425
Colin Cross635c3b02016-05-18 15:37:25 -07001426func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
1427 var objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -08001428
Dan Willemsenb40aab62016-04-20 14:21:14 -07001429 objFiles = library.baseCompiler.compile(ctx, flags, deps)
Colin Crossc99deeb2016-04-11 15:06:20 -07001430 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001431
1432 if library.linker.static() {
Colin Cross635c3b02016-05-18 15:37:25 -07001433 objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceStaticLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001434 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
1435 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001436 } else {
Colin Cross635c3b02016-05-18 15:37:25 -07001437 objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceSharedLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001438 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
1439 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001440 }
1441
1442 return objFiles
1443}
1444
1445type libraryLinker struct {
1446 baseLinker
Colin Cross919281a2016-04-05 16:42:05 -07001447 flagExporter
Colin Cross665dce92016-04-28 14:50:03 -07001448 stripper
Colin Crossca860ac2016-01-04 14:34:37 -08001449
1450 Properties LibraryLinkerProperties
1451
1452 dynamicProperties struct {
1453 BuildStatic bool `blueprint:"mutated"`
1454 BuildShared bool `blueprint:"mutated"`
1455 }
1456
Colin Crossca860ac2016-01-04 14:34:37 -08001457 // If we're used as a whole_static_lib, our missing dependencies need
1458 // to be given
1459 wholeStaticMissingDeps []string
1460
1461 // For whole_static_libs
Colin Cross635c3b02016-05-18 15:37:25 -07001462 objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -08001463}
1464
1465var _ linker = (*libraryLinker)(nil)
Colin Crossca860ac2016-01-04 14:34:37 -08001466
1467func (library *libraryLinker) props() []interface{} {
1468 props := library.baseLinker.props()
Colin Cross919281a2016-04-05 16:42:05 -07001469 return append(props,
1470 &library.Properties,
1471 &library.dynamicProperties,
Colin Cross665dce92016-04-28 14:50:03 -07001472 &library.flagExporter.Properties,
1473 &library.stripper.StripProperties)
Colin Crossca860ac2016-01-04 14:34:37 -08001474}
1475
1476func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1477 flags = library.baseLinker.flags(ctx, flags)
1478
1479 flags.Nocrt = Bool(library.Properties.Nocrt)
1480
1481 if !library.static() {
Colin Cross30d5f512016-05-03 18:02:42 -07001482 libName := ctx.ModuleName() + library.Properties.VariantName
Colin Cross3f40fa42015-01-30 17:27:36 -08001483 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1484 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001485 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001486 sharedFlag = "-shared"
1487 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001488 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001489 flags.LdFlags = append(flags.LdFlags,
1490 "-nostdlib",
1491 "-Wl,--gc-sections",
1492 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001493 }
Colin Cross97ba0732015-03-23 17:50:24 -07001494
Colin Cross0af4b842015-04-30 16:36:18 -07001495 if ctx.Darwin() {
1496 flags.LdFlags = append(flags.LdFlags,
1497 "-dynamiclib",
1498 "-single_module",
1499 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001500 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001501 )
1502 } else {
1503 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001504 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001505 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001506 )
1507 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001508 }
Colin Cross97ba0732015-03-23 17:50:24 -07001509
1510 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001511}
1512
Colin Crossca860ac2016-01-04 14:34:37 -08001513func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1514 deps = library.baseLinker.deps(ctx, deps)
1515 if library.static() {
1516 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1517 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1518 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1519 } else {
1520 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1521 if !ctx.sdk() {
1522 deps.CrtBegin = "crtbegin_so"
1523 deps.CrtEnd = "crtend_so"
1524 } else {
1525 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1526 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1527 }
1528 }
1529 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1530 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1531 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1532 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001533
Colin Crossca860ac2016-01-04 14:34:37 -08001534 return deps
1535}
Colin Cross3f40fa42015-01-30 17:27:36 -08001536
Colin Crossca860ac2016-01-04 14:34:37 -08001537func (library *libraryLinker) linkStatic(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001538 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Crossca860ac2016-01-04 14:34:37 -08001539
Colin Cross635c3b02016-05-18 15:37:25 -07001540 library.objFiles = append(android.Paths{}, deps.WholeStaticLibObjFiles...)
Dan Willemsen025b4802016-05-11 17:25:48 -07001541 library.objFiles = append(library.objFiles, objFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001542
Colin Cross635c3b02016-05-18 15:37:25 -07001543 outputFile := android.PathForModuleOut(ctx,
Colin Cross16b23492016-01-06 14:41:07 -08001544 ctx.ModuleName()+library.Properties.VariantName+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001545
Colin Cross0af4b842015-04-30 16:36:18 -07001546 if ctx.Darwin() {
Dan Willemsen025b4802016-05-11 17:25:48 -07001547 TransformDarwinObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001548 } else {
Dan Willemsen025b4802016-05-11 17:25:48 -07001549 TransformObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001550 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001551
Colin Crossca860ac2016-01-04 14:34:37 -08001552 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001553
1554 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001555
1556 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001557}
1558
Colin Crossca860ac2016-01-04 14:34:37 -08001559func (library *libraryLinker) linkShared(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001560 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001561
Colin Cross635c3b02016-05-18 15:37:25 -07001562 var linkerDeps android.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001563
Colin Cross635c3b02016-05-18 15:37:25 -07001564 versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1565 unexportedSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1566 forceNotWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1567 forceWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001568 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001569 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001570 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001571 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001572 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001573 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001574 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1575 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001576 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001577 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1578 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001579 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001580 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1581 }
1582 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001583 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001584 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1585 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001586 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001587 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001588 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001589 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001590 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001591 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001592 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001593 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001594 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001595 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001596 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001597 }
Colin Crossaee540a2015-07-06 17:48:31 -07001598 }
1599
Colin Cross665dce92016-04-28 14:50:03 -07001600 fileName := ctx.ModuleName() + library.Properties.VariantName + flags.Toolchain.ShlibSuffix()
Colin Cross635c3b02016-05-18 15:37:25 -07001601 outputFile := android.PathForModuleOut(ctx, fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001602 ret := outputFile
1603
1604 builderFlags := flagsToBuilderFlags(flags)
1605
1606 if library.stripper.needsStrip(ctx) {
1607 strippedOutputFile := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07001608 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001609 library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
1610 }
1611
Colin Crossca860ac2016-01-04 14:34:37 -08001612 sharedLibs := deps.SharedLibs
1613 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001614
Colin Crossca860ac2016-01-04 14:34:37 -08001615 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1616 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
Colin Cross665dce92016-04-28 14:50:03 -07001617 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001618
Colin Cross665dce92016-04-28 14:50:03 -07001619 return ret
Colin Cross3f40fa42015-01-30 17:27:36 -08001620}
1621
Colin Crossca860ac2016-01-04 14:34:37 -08001622func (library *libraryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001623 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001624
Colin Crossc99deeb2016-04-11 15:06:20 -07001625 objFiles = append(objFiles, deps.ObjFiles...)
1626
Colin Cross635c3b02016-05-18 15:37:25 -07001627 var out android.Path
Colin Crossca860ac2016-01-04 14:34:37 -08001628 if library.static() {
1629 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001630 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001631 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001632 }
1633
Colin Cross919281a2016-04-05 16:42:05 -07001634 library.exportIncludes(ctx, "-I")
1635 library.reexportFlags(deps.ReexportedCflags)
Colin Crossca860ac2016-01-04 14:34:37 -08001636
1637 return out
1638}
1639
1640func (library *libraryLinker) buildStatic() bool {
1641 return library.dynamicProperties.BuildStatic
1642}
1643
1644func (library *libraryLinker) buildShared() bool {
1645 return library.dynamicProperties.BuildShared
1646}
1647
1648func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1649 return library.wholeStaticMissingDeps
1650}
1651
Colin Crossc99deeb2016-04-11 15:06:20 -07001652func (library *libraryLinker) installable() bool {
1653 return !library.static()
1654}
1655
Colin Crossca860ac2016-01-04 14:34:37 -08001656type libraryInstaller struct {
1657 baseInstaller
1658
Colin Cross30d5f512016-05-03 18:02:42 -07001659 linker *libraryLinker
1660 sanitize *sanitize
Colin Crossca860ac2016-01-04 14:34:37 -08001661}
1662
Colin Cross635c3b02016-05-18 15:37:25 -07001663func (library *libraryInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08001664 if !library.linker.static() {
1665 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001666 }
1667}
1668
Colin Cross30d5f512016-05-03 18:02:42 -07001669func (library *libraryInstaller) inData() bool {
1670 return library.baseInstaller.inData() || library.sanitize.inData()
1671}
1672
Colin Cross635c3b02016-05-18 15:37:25 -07001673func NewLibrary(hod android.HostOrDeviceSupported, shared, static bool) *Module {
1674 module := newModule(hod, android.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001675
Colin Crossca860ac2016-01-04 14:34:37 -08001676 linker := &libraryLinker{}
1677 linker.dynamicProperties.BuildShared = shared
1678 linker.dynamicProperties.BuildStatic = static
1679 module.linker = linker
1680
1681 module.compiler = &libraryCompiler{
1682 linker: linker,
1683 }
1684 module.installer = &libraryInstaller{
1685 baseInstaller: baseInstaller{
1686 dir: "lib",
1687 dir64: "lib64",
1688 },
Colin Cross30d5f512016-05-03 18:02:42 -07001689 linker: linker,
1690 sanitize: module.sanitize,
Dan Albertc403f7c2015-03-18 14:01:18 -07001691 }
1692
Colin Crossca860ac2016-01-04 14:34:37 -08001693 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001694}
1695
Colin Crossca860ac2016-01-04 14:34:37 -08001696func libraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001697 module := NewLibrary(android.HostAndDeviceSupported, true, true)
Colin Crossca860ac2016-01-04 14:34:37 -08001698 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001699}
1700
Colin Cross3f40fa42015-01-30 17:27:36 -08001701//
1702// Objects (for crt*.o)
1703//
1704
Colin Crossca860ac2016-01-04 14:34:37 -08001705type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001706 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001707}
1708
Colin Crossca860ac2016-01-04 14:34:37 -08001709func objectFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001710 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08001711 module.compiler = &baseCompiler{}
1712 module.linker = &objectLinker{}
1713 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001714}
1715
Colin Cross81413472016-04-11 14:37:39 -07001716func (object *objectLinker) props() []interface{} {
1717 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001718}
1719
Colin Crossca860ac2016-01-04 14:34:37 -08001720func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001721
Colin Cross81413472016-04-11 14:37:39 -07001722func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1723 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001724 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001725}
1726
Colin Crossca860ac2016-01-04 14:34:37 -08001727func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001728 if flags.Clang {
1729 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1730 } else {
1731 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1732 }
1733
Colin Crossca860ac2016-01-04 14:34:37 -08001734 return flags
1735}
1736
1737func (object *objectLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001738 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001739
Colin Cross97ba0732015-03-23 17:50:24 -07001740 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001741
Colin Cross635c3b02016-05-18 15:37:25 -07001742 var outputFile android.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001743 if len(objFiles) == 1 {
1744 outputFile = objFiles[0]
1745 } else {
Colin Cross635c3b02016-05-18 15:37:25 -07001746 output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001747 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001748 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001749 }
1750
Colin Cross3f40fa42015-01-30 17:27:36 -08001751 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001752 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001753}
1754
Colin Crossc99deeb2016-04-11 15:06:20 -07001755func (*objectLinker) installable() bool {
1756 return false
1757}
1758
Colin Cross3f40fa42015-01-30 17:27:36 -08001759//
1760// Executables
1761//
1762
Colin Crossca860ac2016-01-04 14:34:37 -08001763type binaryLinker struct {
1764 baseLinker
Colin Cross665dce92016-04-28 14:50:03 -07001765 stripper
Colin Cross7d5136f2015-05-11 13:39:40 -07001766
Colin Crossca860ac2016-01-04 14:34:37 -08001767 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001768
Colin Cross635c3b02016-05-18 15:37:25 -07001769 hostToolPath android.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001770}
1771
Colin Crossca860ac2016-01-04 14:34:37 -08001772var _ linker = (*binaryLinker)(nil)
1773
1774func (binary *binaryLinker) props() []interface{} {
Colin Cross665dce92016-04-28 14:50:03 -07001775 return append(binary.baseLinker.props(),
1776 &binary.Properties,
1777 &binary.stripper.StripProperties)
1778
Colin Cross3f40fa42015-01-30 17:27:36 -08001779}
1780
Colin Crossca860ac2016-01-04 14:34:37 -08001781func (binary *binaryLinker) buildStatic() bool {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001782 return binary.baseLinker.staticBinary()
Colin Crossed4cf0b2015-03-26 14:43:45 -07001783}
1784
Colin Crossca860ac2016-01-04 14:34:37 -08001785func (binary *binaryLinker) buildShared() bool {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001786 return !binary.baseLinker.staticBinary()
Colin Crossed4cf0b2015-03-26 14:43:45 -07001787}
1788
Colin Crossca860ac2016-01-04 14:34:37 -08001789func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001790 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001791 if binary.Properties.Stem != "" {
1792 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001793 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001794
Colin Crossca860ac2016-01-04 14:34:37 -08001795 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001796}
1797
Colin Crossca860ac2016-01-04 14:34:37 -08001798func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1799 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001800 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001801 if !ctx.sdk() {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001802 if binary.buildStatic() {
Colin Crossca860ac2016-01-04 14:34:37 -08001803 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001804 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001805 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001806 }
Colin Crossca860ac2016-01-04 14:34:37 -08001807 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001808 } else {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001809 if binary.buildStatic() {
Colin Crossca860ac2016-01-04 14:34:37 -08001810 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001811 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001812 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001813 }
Colin Crossca860ac2016-01-04 14:34:37 -08001814 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001815 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001816
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001817 if binary.buildStatic() {
Colin Crossca860ac2016-01-04 14:34:37 -08001818 if inList("libc++_static", deps.StaticLibs) {
1819 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001820 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001821 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1822 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1823 // move them to the beginning of deps.LateStaticLibs
1824 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001825 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001826 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001827 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001828 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001829 }
Colin Crossca860ac2016-01-04 14:34:37 -08001830
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001831 if binary.buildShared() && inList("libc", deps.StaticLibs) {
Colin Crossca860ac2016-01-04 14:34:37 -08001832 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1833 "from static libs or set static_executable: true")
1834 }
1835 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001836}
1837
Colin Crossc99deeb2016-04-11 15:06:20 -07001838func (*binaryLinker) installable() bool {
1839 return true
1840}
1841
Colin Cross16b23492016-01-06 14:41:07 -08001842func (binary *binaryLinker) isDependencyRoot() bool {
1843 return true
1844}
1845
Colin Cross635c3b02016-05-18 15:37:25 -07001846func NewBinary(hod android.HostOrDeviceSupported) *Module {
1847 module := newModule(hod, android.MultilibFirst)
Colin Crossca860ac2016-01-04 14:34:37 -08001848 module.compiler = &baseCompiler{}
1849 module.linker = &binaryLinker{}
1850 module.installer = &baseInstaller{
1851 dir: "bin",
1852 }
1853 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001854}
1855
Colin Crossca860ac2016-01-04 14:34:37 -08001856func binaryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001857 module := NewBinary(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08001858 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001859}
1860
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001861func (binary *binaryLinker) begin(ctx BaseModuleContext) {
1862 binary.baseLinker.begin(ctx)
1863
1864 static := Bool(binary.Properties.Static_executable)
1865 if ctx.Host() {
Colin Cross635c3b02016-05-18 15:37:25 -07001866 if ctx.HostType() == android.Linux {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001867 if binary.Properties.Static_executable == nil && Bool(ctx.AConfig().ProductVariables.HostStaticBinaries) {
1868 static = true
1869 }
1870 } else {
1871 // Static executables are not supported on Darwin or Windows
1872 static = false
1873 }
Colin Cross0af4b842015-04-30 16:36:18 -07001874 }
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001875 if static {
1876 binary.dynamicProperties.VariantIsStatic = true
Colin Crossca860ac2016-01-04 14:34:37 -08001877 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001878 }
1879}
1880
Colin Crossca860ac2016-01-04 14:34:37 -08001881func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1882 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001883
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001884 if ctx.Host() && !binary.staticBinary() {
Dan Willemsen490fd492015-11-24 17:53:15 -08001885 flags.LdFlags = append(flags.LdFlags, "-pie")
Colin Cross635c3b02016-05-18 15:37:25 -07001886 if ctx.HostType() == android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08001887 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1888 }
1889 }
1890
1891 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1892 // all code is position independent, and then those warnings get promoted to
1893 // errors.
Colin Cross635c3b02016-05-18 15:37:25 -07001894 if ctx.HostType() != android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08001895 flags.CFlags = append(flags.CFlags, "-fpie")
1896 }
Colin Cross97ba0732015-03-23 17:50:24 -07001897
Colin Crossf6566ed2015-03-24 11:13:38 -07001898 if ctx.Device() {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001899 if binary.buildStatic() {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001900 // Clang driver needs -static to create static executable.
1901 // However, bionic/linker uses -shared to overwrite.
1902 // Linker for x86 targets does not allow coexistance of -static and -shared,
1903 // so we add -static only if -shared is not used.
1904 if !inList("-shared", flags.LdFlags) {
1905 flags.LdFlags = append(flags.LdFlags, "-static")
1906 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001907
Colin Crossed4cf0b2015-03-26 14:43:45 -07001908 flags.LdFlags = append(flags.LdFlags,
1909 "-nostdlib",
1910 "-Bstatic",
1911 "-Wl,--gc-sections",
1912 )
1913
1914 } else {
Colin Cross16b23492016-01-06 14:41:07 -08001915 if flags.DynamicLinker == "" {
1916 flags.DynamicLinker = "/system/bin/linker"
1917 if flags.Toolchain.Is64Bit() {
1918 flags.DynamicLinker += "64"
1919 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001920 }
1921
1922 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001923 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001924 "-nostdlib",
1925 "-Bdynamic",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001926 "-Wl,--gc-sections",
1927 "-Wl,-z,nocopyreloc",
1928 )
1929 }
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001930 } else {
1931 if binary.staticBinary() {
1932 flags.LdFlags = append(flags.LdFlags, "-static")
1933 }
1934 if ctx.Darwin() {
1935 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
1936 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001937 }
1938
Colin Cross97ba0732015-03-23 17:50:24 -07001939 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001940}
1941
Colin Crossca860ac2016-01-04 14:34:37 -08001942func (binary *binaryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001943 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001944
Colin Cross665dce92016-04-28 14:50:03 -07001945 fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
Colin Cross635c3b02016-05-18 15:37:25 -07001946 outputFile := android.PathForModuleOut(ctx, fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001947 ret := outputFile
Colin Crossca860ac2016-01-04 14:34:37 -08001948 if ctx.HostOrDevice().Host() {
Colin Cross635c3b02016-05-18 15:37:25 -07001949 binary.hostToolPath = android.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001950 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001951
Colin Cross635c3b02016-05-18 15:37:25 -07001952 var linkerDeps android.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001953
Colin Crossca860ac2016-01-04 14:34:37 -08001954 sharedLibs := deps.SharedLibs
1955 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1956
Colin Cross16b23492016-01-06 14:41:07 -08001957 if flags.DynamicLinker != "" {
1958 flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
1959 }
1960
Colin Cross665dce92016-04-28 14:50:03 -07001961 builderFlags := flagsToBuilderFlags(flags)
1962
1963 if binary.stripper.needsStrip(ctx) {
1964 strippedOutputFile := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07001965 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001966 binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
1967 }
1968
1969 if binary.Properties.Prefix_symbols != "" {
1970 afterPrefixSymbols := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07001971 outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001972 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1973 flagsToBuilderFlags(flags), afterPrefixSymbols)
1974 }
1975
Colin Crossca860ac2016-01-04 14:34:37 -08001976 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001977 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Cross665dce92016-04-28 14:50:03 -07001978 builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001979
1980 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001981}
Colin Cross3f40fa42015-01-30 17:27:36 -08001982
Colin Cross635c3b02016-05-18 15:37:25 -07001983func (binary *binaryLinker) HostToolPath() android.OptionalPath {
Colin Crossca860ac2016-01-04 14:34:37 -08001984 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001985}
1986
Colin Cross665dce92016-04-28 14:50:03 -07001987type stripper struct {
1988 StripProperties StripProperties
1989}
1990
1991func (stripper *stripper) needsStrip(ctx ModuleContext) bool {
1992 return !ctx.AConfig().EmbeddedInMake() && !stripper.StripProperties.Strip.None
1993}
1994
Colin Cross635c3b02016-05-18 15:37:25 -07001995func (stripper *stripper) strip(ctx ModuleContext, in, out android.ModuleOutPath,
Colin Cross665dce92016-04-28 14:50:03 -07001996 flags builderFlags) {
Colin Crossb8ecdfe2016-05-03 15:10:29 -07001997 if ctx.Darwin() {
1998 TransformDarwinStrip(ctx, in, out)
1999 } else {
2000 flags.stripKeepSymbols = stripper.StripProperties.Strip.Keep_symbols
2001 // TODO(ccross): don't add gnu debuglink for user builds
2002 flags.stripAddGnuDebuglink = true
2003 TransformStrip(ctx, in, out, flags)
2004 }
Colin Cross665dce92016-04-28 14:50:03 -07002005}
2006
Colin Cross635c3b02016-05-18 15:37:25 -07002007func testPerSrcMutator(mctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002008 if m, ok := mctx.Module().(*Module); ok {
2009 if test, ok := m.linker.(*testLinker); ok {
2010 if Bool(test.Properties.Test_per_src) {
2011 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
2012 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2013 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
2014 }
2015 tests := mctx.CreateLocalVariations(testNames...)
2016 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2017 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
2018 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
2019 }
Colin Cross6002e052015-09-16 16:00:08 -07002020 }
2021 }
2022 }
Colin Cross7d5136f2015-05-11 13:39:40 -07002023}
2024
Colin Crossca860ac2016-01-04 14:34:37 -08002025type testLinker struct {
2026 binaryLinker
2027 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002028}
2029
Dan Willemsend30e6102016-03-30 17:35:50 -07002030func (test *testLinker) begin(ctx BaseModuleContext) {
2031 test.binaryLinker.begin(ctx)
2032
2033 runpath := "../../lib"
2034 if ctx.toolchain().Is64Bit() {
2035 runpath += "64"
2036 }
Colin Crossc99deeb2016-04-11 15:06:20 -07002037 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
Dan Willemsend30e6102016-03-30 17:35:50 -07002038}
2039
Colin Crossca860ac2016-01-04 14:34:37 -08002040func (test *testLinker) props() []interface{} {
2041 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07002042}
2043
Colin Crossca860ac2016-01-04 14:34:37 -08002044func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
2045 flags = test.binaryLinker.flags(ctx, flags)
2046
2047 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002048 return flags
2049 }
Dan Albertc403f7c2015-03-18 14:01:18 -07002050
Colin Cross97ba0732015-03-23 17:50:24 -07002051 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07002052 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07002053 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002054
Dan Willemsen4a946832016-05-13 14:13:01 -07002055 switch ctx.HostType() {
Colin Cross635c3b02016-05-18 15:37:25 -07002056 case android.Windows:
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002057 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
Colin Cross635c3b02016-05-18 15:37:25 -07002058 case android.Linux:
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002059 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
2060 flags.LdFlags = append(flags.LdFlags, "-lpthread")
Colin Cross635c3b02016-05-18 15:37:25 -07002061 case android.Darwin:
Dan Willemsen4a946832016-05-13 14:13:01 -07002062 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_MAC")
2063 flags.LdFlags = append(flags.LdFlags, "-lpthread")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002064 }
2065 } else {
2066 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07002067 }
2068
Colin Cross21b9a242015-03-24 14:15:58 -07002069 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07002070}
2071
Colin Crossca860ac2016-01-04 14:34:37 -08002072func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2073 if test.Properties.Gtest {
Dan Willemsen8146b2f2016-03-30 21:00:30 -07002074 if ctx.sdk() && ctx.Device() {
2075 switch ctx.selectedStl() {
2076 case "ndk_libc++_shared", "ndk_libc++_static":
2077 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_libcxx", "libgtest_ndk_libcxx")
2078 case "ndk_libgnustl_static":
2079 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_gnustl", "libgtest_ndk_gnustl")
2080 default:
2081 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk", "libgtest_ndk")
2082 }
2083 } else {
2084 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
2085 }
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002086 }
Colin Crossca860ac2016-01-04 14:34:37 -08002087 deps = test.binaryLinker.deps(ctx, deps)
2088 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07002089}
2090
Colin Crossca860ac2016-01-04 14:34:37 -08002091type testInstaller struct {
2092 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08002093}
2094
Colin Cross635c3b02016-05-18 15:37:25 -07002095func (installer *testInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08002096 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
2097 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
2098 installer.baseInstaller.install(ctx, file)
2099}
2100
Colin Cross635c3b02016-05-18 15:37:25 -07002101func NewTest(hod android.HostOrDeviceSupported) *Module {
2102 module := newModule(hod, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002103 module.compiler = &baseCompiler{}
2104 linker := &testLinker{}
2105 linker.Properties.Gtest = true
2106 module.linker = linker
2107 module.installer = &testInstaller{
2108 baseInstaller: baseInstaller{
2109 dir: "nativetest",
2110 dir64: "nativetest64",
2111 data: true,
2112 },
Dan Albertc403f7c2015-03-18 14:01:18 -07002113 }
Colin Crossca860ac2016-01-04 14:34:37 -08002114 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002115}
2116
Colin Crossca860ac2016-01-04 14:34:37 -08002117func testFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002118 module := NewTest(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002119 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07002120}
2121
Colin Crossca860ac2016-01-04 14:34:37 -08002122type benchmarkLinker struct {
2123 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07002124}
2125
Colin Crossca860ac2016-01-04 14:34:37 -08002126func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2127 deps = benchmark.binaryLinker.deps(ctx, deps)
2128 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
2129 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07002130}
2131
Colin Cross635c3b02016-05-18 15:37:25 -07002132func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
2133 module := newModule(hod, android.MultilibFirst)
Colin Crossca860ac2016-01-04 14:34:37 -08002134 module.compiler = &baseCompiler{}
2135 module.linker = &benchmarkLinker{}
2136 module.installer = &baseInstaller{
2137 dir: "nativetest",
2138 dir64: "nativetest64",
2139 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07002140 }
Colin Crossca860ac2016-01-04 14:34:37 -08002141 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07002142}
2143
Colin Crossca860ac2016-01-04 14:34:37 -08002144func benchmarkFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002145 module := NewBenchmark(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002146 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002147}
2148
Colin Cross3f40fa42015-01-30 17:27:36 -08002149//
2150// Static library
2151//
2152
Colin Crossca860ac2016-01-04 14:34:37 -08002153func libraryStaticFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002154 module := NewLibrary(android.HostAndDeviceSupported, false, true)
Colin Crossca860ac2016-01-04 14:34:37 -08002155 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002156}
2157
2158//
2159// Shared libraries
2160//
2161
Colin Crossca860ac2016-01-04 14:34:37 -08002162func librarySharedFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002163 module := NewLibrary(android.HostAndDeviceSupported, true, false)
Colin Crossca860ac2016-01-04 14:34:37 -08002164 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002165}
2166
2167//
2168// Host static library
2169//
2170
Colin Crossca860ac2016-01-04 14:34:37 -08002171func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002172 module := NewLibrary(android.HostSupported, false, true)
Colin Crossca860ac2016-01-04 14:34:37 -08002173 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002174}
2175
2176//
2177// Host Shared libraries
2178//
2179
Colin Crossca860ac2016-01-04 14:34:37 -08002180func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002181 module := NewLibrary(android.HostSupported, true, false)
Colin Crossca860ac2016-01-04 14:34:37 -08002182 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002183}
2184
2185//
2186// Host Binaries
2187//
2188
Colin Crossca860ac2016-01-04 14:34:37 -08002189func binaryHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002190 module := NewBinary(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002191 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002192}
2193
2194//
Colin Cross1f8f2342015-03-26 16:09:47 -07002195// Host Tests
2196//
2197
Colin Crossca860ac2016-01-04 14:34:37 -08002198func testHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002199 module := NewTest(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002200 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07002201}
2202
2203//
Colin Cross2ba19d92015-05-07 15:44:20 -07002204// Host Benchmarks
2205//
2206
Colin Crossca860ac2016-01-04 14:34:37 -08002207func benchmarkHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002208 module := NewBenchmark(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002209 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002210}
2211
2212//
Colin Crosscfad1192015-11-02 16:43:11 -08002213// Defaults
2214//
Colin Crossca860ac2016-01-04 14:34:37 -08002215type Defaults struct {
Colin Cross635c3b02016-05-18 15:37:25 -07002216 android.ModuleBase
2217 android.DefaultsModule
Colin Crosscfad1192015-11-02 16:43:11 -08002218}
2219
Colin Cross635c3b02016-05-18 15:37:25 -07002220func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002221}
2222
Colin Crossca860ac2016-01-04 14:34:37 -08002223func defaultsFactory() (blueprint.Module, []interface{}) {
2224 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002225
2226 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002227 &BaseProperties{},
2228 &BaseCompilerProperties{},
2229 &BaseLinkerProperties{},
2230 &LibraryCompilerProperties{},
Colin Cross919281a2016-04-05 16:42:05 -07002231 &FlagExporterProperties{},
Colin Crossca860ac2016-01-04 14:34:37 -08002232 &LibraryLinkerProperties{},
2233 &BinaryLinkerProperties{},
2234 &TestLinkerProperties{},
2235 &UnusedProperties{},
2236 &StlProperties{},
Colin Cross16b23492016-01-06 14:41:07 -08002237 &SanitizeProperties{},
Colin Cross665dce92016-04-28 14:50:03 -07002238 &StripProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002239 }
2240
Colin Cross635c3b02016-05-18 15:37:25 -07002241 _, propertyStructs = android.InitAndroidArchModule(module, android.HostAndDeviceDefault,
2242 android.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002243
Colin Cross635c3b02016-05-18 15:37:25 -07002244 return android.InitDefaultsModule(module, module, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002245}
2246
2247//
Colin Cross3f40fa42015-01-30 17:27:36 -08002248// Device libraries shipped with gcc
2249//
2250
Colin Crossca860ac2016-01-04 14:34:37 -08002251type toolchainLibraryLinker struct {
2252 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002253}
2254
Colin Crossca860ac2016-01-04 14:34:37 -08002255var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2256
2257func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002258 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002259 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002260}
2261
Colin Crossca860ac2016-01-04 14:34:37 -08002262func (*toolchainLibraryLinker) buildStatic() bool {
2263 return true
2264}
Colin Cross3f40fa42015-01-30 17:27:36 -08002265
Colin Crossca860ac2016-01-04 14:34:37 -08002266func (*toolchainLibraryLinker) buildShared() bool {
2267 return false
2268}
2269
2270func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002271 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002272 module.compiler = &baseCompiler{}
2273 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002274 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002275 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002276}
2277
Colin Crossca860ac2016-01-04 14:34:37 -08002278func (library *toolchainLibraryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07002279 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002280
2281 libName := ctx.ModuleName() + staticLibraryExtension
Colin Cross635c3b02016-05-18 15:37:25 -07002282 outputFile := android.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002283
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002284 if flags.Clang {
2285 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2286 }
2287
Colin Crossca860ac2016-01-04 14:34:37 -08002288 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002289
2290 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002291
Colin Crossca860ac2016-01-04 14:34:37 -08002292 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002293}
2294
Colin Crossc99deeb2016-04-11 15:06:20 -07002295func (*toolchainLibraryLinker) installable() bool {
2296 return false
2297}
2298
Dan Albertbe961682015-03-18 23:38:50 -07002299// NDK prebuilt libraries.
2300//
2301// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2302// either (with the exception of the shared STLs, which are installed to the app's directory rather
2303// than to the system image).
2304
Colin Cross635c3b02016-05-18 15:37:25 -07002305func getNdkLibDir(ctx android.ModuleContext, toolchain Toolchain, version string) android.SourcePath {
Colin Crossc7fd91a2016-05-17 13:15:15 -07002306 suffix := ""
2307 // Most 64-bit NDK prebuilts store libraries in "lib64", except for arm64 which is not a
2308 // multilib toolchain and stores the libraries in "lib".
Colin Cross635c3b02016-05-18 15:37:25 -07002309 if toolchain.Is64Bit() && ctx.Arch().ArchType != android.Arm64 {
Colin Crossc7fd91a2016-05-17 13:15:15 -07002310 suffix = "64"
2311 }
Colin Cross635c3b02016-05-18 15:37:25 -07002312 return android.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib%s",
Colin Crossc7fd91a2016-05-17 13:15:15 -07002313 version, toolchain.Name(), suffix))
Dan Albertbe961682015-03-18 23:38:50 -07002314}
2315
Colin Cross635c3b02016-05-18 15:37:25 -07002316func ndkPrebuiltModuleToPath(ctx android.ModuleContext, toolchain Toolchain,
2317 ext string, version string) android.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002318
2319 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2320 // We want to translate to just NAME.EXT
2321 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2322 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002323 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002324}
2325
Colin Crossca860ac2016-01-04 14:34:37 -08002326type ndkPrebuiltObjectLinker struct {
2327 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002328}
2329
Colin Crossca860ac2016-01-04 14:34:37 -08002330func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002331 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002332 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002333}
2334
Colin Crossca860ac2016-01-04 14:34:37 -08002335func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002336 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002337 module.linker = &ndkPrebuiltObjectLinker{}
2338 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002339}
2340
Colin Crossca860ac2016-01-04 14:34:37 -08002341func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002342 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002343 // A null build step, but it sets up the output path.
2344 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2345 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2346 }
2347
Colin Crossca860ac2016-01-04 14:34:37 -08002348 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002349}
2350
Colin Crossca860ac2016-01-04 14:34:37 -08002351type ndkPrebuiltLibraryLinker struct {
2352 libraryLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002353}
2354
Colin Crossca860ac2016-01-04 14:34:37 -08002355var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2356var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002357
Colin Crossca860ac2016-01-04 14:34:37 -08002358func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Cross919281a2016-04-05 16:42:05 -07002359 return append(ndk.libraryLinker.props(), &ndk.Properties, &ndk.flagExporter.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002360}
2361
Colin Crossca860ac2016-01-04 14:34:37 -08002362func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002363 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002364 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002365}
2366
Colin Crossca860ac2016-01-04 14:34:37 -08002367func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002368 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002369 linker := &ndkPrebuiltLibraryLinker{}
2370 linker.dynamicProperties.BuildShared = true
2371 module.linker = linker
2372 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002373}
2374
Colin Crossca860ac2016-01-04 14:34:37 -08002375func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002376 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002377 // A null build step, but it sets up the output path.
2378 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2379 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2380 }
2381
Colin Cross919281a2016-04-05 16:42:05 -07002382 ndk.exportIncludes(ctx, "-isystem")
Dan Albertbe961682015-03-18 23:38:50 -07002383
Colin Crossca860ac2016-01-04 14:34:37 -08002384 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2385 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002386}
2387
2388// The NDK STLs are slightly different from the prebuilt system libraries:
2389// * Are not specific to each platform version.
2390// * The libraries are not in a predictable location for each STL.
2391
Colin Crossca860ac2016-01-04 14:34:37 -08002392type ndkPrebuiltStlLinker struct {
2393 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002394}
2395
Colin Crossca860ac2016-01-04 14:34:37 -08002396func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002397 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002398 linker := &ndkPrebuiltStlLinker{}
2399 linker.dynamicProperties.BuildShared = true
2400 module.linker = linker
2401 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002402}
2403
Colin Crossca860ac2016-01-04 14:34:37 -08002404func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002405 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002406 linker := &ndkPrebuiltStlLinker{}
2407 linker.dynamicProperties.BuildStatic = true
2408 module.linker = linker
2409 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002410}
2411
Colin Cross635c3b02016-05-18 15:37:25 -07002412func getNdkStlLibDir(ctx android.ModuleContext, toolchain Toolchain, stl string) android.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002413 gccVersion := toolchain.GccVersion()
2414 var libDir string
2415 switch stl {
2416 case "libstlport":
2417 libDir = "cxx-stl/stlport/libs"
2418 case "libc++":
2419 libDir = "cxx-stl/llvm-libc++/libs"
2420 case "libgnustl":
2421 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2422 }
2423
2424 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002425 ndkSrcRoot := "prebuilts/ndk/current/sources"
Colin Cross635c3b02016-05-18 15:37:25 -07002426 return android.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002427 }
2428
2429 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Colin Cross635c3b02016-05-18 15:37:25 -07002430 return android.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002431}
2432
Colin Crossca860ac2016-01-04 14:34:37 -08002433func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002434 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002435 // A null build step, but it sets up the output path.
2436 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2437 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2438 }
2439
Colin Cross919281a2016-04-05 16:42:05 -07002440 ndk.exportIncludes(ctx, "-I")
Dan Albertbe961682015-03-18 23:38:50 -07002441
2442 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002443 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002444 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002445 libExt = staticLibraryExtension
2446 }
2447
2448 stlName := strings.TrimSuffix(libName, "_shared")
2449 stlName = strings.TrimSuffix(stlName, "_static")
2450 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002451 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002452}
2453
Colin Cross635c3b02016-05-18 15:37:25 -07002454func linkageMutator(mctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002455 if m, ok := mctx.Module().(*Module); ok {
2456 if m.linker != nil {
2457 if linker, ok := m.linker.(baseLinkerInterface); ok {
2458 var modules []blueprint.Module
2459 if linker.buildStatic() && linker.buildShared() {
2460 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002461 static := modules[0].(*Module)
2462 shared := modules[1].(*Module)
2463
2464 static.linker.(baseLinkerInterface).setStatic(true)
2465 shared.linker.(baseLinkerInterface).setStatic(false)
2466
2467 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2468 sharedCompiler := shared.compiler.(*libraryCompiler)
2469 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2470 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2471 // Optimize out compiling common .o files twice for static+shared libraries
2472 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2473 sharedCompiler.baseCompiler.Properties.Srcs = nil
2474 }
2475 }
Colin Crossca860ac2016-01-04 14:34:37 -08002476 } else if linker.buildStatic() {
2477 modules = mctx.CreateLocalVariations("static")
2478 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2479 } else if linker.buildShared() {
2480 modules = mctx.CreateLocalVariations("shared")
2481 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2482 } else {
2483 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2484 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002485 }
2486 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002487 }
2488}
Colin Cross74d1ec02015-04-28 13:30:13 -07002489
2490// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2491// modifies the slice contents in place, and returns a subslice of the original slice
2492func lastUniqueElements(list []string) []string {
2493 totalSkip := 0
2494 for i := len(list) - 1; i >= totalSkip; i-- {
2495 skip := 0
2496 for j := i - 1; j >= totalSkip; j-- {
2497 if list[i] == list[j] {
2498 skip++
2499 } else {
2500 list[j+skip] = list[j]
2501 }
2502 }
2503 totalSkip += skip
2504 }
2505 return list[totalSkip:]
2506}
Colin Cross06a931b2015-10-28 17:23:31 -07002507
2508var Bool = proptools.Bool