blob: 3cc0d0da27cb9bbb748c71d0ad65dd737d58fa46 [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 Cross54c71122016-06-01 17:09:44 -0700121 if android.BuildOs == 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
272 // list of directories relative to the Blueprints file that will
273 // be added to the include path using -I
274 Local_include_dirs []string `android:"arch_variant"`
275
Dan Willemsenb40aab62016-04-20 14:21:14 -0700276 // list of generated sources to compile. These are the names of gensrcs or
277 // genrule modules.
278 Generated_sources []string `android:"arch_variant"`
279
280 // list of generated headers to add to the include path. These are the names
281 // of genrule modules.
282 Generated_headers []string `android:"arch_variant"`
283
Colin Crossca860ac2016-01-04 14:34:37 -0800284 // pass -frtti instead of -fno-rtti
285 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700286
Colin Crossca860ac2016-01-04 14:34:37 -0800287 Debug, Release struct {
288 // list of module-specific flags that will be used for C and C++ compiles in debug or
289 // release builds
290 Cflags []string `android:"arch_variant"`
291 } `android:"arch_variant"`
292}
Colin Cross7d5136f2015-05-11 13:39:40 -0700293
Colin Crossca860ac2016-01-04 14:34:37 -0800294type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700295 // list of modules whose object files should be linked into this module
296 // in their entirety. For static library modules, all of the .o files from the intermediate
297 // directory of the dependency will be linked into this modules .a file. For a shared library,
298 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
Colin Cross6ee75b62016-05-05 15:57:15 -0700299 Whole_static_libs []string `android:"arch_variant,variant_prepend"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700300
301 // list of modules that should be statically linked into this module.
Colin Cross6ee75b62016-05-05 15:57:15 -0700302 Static_libs []string `android:"arch_variant,variant_prepend"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700303
304 // list of modules that should be dynamically linked into this module.
305 Shared_libs []string `android:"arch_variant"`
306
Colin Crossca860ac2016-01-04 14:34:37 -0800307 // list of module-specific flags that will be used for all link steps
308 Ldflags []string `android:"arch_variant"`
309
310 // don't insert default compiler flags into asflags, cflags,
311 // cppflags, conlyflags, ldflags, or include_dirs
312 No_default_compiler_flags *bool
313
314 // list of system libraries that will be dynamically linked to
315 // shared library and executable modules. If unset, generally defaults to libc
316 // and libm. Set to [] to prevent linking against libc and libm.
317 System_shared_libs []string
318
Colin Cross7d5136f2015-05-11 13:39:40 -0700319 // allow the module to contain undefined symbols. By default,
320 // modules cannot contain undefined symbols that are not satisified by their immediate
321 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
322 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700323 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700324
Dan Willemsend67be222015-09-16 15:19:33 -0700325 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700326 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700327
Colin Cross7d5136f2015-05-11 13:39:40 -0700328 // -l arguments to pass to linker for host-provided shared libraries
329 Host_ldlibs []string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800330}
Colin Cross7d5136f2015-05-11 13:39:40 -0700331
Colin Crossca860ac2016-01-04 14:34:37 -0800332type LibraryCompilerProperties struct {
333 Static struct {
334 Srcs []string `android:"arch_variant"`
335 Exclude_srcs []string `android:"arch_variant"`
336 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700337 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800338 Shared struct {
339 Srcs []string `android:"arch_variant"`
340 Exclude_srcs []string `android:"arch_variant"`
341 Cflags []string `android:"arch_variant"`
342 } `android:"arch_variant"`
343}
344
Colin Cross919281a2016-04-05 16:42:05 -0700345type FlagExporterProperties struct {
346 // list of directories relative to the Blueprints file that will
347 // be added to the include path using -I for any module that links against this module
348 Export_include_dirs []string `android:"arch_variant"`
349}
350
Colin Crossca860ac2016-01-04 14:34:37 -0800351type LibraryLinkerProperties struct {
352 Static struct {
353 Whole_static_libs []string `android:"arch_variant"`
354 Static_libs []string `android:"arch_variant"`
355 Shared_libs []string `android:"arch_variant"`
356 } `android:"arch_variant"`
357 Shared struct {
358 Whole_static_libs []string `android:"arch_variant"`
359 Static_libs []string `android:"arch_variant"`
360 Shared_libs []string `android:"arch_variant"`
361 } `android:"arch_variant"`
362
363 // local file name to pass to the linker as --version_script
364 Version_script *string `android:"arch_variant"`
365 // local file name to pass to the linker as -unexported_symbols_list
366 Unexported_symbols_list *string `android:"arch_variant"`
367 // local file name to pass to the linker as -force_symbols_not_weak_list
368 Force_symbols_not_weak_list *string `android:"arch_variant"`
369 // local file name to pass to the linker as -force_symbols_weak_list
370 Force_symbols_weak_list *string `android:"arch_variant"`
371
Colin Crossca860ac2016-01-04 14:34:37 -0800372 // don't link in crt_begin and crt_end. This flag should only be necessary for
373 // compiling crt or libc.
374 Nocrt *bool `android:"arch_variant"`
Colin Cross16b23492016-01-06 14:41:07 -0800375
376 VariantName string `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800377}
378
379type BinaryLinkerProperties struct {
380 // compile executable with -static
381 Static_executable *bool
382
383 // set the name of the output
384 Stem string `android:"arch_variant"`
385
386 // append to the name of the output
387 Suffix string `android:"arch_variant"`
388
389 // if set, add an extra objcopy --prefix-symbols= step
390 Prefix_symbols string
391}
392
393type TestLinkerProperties struct {
394 // if set, build against the gtest library. Defaults to true.
395 Gtest bool
396
397 // Create a separate binary for each source file. Useful when there is
398 // global state that can not be torn down and reset between each test suite.
399 Test_per_src *bool
400}
401
Colin Cross81413472016-04-11 14:37:39 -0700402type ObjectLinkerProperties struct {
403 // names of other cc_object modules to link into this module using partial linking
404 Objs []string `android:"arch_variant"`
405}
406
Colin Crossca860ac2016-01-04 14:34:37 -0800407// Properties used to compile all C or C++ modules
408type BaseProperties struct {
409 // compile module with clang instead of gcc
410 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700411
412 // Minimum sdk version supported when compiling against the ndk
413 Sdk_version string
414
Colin Crossca860ac2016-01-04 14:34:37 -0800415 // don't insert default compiler flags into asflags, cflags,
416 // cppflags, conlyflags, ldflags, or include_dirs
417 No_default_compiler_flags *bool
Colin Crossc99deeb2016-04-11 15:06:20 -0700418
419 AndroidMkSharedLibs []string `blueprint:"mutated"`
Colin Crossbc6fb162016-05-24 15:39:04 -0700420 HideFromMake bool `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800421}
422
423type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700424 // install to a subdirectory of the default install path for the module
425 Relative_install_path string
426}
427
Colin Cross665dce92016-04-28 14:50:03 -0700428type StripProperties struct {
429 Strip struct {
430 None bool
431 Keep_symbols bool
432 }
433}
434
Colin Crossca860ac2016-01-04 14:34:37 -0800435type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700436 Native_coverage *bool
437 Required []string
Colin Cross21b481b2016-04-15 16:27:17 -0700438 Tags []string
Colin Crosscfad1192015-11-02 16:43:11 -0800439}
440
Colin Crossca860ac2016-01-04 14:34:37 -0800441type ModuleContextIntf interface {
442 module() *Module
443 static() bool
444 staticBinary() bool
445 clang() bool
446 toolchain() Toolchain
447 noDefaultCompilerFlags() bool
448 sdk() bool
449 sdkVersion() string
Dan Willemsen8146b2f2016-03-30 21:00:30 -0700450 selectedStl() string
Colin Crossca860ac2016-01-04 14:34:37 -0800451}
452
453type ModuleContext interface {
Colin Cross635c3b02016-05-18 15:37:25 -0700454 android.ModuleContext
Colin Crossca860ac2016-01-04 14:34:37 -0800455 ModuleContextIntf
456}
457
458type BaseModuleContext interface {
Colin Cross635c3b02016-05-18 15:37:25 -0700459 android.BaseContext
Colin Crossca860ac2016-01-04 14:34:37 -0800460 ModuleContextIntf
461}
462
463type Customizer interface {
464 CustomizeProperties(BaseModuleContext)
465 Properties() []interface{}
466}
467
468type feature interface {
469 begin(ctx BaseModuleContext)
470 deps(ctx BaseModuleContext, deps Deps) Deps
471 flags(ctx ModuleContext, flags Flags) Flags
472 props() []interface{}
473}
474
475type compiler interface {
476 feature
Colin Cross635c3b02016-05-18 15:37:25 -0700477 compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800478}
479
480type linker interface {
481 feature
Colin Cross635c3b02016-05-18 15:37:25 -0700482 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles android.Paths) android.Path
Colin Crossc99deeb2016-04-11 15:06:20 -0700483 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800484}
485
486type installer interface {
487 props() []interface{}
Colin Cross635c3b02016-05-18 15:37:25 -0700488 install(ctx ModuleContext, path android.Path)
Colin Crossca860ac2016-01-04 14:34:37 -0800489 inData() bool
490}
491
Colin Crossc99deeb2016-04-11 15:06:20 -0700492type dependencyTag struct {
493 blueprint.BaseDependencyTag
494 name string
495 library bool
496}
497
498var (
499 sharedDepTag = dependencyTag{name: "shared", library: true}
500 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
501 staticDepTag = dependencyTag{name: "static", library: true}
502 lateStaticDepTag = dependencyTag{name: "late static", library: true}
503 wholeStaticDepTag = dependencyTag{name: "whole static", library: true}
Dan Willemsenb40aab62016-04-20 14:21:14 -0700504 genSourceDepTag = dependencyTag{name: "gen source"}
505 genHeaderDepTag = dependencyTag{name: "gen header"}
Colin Crossc99deeb2016-04-11 15:06:20 -0700506 objDepTag = dependencyTag{name: "obj"}
507 crtBeginDepTag = dependencyTag{name: "crtbegin"}
508 crtEndDepTag = dependencyTag{name: "crtend"}
509 reuseObjTag = dependencyTag{name: "reuse objects"}
510)
511
Colin Crossca860ac2016-01-04 14:34:37 -0800512// Module contains the properties and members used by all C/C++ module types, and implements
513// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
514// to construct the output file. Behavior can be customized with a Customizer interface
515type Module struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700516 android.ModuleBase
517 android.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700518
Colin Crossca860ac2016-01-04 14:34:37 -0800519 Properties BaseProperties
520 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700521
Colin Crossca860ac2016-01-04 14:34:37 -0800522 // initialize before calling Init
Colin Cross635c3b02016-05-18 15:37:25 -0700523 hod android.HostOrDeviceSupported
524 multilib android.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700525
Colin Crossca860ac2016-01-04 14:34:37 -0800526 // delegates, initialize before calling Init
527 customizer Customizer
528 features []feature
529 compiler compiler
530 linker linker
531 installer installer
Colin Crossa8e07cc2016-04-04 15:07:06 -0700532 stl *stl
Colin Cross16b23492016-01-06 14:41:07 -0800533 sanitize *sanitize
534
535 androidMkSharedLibDeps []string
Colin Cross74d1ec02015-04-28 13:30:13 -0700536
Colin Cross635c3b02016-05-18 15:37:25 -0700537 outputFile android.OptionalPath
Colin Crossca860ac2016-01-04 14:34:37 -0800538
539 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700540}
541
Colin Crossca860ac2016-01-04 14:34:37 -0800542func (c *Module) Init() (blueprint.Module, []interface{}) {
543 props := []interface{}{&c.Properties, &c.unused}
544 if c.customizer != nil {
545 props = append(props, c.customizer.Properties()...)
546 }
547 if c.compiler != nil {
548 props = append(props, c.compiler.props()...)
549 }
550 if c.linker != nil {
551 props = append(props, c.linker.props()...)
552 }
553 if c.installer != nil {
554 props = append(props, c.installer.props()...)
555 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700556 if c.stl != nil {
557 props = append(props, c.stl.props()...)
558 }
Colin Cross16b23492016-01-06 14:41:07 -0800559 if c.sanitize != nil {
560 props = append(props, c.sanitize.props()...)
561 }
Colin Crossca860ac2016-01-04 14:34:37 -0800562 for _, feature := range c.features {
563 props = append(props, feature.props()...)
564 }
Colin Crossc472d572015-03-17 15:06:21 -0700565
Colin Cross635c3b02016-05-18 15:37:25 -0700566 _, props = android.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700567
Colin Cross635c3b02016-05-18 15:37:25 -0700568 return android.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700569}
570
Colin Crossca860ac2016-01-04 14:34:37 -0800571type baseModuleContext struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700572 android.BaseContext
Colin Crossca860ac2016-01-04 14:34:37 -0800573 moduleContextImpl
574}
575
576type moduleContext struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700577 android.ModuleContext
Colin Crossca860ac2016-01-04 14:34:37 -0800578 moduleContextImpl
579}
580
581type moduleContextImpl struct {
582 mod *Module
583 ctx BaseModuleContext
584}
585
586func (ctx *moduleContextImpl) module() *Module {
587 return ctx.mod
588}
589
590func (ctx *moduleContextImpl) clang() bool {
591 return ctx.mod.clang(ctx.ctx)
592}
593
594func (ctx *moduleContextImpl) toolchain() Toolchain {
595 return ctx.mod.toolchain(ctx.ctx)
596}
597
598func (ctx *moduleContextImpl) static() bool {
599 if ctx.mod.linker == nil {
600 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
601 }
602 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
603 return linker.static()
604 } else {
605 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
606 }
607}
608
609func (ctx *moduleContextImpl) staticBinary() bool {
610 if ctx.mod.linker == nil {
611 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
612 }
613 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
614 return linker.staticBinary()
615 } else {
616 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
617 }
618}
619
620func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
621 return Bool(ctx.mod.Properties.No_default_compiler_flags)
622}
623
624func (ctx *moduleContextImpl) sdk() bool {
625 return ctx.mod.Properties.Sdk_version != ""
626}
627
628func (ctx *moduleContextImpl) sdkVersion() string {
629 return ctx.mod.Properties.Sdk_version
630}
631
Dan Willemsen8146b2f2016-03-30 21:00:30 -0700632func (ctx *moduleContextImpl) selectedStl() string {
633 if stl := ctx.mod.stl; stl != nil {
634 return stl.Properties.SelectedStl
635 }
636 return ""
637}
638
Colin Cross635c3b02016-05-18 15:37:25 -0700639func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
Colin Crossca860ac2016-01-04 14:34:37 -0800640 return &Module{
641 hod: hod,
642 multilib: multilib,
643 }
644}
645
Colin Cross635c3b02016-05-18 15:37:25 -0700646func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
Colin Crossca860ac2016-01-04 14:34:37 -0800647 module := newBaseModule(hod, multilib)
Colin Crossa8e07cc2016-04-04 15:07:06 -0700648 module.stl = &stl{}
Colin Cross16b23492016-01-06 14:41:07 -0800649 module.sanitize = &sanitize{}
Colin Crossca860ac2016-01-04 14:34:37 -0800650 return module
651}
652
Colin Cross635c3b02016-05-18 15:37:25 -0700653func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800654 ctx := &moduleContext{
Colin Cross635c3b02016-05-18 15:37:25 -0700655 ModuleContext: actx,
Colin Crossca860ac2016-01-04 14:34:37 -0800656 moduleContextImpl: moduleContextImpl{
657 mod: c,
658 },
659 }
660 ctx.ctx = ctx
661
662 flags := Flags{
663 Toolchain: c.toolchain(ctx),
664 Clang: c.clang(ctx),
665 }
Colin Crossca860ac2016-01-04 14:34:37 -0800666 if c.compiler != nil {
667 flags = c.compiler.flags(ctx, flags)
668 }
669 if c.linker != nil {
670 flags = c.linker.flags(ctx, flags)
671 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700672 if c.stl != nil {
673 flags = c.stl.flags(ctx, flags)
674 }
Colin Cross16b23492016-01-06 14:41:07 -0800675 if c.sanitize != nil {
676 flags = c.sanitize.flags(ctx, flags)
677 }
Colin Crossca860ac2016-01-04 14:34:37 -0800678 for _, feature := range c.features {
679 flags = feature.flags(ctx, flags)
680 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800681 if ctx.Failed() {
682 return
683 }
684
Colin Crossca860ac2016-01-04 14:34:37 -0800685 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
686 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
687 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800688
Colin Crossca860ac2016-01-04 14:34:37 -0800689 // Optimization to reduce size of build.ninja
690 // Replace the long list of flags for each file with a module-local variable
691 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
692 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
693 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
694 flags.CFlags = []string{"$cflags"}
695 flags.CppFlags = []string{"$cppflags"}
696 flags.AsFlags = []string{"$asflags"}
697
Colin Crossc99deeb2016-04-11 15:06:20 -0700698 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800699 if ctx.Failed() {
700 return
701 }
702
Colin Cross28344522015-04-22 13:07:53 -0700703 flags.CFlags = append(flags.CFlags, deps.Cflags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700704
Colin Cross635c3b02016-05-18 15:37:25 -0700705 var objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800706 if c.compiler != nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700707 objFiles = c.compiler.compile(ctx, flags, deps)
Colin Crossca860ac2016-01-04 14:34:37 -0800708 if ctx.Failed() {
709 return
710 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800711 }
712
Colin Crossca860ac2016-01-04 14:34:37 -0800713 if c.linker != nil {
714 outputFile := c.linker.link(ctx, flags, deps, objFiles)
715 if ctx.Failed() {
716 return
717 }
Colin Cross635c3b02016-05-18 15:37:25 -0700718 c.outputFile = android.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700719
Colin Crossc99deeb2016-04-11 15:06:20 -0700720 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800721 c.installer.install(ctx, outputFile)
722 if ctx.Failed() {
723 return
724 }
725 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700726 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800727}
728
Colin Crossca860ac2016-01-04 14:34:37 -0800729func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
730 if c.cachedToolchain == nil {
731 arch := ctx.Arch()
Colin Cross54c71122016-06-01 17:09:44 -0700732 os := ctx.Os()
733 factory := toolchainFactories[os][arch.ArchType]
Colin Crossca860ac2016-01-04 14:34:37 -0800734 if factory == nil {
Colin Cross54c71122016-06-01 17:09:44 -0700735 ctx.ModuleErrorf("Toolchain not found for %s arch %q", os.String(), arch.String())
Colin Crossca860ac2016-01-04 14:34:37 -0800736 return nil
737 }
738 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800739 }
Colin Crossca860ac2016-01-04 14:34:37 -0800740 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800741}
742
Colin Crossca860ac2016-01-04 14:34:37 -0800743func (c *Module) begin(ctx BaseModuleContext) {
744 if c.compiler != nil {
745 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700746 }
Colin Crossca860ac2016-01-04 14:34:37 -0800747 if c.linker != nil {
748 c.linker.begin(ctx)
749 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700750 if c.stl != nil {
751 c.stl.begin(ctx)
752 }
Colin Cross16b23492016-01-06 14:41:07 -0800753 if c.sanitize != nil {
754 c.sanitize.begin(ctx)
755 }
Colin Crossca860ac2016-01-04 14:34:37 -0800756 for _, feature := range c.features {
757 feature.begin(ctx)
758 }
759}
760
Colin Crossc99deeb2016-04-11 15:06:20 -0700761func (c *Module) deps(ctx BaseModuleContext) Deps {
762 deps := Deps{}
763
764 if c.compiler != nil {
765 deps = c.compiler.deps(ctx, deps)
766 }
767 if c.linker != nil {
768 deps = c.linker.deps(ctx, deps)
769 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700770 if c.stl != nil {
771 deps = c.stl.deps(ctx, deps)
772 }
Colin Cross16b23492016-01-06 14:41:07 -0800773 if c.sanitize != nil {
774 deps = c.sanitize.deps(ctx, deps)
775 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700776 for _, feature := range c.features {
777 deps = feature.deps(ctx, deps)
778 }
779
780 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
781 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
782 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
783 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
784 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
785
786 return deps
787}
788
Colin Cross635c3b02016-05-18 15:37:25 -0700789func (c *Module) depsMutator(actx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800790 ctx := &baseModuleContext{
Colin Cross635c3b02016-05-18 15:37:25 -0700791 BaseContext: actx,
Colin Crossca860ac2016-01-04 14:34:37 -0800792 moduleContextImpl: moduleContextImpl{
793 mod: c,
794 },
795 }
796 ctx.ctx = ctx
797
798 if c.customizer != nil {
799 c.customizer.CustomizeProperties(ctx)
800 }
801
802 c.begin(ctx)
803
Colin Crossc99deeb2016-04-11 15:06:20 -0700804 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800805
Colin Crossc99deeb2016-04-11 15:06:20 -0700806 c.Properties.AndroidMkSharedLibs = deps.SharedLibs
807
808 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
809 deps.WholeStaticLibs...)
810
811 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticDepTag,
812 deps.StaticLibs...)
813
814 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
815 deps.LateStaticLibs...)
816
817 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedDepTag,
818 deps.SharedLibs...)
819
820 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
821 deps.LateSharedLibs...)
822
Dan Willemsenb40aab62016-04-20 14:21:14 -0700823 actx.AddDependency(ctx.module(), genSourceDepTag, deps.GeneratedSources...)
824 actx.AddDependency(ctx.module(), genHeaderDepTag, deps.GeneratedHeaders...)
825
Colin Crossc99deeb2016-04-11 15:06:20 -0700826 actx.AddDependency(ctx.module(), objDepTag, deps.ObjFiles...)
827
828 if deps.CrtBegin != "" {
829 actx.AddDependency(ctx.module(), crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800830 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700831 if deps.CrtEnd != "" {
832 actx.AddDependency(ctx.module(), crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700833 }
Colin Cross6362e272015-10-29 15:25:03 -0700834}
Colin Cross21b9a242015-03-24 14:15:58 -0700835
Colin Cross635c3b02016-05-18 15:37:25 -0700836func depsMutator(ctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800837 if c, ok := ctx.Module().(*Module); ok {
Colin Cross6362e272015-10-29 15:25:03 -0700838 c.depsMutator(ctx)
839 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800840}
841
Colin Crossca860ac2016-01-04 14:34:37 -0800842func (c *Module) clang(ctx BaseModuleContext) bool {
843 clang := Bool(c.Properties.Clang)
844
845 if c.Properties.Clang == nil {
846 if ctx.Host() {
847 clang = true
848 }
849
850 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
851 clang = true
852 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800853 }
Colin Cross28344522015-04-22 13:07:53 -0700854
Colin Crossca860ac2016-01-04 14:34:37 -0800855 if !c.toolchain(ctx).ClangSupported() {
856 clang = false
857 }
858
859 return clang
860}
861
Colin Crossc99deeb2016-04-11 15:06:20 -0700862// Convert dependencies to paths. Returns a PathDeps containing paths
Colin Cross635c3b02016-05-18 15:37:25 -0700863func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800864 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800865
Colin Crossc99deeb2016-04-11 15:06:20 -0700866 ctx.VisitDirectDeps(func(m blueprint.Module) {
867 name := ctx.OtherModuleName(m)
868 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800869
Colin Cross635c3b02016-05-18 15:37:25 -0700870 a, _ := m.(android.Module)
Colin Crossc99deeb2016-04-11 15:06:20 -0700871 if a == nil {
872 ctx.ModuleErrorf("module %q not an android module", name)
873 return
Colin Crossca860ac2016-01-04 14:34:37 -0800874 }
Colin Crossca860ac2016-01-04 14:34:37 -0800875
Colin Crossc99deeb2016-04-11 15:06:20 -0700876 c, _ := m.(*Module)
877 if c == nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700878 switch tag {
Colin Cross635c3b02016-05-18 15:37:25 -0700879 case android.DefaultsDepTag:
Dan Willemsenb40aab62016-04-20 14:21:14 -0700880 case genSourceDepTag:
881 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
882 depPaths.GeneratedSources = append(depPaths.GeneratedSources,
883 genRule.GeneratedSourceFiles()...)
884 } else {
885 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
886 }
887 case genHeaderDepTag:
888 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
889 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
890 genRule.GeneratedSourceFiles()...)
891 depPaths.Cflags = append(depPaths.Cflags,
Colin Cross635c3b02016-05-18 15:37:25 -0700892 includeDirsToFlags(android.Paths{genRule.GeneratedHeaderDir()}))
Dan Willemsenb40aab62016-04-20 14:21:14 -0700893 } else {
894 ctx.ModuleErrorf("module %q is not a genrule", name)
895 }
896 default:
Colin Crossc99deeb2016-04-11 15:06:20 -0700897 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -0800898 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700899 return
900 }
901
902 if !a.Enabled() {
903 ctx.ModuleErrorf("depends on disabled module %q", name)
904 return
905 }
906
Colin Cross54c71122016-06-01 17:09:44 -0700907 if a.Target().Os != ctx.Os() {
908 ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), name)
909 return
910 }
911
912 if a.Target().Arch.ArchType != ctx.Arch().ArchType {
913 ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), name)
Colin Crossc99deeb2016-04-11 15:06:20 -0700914 return
915 }
916
917 if !c.outputFile.Valid() {
918 ctx.ModuleErrorf("module %q missing output file", name)
919 return
920 }
921
922 if tag == reuseObjTag {
923 depPaths.ObjFiles = append(depPaths.ObjFiles,
924 c.compiler.(*libraryCompiler).reuseObjFiles...)
925 return
926 }
927
928 var cflags []string
929 if t, _ := tag.(dependencyTag); t.library {
930 if i, ok := c.linker.(exportedFlagsProducer); ok {
931 cflags = i.exportedFlags()
932 depPaths.Cflags = append(depPaths.Cflags, cflags...)
933 }
934 }
935
Colin Cross635c3b02016-05-18 15:37:25 -0700936 var depPtr *android.Paths
Colin Crossc99deeb2016-04-11 15:06:20 -0700937
938 switch tag {
939 case sharedDepTag:
940 depPtr = &depPaths.SharedLibs
941 case lateSharedDepTag:
942 depPtr = &depPaths.LateSharedLibs
943 case staticDepTag:
944 depPtr = &depPaths.StaticLibs
945 case lateStaticDepTag:
946 depPtr = &depPaths.LateStaticLibs
947 case wholeStaticDepTag:
948 depPtr = &depPaths.WholeStaticLibs
949 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, cflags...)
950 staticLib, _ := c.linker.(*libraryLinker)
951 if staticLib == nil || !staticLib.static() {
952 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
953 return
954 }
955
956 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
957 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
958 for i := range missingDeps {
959 missingDeps[i] += postfix
960 }
961 ctx.AddMissingDependencies(missingDeps)
962 }
963 depPaths.WholeStaticLibObjFiles =
964 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...)
965 case objDepTag:
966 depPtr = &depPaths.ObjFiles
967 case crtBeginDepTag:
968 depPaths.CrtBegin = c.outputFile
969 case crtEndDepTag:
970 depPaths.CrtEnd = c.outputFile
971 default:
972 panic(fmt.Errorf("unknown dependency tag: %s", ctx.OtherModuleDependencyTag(m)))
973 }
974
975 if depPtr != nil {
976 *depPtr = append(*depPtr, c.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -0800977 }
978 })
979
980 return depPaths
981}
982
983func (c *Module) InstallInData() bool {
984 if c.installer == nil {
985 return false
986 }
987 return c.installer.inData()
988}
989
990// Compiler
991
992type baseCompiler struct {
993 Properties BaseCompilerProperties
994}
995
996var _ compiler = (*baseCompiler)(nil)
997
998func (compiler *baseCompiler) props() []interface{} {
999 return []interface{}{&compiler.Properties}
1000}
1001
Dan Willemsenb40aab62016-04-20 14:21:14 -07001002func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
1003
1004func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
1005 deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
1006 deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
1007
1008 return deps
1009}
Colin Crossca860ac2016-01-04 14:34:37 -08001010
1011// Create a Flags struct that collects the compile flags from global values,
1012// per-target values, module type values, and per-module Blueprints properties
1013func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1014 toolchain := ctx.toolchain()
1015
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001016 CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
1017 CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
1018 CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
1019 CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
1020
Colin Crossca860ac2016-01-04 14:34:37 -08001021 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
1022 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
1023 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
1024 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
1025 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
1026
Colin Cross28344522015-04-22 13:07:53 -07001027 // Include dir cflags
Colin Cross635c3b02016-05-18 15:37:25 -07001028 rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
1029 localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -07001030 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -07001031 includeDirsToFlags(localIncludeDirs),
1032 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -07001033
Colin Crossca860ac2016-01-04 14:34:37 -08001034 if !ctx.noDefaultCompilerFlags() {
1035 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -07001036 flags.GlobalFlags = append(flags.GlobalFlags,
1037 "${commonGlobalIncludes}",
1038 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -08001039 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -07001040 }
1041
1042 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Colin Cross635c3b02016-05-18 15:37:25 -07001043 "-I" + android.PathForModuleSrc(ctx).String(),
1044 "-I" + android.PathForModuleOut(ctx).String(),
1045 "-I" + android.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -07001046 }...)
1047 }
1048
Colin Crossca860ac2016-01-04 14:34:37 -08001049 instructionSet := compiler.Properties.Instruction_set
1050 if flags.RequiredInstructionSet != "" {
1051 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -08001052 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001053 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
1054 if flags.Clang {
1055 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
1056 }
1057 if err != nil {
1058 ctx.ModuleErrorf("%s", err)
1059 }
1060
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001061 CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags)
1062
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001063 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -08001064 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001065
Colin Cross97ba0732015-03-23 17:50:24 -07001066 if flags.Clang {
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001067 CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
1068 CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
1069
Colin Cross97ba0732015-03-23 17:50:24 -07001070 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001071 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
1072 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -07001073 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
1074 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
1075 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001076
1077 target := "-target " + toolchain.ClangTriple()
Dan Willemsen3772da12016-05-16 18:01:46 -07001078 var gccPrefix string
1079 if !ctx.Darwin() {
1080 gccPrefix = "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
1081 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001082
Colin Cross97ba0732015-03-23 17:50:24 -07001083 flags.CFlags = append(flags.CFlags, target, gccPrefix)
1084 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
1085 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -08001086 }
1087
Colin Cross54c71122016-06-01 17:09:44 -07001088 hod := "host"
1089 if ctx.Os().Class == android.Device {
1090 hod = "device"
1091 }
1092
Colin Crossca860ac2016-01-04 14:34:37 -08001093 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001094 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1095
Colin Cross97ba0732015-03-23 17:50:24 -07001096 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001097 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001098 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001099 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001100 toolchain.ClangCflags(),
1101 "${commonClangGlobalCflags}",
Colin Cross54c71122016-06-01 17:09:44 -07001102 fmt.Sprintf("${%sClangGlobalCflags}", hod))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001103
1104 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001105 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001106 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001107 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001108 toolchain.Cflags(),
1109 "${commonGlobalCflags}",
Colin Cross54c71122016-06-01 17:09:44 -07001110 fmt.Sprintf("${%sGlobalCflags}", hod))
Colin Cross3f40fa42015-01-30 17:27:36 -08001111 }
1112
Colin Cross7b66f152015-12-15 16:07:43 -08001113 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1114 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1115 }
1116
Colin Crossf6566ed2015-03-24 11:13:38 -07001117 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001118 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001119 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001120 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001121 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001122 }
1123 }
1124
Colin Cross97ba0732015-03-23 17:50:24 -07001125 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001126
Colin Cross97ba0732015-03-23 17:50:24 -07001127 if flags.Clang {
1128 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001129 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001130 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001131 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001132 }
1133
Colin Crossc4bde762015-11-23 16:11:30 -08001134 if flags.Clang {
1135 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1136 } else {
1137 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001138 }
1139
Colin Crossca860ac2016-01-04 14:34:37 -08001140 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001141 if ctx.Host() && !flags.Clang {
1142 // The host GCC doesn't support C++14 (and is deprecated, so likely
1143 // never will). Build these modules with C++11.
1144 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1145 } else {
1146 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1147 }
1148 }
1149
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001150 // We can enforce some rules more strictly in the code we own. strict
1151 // indicates if this is code that we can be stricter with. If we have
1152 // rules that we want to apply to *our* code (but maybe can't for
1153 // vendor/device specific things), we could extend this to be a ternary
1154 // value.
1155 strict := true
Colin Cross635c3b02016-05-18 15:37:25 -07001156 if strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "external/") {
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001157 strict = false
1158 }
1159
1160 // Can be used to make some annotations stricter for code we can fix
1161 // (such as when we mark functions as deprecated).
1162 if strict {
1163 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1164 }
1165
Colin Cross3f40fa42015-01-30 17:27:36 -08001166 return flags
1167}
1168
Colin Cross635c3b02016-05-18 15:37:25 -07001169func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001170 // Compile files listed in c.Properties.Srcs into objects
Dan Willemsenb40aab62016-04-20 14:21:14 -07001171 objFiles := compiler.compileObjs(ctx, flags, "",
1172 compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
1173 deps.GeneratedSources, deps.GeneratedHeaders)
1174
Colin Crossca860ac2016-01-04 14:34:37 -08001175 if ctx.Failed() {
1176 return nil
1177 }
1178
Colin Crossca860ac2016-01-04 14:34:37 -08001179 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001180}
1181
1182// Compile a list of source files into objects a specified subdirectory
Colin Cross635c3b02016-05-18 15:37:25 -07001183func (compiler *baseCompiler) compileObjs(ctx android.ModuleContext, flags Flags,
1184 subdir string, srcFiles, excludes []string, extraSrcs, deps android.Paths) android.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001185
Colin Crossca860ac2016-01-04 14:34:37 -08001186 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001187
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001188 inputFiles := ctx.ExpandSources(srcFiles, excludes)
Dan Willemsenb40aab62016-04-20 14:21:14 -07001189 inputFiles = append(inputFiles, extraSrcs...)
1190 srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)
1191
1192 deps = append(deps, gendeps...)
Colin Cross16b23492016-01-06 14:41:07 -08001193 deps = append(deps, flags.CFlagsDeps...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001194
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001195 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001196}
1197
Colin Crossca860ac2016-01-04 14:34:37 -08001198// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1199type baseLinker struct {
1200 Properties BaseLinkerProperties
1201 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001202 VariantIsShared bool `blueprint:"mutated"`
1203 VariantIsStatic bool `blueprint:"mutated"`
1204 VariantIsStaticBinary bool `blueprint:"mutated"`
1205 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001206 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001207}
1208
Dan Willemsend30e6102016-03-30 17:35:50 -07001209func (linker *baseLinker) begin(ctx BaseModuleContext) {
1210 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001211 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001212 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001213 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001214 }
1215}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001216
Colin Crossca860ac2016-01-04 14:34:37 -08001217func (linker *baseLinker) props() []interface{} {
1218 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001219}
1220
Colin Crossca860ac2016-01-04 14:34:37 -08001221func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1222 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1223 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1224 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001225
Colin Cross74d1ec02015-04-28 13:30:13 -07001226 if ctx.ModuleName() != "libcompiler_rt-extras" {
Colin Crossca860ac2016-01-04 14:34:37 -08001227 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001228 }
1229
Colin Crossf6566ed2015-03-24 11:13:38 -07001230 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001231 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001232 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1233 if !Bool(linker.Properties.No_libgcc) {
1234 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001235 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001236
Colin Crossca860ac2016-01-04 14:34:37 -08001237 if !linker.static() {
1238 if linker.Properties.System_shared_libs != nil {
1239 deps.LateSharedLibs = append(deps.LateSharedLibs,
1240 linker.Properties.System_shared_libs...)
1241 } else if !ctx.sdk() {
1242 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1243 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001244 }
Colin Cross577f6e42015-03-27 18:23:34 -07001245
Colin Crossca860ac2016-01-04 14:34:37 -08001246 if ctx.sdk() {
1247 version := ctx.sdkVersion()
1248 deps.SharedLibs = append(deps.SharedLibs,
Colin Cross577f6e42015-03-27 18:23:34 -07001249 "ndk_libc."+version,
1250 "ndk_libm."+version,
1251 )
1252 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001253 }
1254
Colin Crossca860ac2016-01-04 14:34:37 -08001255 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001256}
1257
Colin Crossca860ac2016-01-04 14:34:37 -08001258func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1259 toolchain := ctx.toolchain()
1260
Colin Crossca860ac2016-01-04 14:34:37 -08001261 if !ctx.noDefaultCompilerFlags() {
1262 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1263 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1264 }
1265
1266 if flags.Clang {
1267 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1268 } else {
1269 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1270 }
1271
1272 if ctx.Host() {
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001273 CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)
1274
Colin Crossca860ac2016-01-04 14:34:37 -08001275 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1276 }
1277 }
1278
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001279 CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)
1280
Dan Willemsen00ced762016-05-10 17:31:21 -07001281 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1282
Dan Willemsend30e6102016-03-30 17:35:50 -07001283 if ctx.Host() && !linker.static() {
1284 rpath_prefix := `\$$ORIGIN/`
1285 if ctx.Darwin() {
1286 rpath_prefix = "@loader_path/"
1287 }
1288
Colin Crossc99deeb2016-04-11 15:06:20 -07001289 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001290 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1291 }
1292 }
1293
Dan Willemsene7174922016-03-30 17:33:52 -07001294 if flags.Clang {
1295 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1296 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001297 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1298 }
1299
1300 return flags
1301}
1302
1303func (linker *baseLinker) static() bool {
1304 return linker.dynamicProperties.VariantIsStatic
1305}
1306
1307func (linker *baseLinker) staticBinary() bool {
1308 return linker.dynamicProperties.VariantIsStaticBinary
1309}
1310
1311func (linker *baseLinker) setStatic(static bool) {
1312 linker.dynamicProperties.VariantIsStatic = static
1313}
1314
Colin Cross16b23492016-01-06 14:41:07 -08001315func (linker *baseLinker) isDependencyRoot() bool {
1316 return false
1317}
1318
Colin Crossca860ac2016-01-04 14:34:37 -08001319type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001320 // Returns true if the build options for the module have selected a static or shared build
1321 buildStatic() bool
1322 buildShared() bool
1323
1324 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001325 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001326
Colin Cross18b6dc52015-04-28 13:20:37 -07001327 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001328 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001329
1330 // Returns whether a module is a static binary
1331 staticBinary() bool
Colin Cross16b23492016-01-06 14:41:07 -08001332
1333 // Returns true for dependency roots (binaries)
1334 // TODO(ccross): also handle dlopenable libraries
1335 isDependencyRoot() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001336}
1337
Colin Crossca860ac2016-01-04 14:34:37 -08001338type baseInstaller struct {
1339 Properties InstallerProperties
1340
1341 dir string
1342 dir64 string
1343 data bool
1344
Colin Cross635c3b02016-05-18 15:37:25 -07001345 path android.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001346}
1347
1348var _ installer = (*baseInstaller)(nil)
1349
1350func (installer *baseInstaller) props() []interface{} {
1351 return []interface{}{&installer.Properties}
1352}
1353
Colin Cross635c3b02016-05-18 15:37:25 -07001354func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08001355 subDir := installer.dir
1356 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1357 subDir = installer.dir64
1358 }
Dan Willemsen17f05262016-05-31 16:27:00 -07001359 if !ctx.Host() && !ctx.Arch().Native {
1360 subDir = filepath.Join(subDir, ctx.Arch().ArchType.String())
1361 }
Colin Cross635c3b02016-05-18 15:37:25 -07001362 dir := android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
Colin Crossca860ac2016-01-04 14:34:37 -08001363 installer.path = ctx.InstallFile(dir, file)
1364}
1365
1366func (installer *baseInstaller) inData() bool {
1367 return installer.data
1368}
1369
Colin Cross3f40fa42015-01-30 17:27:36 -08001370//
1371// Combined static+shared libraries
1372//
1373
Colin Cross919281a2016-04-05 16:42:05 -07001374type flagExporter struct {
1375 Properties FlagExporterProperties
1376
1377 flags []string
1378}
1379
1380func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
Colin Cross635c3b02016-05-18 15:37:25 -07001381 includeDirs := android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
1382 f.flags = append(f.flags, android.JoinWithPrefix(includeDirs.Strings(), inc))
Colin Cross919281a2016-04-05 16:42:05 -07001383}
1384
1385func (f *flagExporter) reexportFlags(flags []string) {
1386 f.flags = append(f.flags, flags...)
1387}
1388
1389func (f *flagExporter) exportedFlags() []string {
1390 return f.flags
1391}
1392
1393type exportedFlagsProducer interface {
1394 exportedFlags() []string
1395}
1396
1397var _ exportedFlagsProducer = (*flagExporter)(nil)
1398
Colin Crossca860ac2016-01-04 14:34:37 -08001399type libraryCompiler struct {
1400 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001401
Colin Crossca860ac2016-01-04 14:34:37 -08001402 linker *libraryLinker
1403 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001404
Colin Crossca860ac2016-01-04 14:34:37 -08001405 // For reusing static library objects for shared library
Colin Cross635c3b02016-05-18 15:37:25 -07001406 reuseObjFiles android.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001407}
1408
Colin Crossca860ac2016-01-04 14:34:37 -08001409var _ compiler = (*libraryCompiler)(nil)
1410
1411func (library *libraryCompiler) props() []interface{} {
1412 props := library.baseCompiler.props()
1413 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001414}
1415
Colin Crossca860ac2016-01-04 14:34:37 -08001416func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1417 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001418
Dan Willemsen490fd492015-11-24 17:53:15 -08001419 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1420 // all code is position independent, and then those warnings get promoted to
1421 // errors.
Colin Cross54c71122016-06-01 17:09:44 -07001422 if ctx.Os() != android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08001423 flags.CFlags = append(flags.CFlags, "-fPIC")
1424 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001425
Colin Crossca860ac2016-01-04 14:34:37 -08001426 if library.linker.static() {
1427 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001428 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001429 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001430 }
1431
Colin Crossca860ac2016-01-04 14:34:37 -08001432 return flags
1433}
1434
Colin Cross635c3b02016-05-18 15:37:25 -07001435func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
1436 var objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -08001437
Dan Willemsenb40aab62016-04-20 14:21:14 -07001438 objFiles = library.baseCompiler.compile(ctx, flags, deps)
Colin Crossc99deeb2016-04-11 15:06:20 -07001439 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001440
1441 if library.linker.static() {
Colin Cross635c3b02016-05-18 15:37:25 -07001442 objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceStaticLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001443 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
1444 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001445 } else {
Colin Cross635c3b02016-05-18 15:37:25 -07001446 objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceSharedLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001447 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
1448 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001449 }
1450
1451 return objFiles
1452}
1453
1454type libraryLinker struct {
1455 baseLinker
Colin Cross919281a2016-04-05 16:42:05 -07001456 flagExporter
Colin Cross665dce92016-04-28 14:50:03 -07001457 stripper
Colin Crossca860ac2016-01-04 14:34:37 -08001458
1459 Properties LibraryLinkerProperties
1460
1461 dynamicProperties struct {
1462 BuildStatic bool `blueprint:"mutated"`
1463 BuildShared bool `blueprint:"mutated"`
1464 }
1465
Colin Crossca860ac2016-01-04 14:34:37 -08001466 // If we're used as a whole_static_lib, our missing dependencies need
1467 // to be given
1468 wholeStaticMissingDeps []string
1469
1470 // For whole_static_libs
Colin Cross635c3b02016-05-18 15:37:25 -07001471 objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -08001472}
1473
1474var _ linker = (*libraryLinker)(nil)
Colin Crossca860ac2016-01-04 14:34:37 -08001475
1476func (library *libraryLinker) props() []interface{} {
1477 props := library.baseLinker.props()
Colin Cross919281a2016-04-05 16:42:05 -07001478 return append(props,
1479 &library.Properties,
1480 &library.dynamicProperties,
Colin Cross665dce92016-04-28 14:50:03 -07001481 &library.flagExporter.Properties,
1482 &library.stripper.StripProperties)
Colin Crossca860ac2016-01-04 14:34:37 -08001483}
1484
1485func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1486 flags = library.baseLinker.flags(ctx, flags)
1487
1488 flags.Nocrt = Bool(library.Properties.Nocrt)
1489
1490 if !library.static() {
Colin Cross30d5f512016-05-03 18:02:42 -07001491 libName := ctx.ModuleName() + library.Properties.VariantName
Colin Cross3f40fa42015-01-30 17:27:36 -08001492 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1493 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001494 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001495 sharedFlag = "-shared"
1496 }
Colin Crossf6566ed2015-03-24 11:13:38 -07001497 if ctx.Device() {
Dan Willemsen99db8c32016-03-03 18:05:38 -08001498 flags.LdFlags = append(flags.LdFlags,
1499 "-nostdlib",
1500 "-Wl,--gc-sections",
1501 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001502 }
Colin Cross97ba0732015-03-23 17:50:24 -07001503
Colin Cross0af4b842015-04-30 16:36:18 -07001504 if ctx.Darwin() {
1505 flags.LdFlags = append(flags.LdFlags,
1506 "-dynamiclib",
1507 "-single_module",
1508 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001509 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001510 )
1511 } else {
1512 flags.LdFlags = append(flags.LdFlags,
Colin Cross0af4b842015-04-30 16:36:18 -07001513 sharedFlag,
Dan Willemsen490fd492015-11-24 17:53:15 -08001514 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001515 )
1516 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001517 }
Colin Cross97ba0732015-03-23 17:50:24 -07001518
1519 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001520}
1521
Colin Crossca860ac2016-01-04 14:34:37 -08001522func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1523 deps = library.baseLinker.deps(ctx, deps)
1524 if library.static() {
1525 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1526 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1527 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1528 } else {
1529 if ctx.Device() && !Bool(library.Properties.Nocrt) {
1530 if !ctx.sdk() {
1531 deps.CrtBegin = "crtbegin_so"
1532 deps.CrtEnd = "crtend_so"
1533 } else {
1534 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1535 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1536 }
1537 }
1538 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1539 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1540 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1541 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001542
Colin Crossca860ac2016-01-04 14:34:37 -08001543 return deps
1544}
Colin Cross3f40fa42015-01-30 17:27:36 -08001545
Colin Crossca860ac2016-01-04 14:34:37 -08001546func (library *libraryLinker) linkStatic(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001547 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Crossca860ac2016-01-04 14:34:37 -08001548
Colin Cross635c3b02016-05-18 15:37:25 -07001549 library.objFiles = append(android.Paths{}, deps.WholeStaticLibObjFiles...)
Dan Willemsen025b4802016-05-11 17:25:48 -07001550 library.objFiles = append(library.objFiles, objFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001551
Colin Cross635c3b02016-05-18 15:37:25 -07001552 outputFile := android.PathForModuleOut(ctx,
Colin Cross16b23492016-01-06 14:41:07 -08001553 ctx.ModuleName()+library.Properties.VariantName+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001554
Colin Cross0af4b842015-04-30 16:36:18 -07001555 if ctx.Darwin() {
Dan Willemsen025b4802016-05-11 17:25:48 -07001556 TransformDarwinObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001557 } else {
Dan Willemsen025b4802016-05-11 17:25:48 -07001558 TransformObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001559 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001560
Colin Crossca860ac2016-01-04 14:34:37 -08001561 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001562
1563 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001564
1565 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001566}
1567
Colin Crossca860ac2016-01-04 14:34:37 -08001568func (library *libraryLinker) linkShared(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001569 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001570
Colin Cross635c3b02016-05-18 15:37:25 -07001571 var linkerDeps android.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001572
Colin Cross635c3b02016-05-18 15:37:25 -07001573 versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1574 unexportedSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1575 forceNotWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1576 forceWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001577 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001578 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001579 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001580 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001581 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001582 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001583 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1584 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001585 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001586 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1587 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001588 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001589 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1590 }
1591 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001592 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001593 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1594 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001595 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001596 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001597 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001598 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001599 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001600 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001601 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001602 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001603 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001604 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001605 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001606 }
Colin Crossaee540a2015-07-06 17:48:31 -07001607 }
1608
Colin Cross665dce92016-04-28 14:50:03 -07001609 fileName := ctx.ModuleName() + library.Properties.VariantName + flags.Toolchain.ShlibSuffix()
Colin Cross635c3b02016-05-18 15:37:25 -07001610 outputFile := android.PathForModuleOut(ctx, fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001611 ret := outputFile
1612
1613 builderFlags := flagsToBuilderFlags(flags)
1614
1615 if library.stripper.needsStrip(ctx) {
1616 strippedOutputFile := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07001617 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001618 library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
1619 }
1620
Colin Crossca860ac2016-01-04 14:34:37 -08001621 sharedLibs := deps.SharedLibs
1622 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001623
Colin Crossca860ac2016-01-04 14:34:37 -08001624 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1625 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
Colin Cross665dce92016-04-28 14:50:03 -07001626 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001627
Colin Cross665dce92016-04-28 14:50:03 -07001628 return ret
Colin Cross3f40fa42015-01-30 17:27:36 -08001629}
1630
Colin Crossca860ac2016-01-04 14:34:37 -08001631func (library *libraryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001632 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001633
Colin Crossc99deeb2016-04-11 15:06:20 -07001634 objFiles = append(objFiles, deps.ObjFiles...)
1635
Colin Cross635c3b02016-05-18 15:37:25 -07001636 var out android.Path
Colin Crossca860ac2016-01-04 14:34:37 -08001637 if library.static() {
1638 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001639 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001640 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001641 }
1642
Colin Cross919281a2016-04-05 16:42:05 -07001643 library.exportIncludes(ctx, "-I")
1644 library.reexportFlags(deps.ReexportedCflags)
Colin Crossca860ac2016-01-04 14:34:37 -08001645
1646 return out
1647}
1648
1649func (library *libraryLinker) buildStatic() bool {
1650 return library.dynamicProperties.BuildStatic
1651}
1652
1653func (library *libraryLinker) buildShared() bool {
1654 return library.dynamicProperties.BuildShared
1655}
1656
1657func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1658 return library.wholeStaticMissingDeps
1659}
1660
Colin Crossc99deeb2016-04-11 15:06:20 -07001661func (library *libraryLinker) installable() bool {
1662 return !library.static()
1663}
1664
Colin Crossca860ac2016-01-04 14:34:37 -08001665type libraryInstaller struct {
1666 baseInstaller
1667
Colin Cross30d5f512016-05-03 18:02:42 -07001668 linker *libraryLinker
1669 sanitize *sanitize
Colin Crossca860ac2016-01-04 14:34:37 -08001670}
1671
Colin Cross635c3b02016-05-18 15:37:25 -07001672func (library *libraryInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08001673 if !library.linker.static() {
1674 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001675 }
1676}
1677
Colin Cross30d5f512016-05-03 18:02:42 -07001678func (library *libraryInstaller) inData() bool {
1679 return library.baseInstaller.inData() || library.sanitize.inData()
1680}
1681
Colin Cross635c3b02016-05-18 15:37:25 -07001682func NewLibrary(hod android.HostOrDeviceSupported, shared, static bool) *Module {
1683 module := newModule(hod, android.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001684
Colin Crossca860ac2016-01-04 14:34:37 -08001685 linker := &libraryLinker{}
1686 linker.dynamicProperties.BuildShared = shared
1687 linker.dynamicProperties.BuildStatic = static
1688 module.linker = linker
1689
1690 module.compiler = &libraryCompiler{
1691 linker: linker,
1692 }
1693 module.installer = &libraryInstaller{
1694 baseInstaller: baseInstaller{
1695 dir: "lib",
1696 dir64: "lib64",
1697 },
Colin Cross30d5f512016-05-03 18:02:42 -07001698 linker: linker,
1699 sanitize: module.sanitize,
Dan Albertc403f7c2015-03-18 14:01:18 -07001700 }
1701
Colin Crossca860ac2016-01-04 14:34:37 -08001702 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001703}
1704
Colin Crossca860ac2016-01-04 14:34:37 -08001705func libraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001706 module := NewLibrary(android.HostAndDeviceSupported, true, true)
Colin Crossca860ac2016-01-04 14:34:37 -08001707 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001708}
1709
Colin Cross3f40fa42015-01-30 17:27:36 -08001710//
1711// Objects (for crt*.o)
1712//
1713
Colin Crossca860ac2016-01-04 14:34:37 -08001714type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001715 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001716}
1717
Colin Crossca860ac2016-01-04 14:34:37 -08001718func objectFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001719 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08001720 module.compiler = &baseCompiler{}
1721 module.linker = &objectLinker{}
1722 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001723}
1724
Colin Cross81413472016-04-11 14:37:39 -07001725func (object *objectLinker) props() []interface{} {
1726 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001727}
1728
Colin Crossca860ac2016-01-04 14:34:37 -08001729func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001730
Colin Cross81413472016-04-11 14:37:39 -07001731func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1732 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001733 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001734}
1735
Colin Crossca860ac2016-01-04 14:34:37 -08001736func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001737 if flags.Clang {
1738 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1739 } else {
1740 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1741 }
1742
Colin Crossca860ac2016-01-04 14:34:37 -08001743 return flags
1744}
1745
1746func (object *objectLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001747 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001748
Colin Cross97ba0732015-03-23 17:50:24 -07001749 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001750
Colin Cross635c3b02016-05-18 15:37:25 -07001751 var outputFile android.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001752 if len(objFiles) == 1 {
1753 outputFile = objFiles[0]
1754 } else {
Colin Cross635c3b02016-05-18 15:37:25 -07001755 output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001756 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001757 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001758 }
1759
Colin Cross3f40fa42015-01-30 17:27:36 -08001760 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001761 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001762}
1763
Colin Crossc99deeb2016-04-11 15:06:20 -07001764func (*objectLinker) installable() bool {
1765 return false
1766}
1767
Colin Cross3f40fa42015-01-30 17:27:36 -08001768//
1769// Executables
1770//
1771
Colin Crossca860ac2016-01-04 14:34:37 -08001772type binaryLinker struct {
1773 baseLinker
Colin Cross665dce92016-04-28 14:50:03 -07001774 stripper
Colin Cross7d5136f2015-05-11 13:39:40 -07001775
Colin Crossca860ac2016-01-04 14:34:37 -08001776 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001777
Colin Cross635c3b02016-05-18 15:37:25 -07001778 hostToolPath android.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001779}
1780
Colin Crossca860ac2016-01-04 14:34:37 -08001781var _ linker = (*binaryLinker)(nil)
1782
1783func (binary *binaryLinker) props() []interface{} {
Colin Cross665dce92016-04-28 14:50:03 -07001784 return append(binary.baseLinker.props(),
1785 &binary.Properties,
1786 &binary.stripper.StripProperties)
1787
Colin Cross3f40fa42015-01-30 17:27:36 -08001788}
1789
Colin Crossca860ac2016-01-04 14:34:37 -08001790func (binary *binaryLinker) buildStatic() bool {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001791 return binary.baseLinker.staticBinary()
Colin Crossed4cf0b2015-03-26 14:43:45 -07001792}
1793
Colin Crossca860ac2016-01-04 14:34:37 -08001794func (binary *binaryLinker) buildShared() bool {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001795 return !binary.baseLinker.staticBinary()
Colin Crossed4cf0b2015-03-26 14:43:45 -07001796}
1797
Colin Crossca860ac2016-01-04 14:34:37 -08001798func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001799 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001800 if binary.Properties.Stem != "" {
1801 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001802 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001803
Colin Crossca860ac2016-01-04 14:34:37 -08001804 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001805}
1806
Colin Crossca860ac2016-01-04 14:34:37 -08001807func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1808 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001809 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001810 if !ctx.sdk() {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001811 if binary.buildStatic() {
Colin Crossca860ac2016-01-04 14:34:37 -08001812 deps.CrtBegin = "crtbegin_static"
Dan Albertc3144b12015-04-28 18:17:56 -07001813 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001814 deps.CrtBegin = "crtbegin_dynamic"
Dan Albertc3144b12015-04-28 18:17:56 -07001815 }
Colin Crossca860ac2016-01-04 14:34:37 -08001816 deps.CrtEnd = "crtend_android"
Colin Cross3f40fa42015-01-30 17:27:36 -08001817 } else {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001818 if binary.buildStatic() {
Colin Crossca860ac2016-01-04 14:34:37 -08001819 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001820 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001821 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
Dan Albertc3144b12015-04-28 18:17:56 -07001822 }
Colin Crossca860ac2016-01-04 14:34:37 -08001823 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
Colin Cross3f40fa42015-01-30 17:27:36 -08001824 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001825
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001826 if binary.buildStatic() {
Colin Crossca860ac2016-01-04 14:34:37 -08001827 if inList("libc++_static", deps.StaticLibs) {
1828 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07001829 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001830 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
1831 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
1832 // move them to the beginning of deps.LateStaticLibs
1833 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08001834 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07001835 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08001836 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001837 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001838 }
Colin Crossca860ac2016-01-04 14:34:37 -08001839
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001840 if binary.buildShared() && inList("libc", deps.StaticLibs) {
Colin Crossca860ac2016-01-04 14:34:37 -08001841 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
1842 "from static libs or set static_executable: true")
1843 }
1844 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001845}
1846
Colin Crossc99deeb2016-04-11 15:06:20 -07001847func (*binaryLinker) installable() bool {
1848 return true
1849}
1850
Colin Cross16b23492016-01-06 14:41:07 -08001851func (binary *binaryLinker) isDependencyRoot() bool {
1852 return true
1853}
1854
Colin Cross635c3b02016-05-18 15:37:25 -07001855func NewBinary(hod android.HostOrDeviceSupported) *Module {
1856 module := newModule(hod, android.MultilibFirst)
Colin Crossca860ac2016-01-04 14:34:37 -08001857 module.compiler = &baseCompiler{}
1858 module.linker = &binaryLinker{}
1859 module.installer = &baseInstaller{
1860 dir: "bin",
1861 }
1862 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08001863}
1864
Colin Crossca860ac2016-01-04 14:34:37 -08001865func binaryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001866 module := NewBinary(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08001867 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001868}
1869
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001870func (binary *binaryLinker) begin(ctx BaseModuleContext) {
1871 binary.baseLinker.begin(ctx)
1872
1873 static := Bool(binary.Properties.Static_executable)
1874 if ctx.Host() {
Colin Cross54c71122016-06-01 17:09:44 -07001875 if ctx.Os() == android.Linux {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001876 if binary.Properties.Static_executable == nil && Bool(ctx.AConfig().ProductVariables.HostStaticBinaries) {
1877 static = true
1878 }
1879 } else {
1880 // Static executables are not supported on Darwin or Windows
1881 static = false
1882 }
Colin Cross0af4b842015-04-30 16:36:18 -07001883 }
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001884 if static {
1885 binary.dynamicProperties.VariantIsStatic = true
Colin Crossca860ac2016-01-04 14:34:37 -08001886 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07001887 }
1888}
1889
Colin Crossca860ac2016-01-04 14:34:37 -08001890func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1891 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001892
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001893 if ctx.Host() && !binary.staticBinary() {
Dan Willemsen490fd492015-11-24 17:53:15 -08001894 flags.LdFlags = append(flags.LdFlags, "-pie")
Colin Cross54c71122016-06-01 17:09:44 -07001895 if ctx.Os() == android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08001896 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
1897 }
1898 }
1899
1900 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1901 // all code is position independent, and then those warnings get promoted to
1902 // errors.
Colin Cross54c71122016-06-01 17:09:44 -07001903 if ctx.Os() != android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08001904 flags.CFlags = append(flags.CFlags, "-fpie")
1905 }
Colin Cross97ba0732015-03-23 17:50:24 -07001906
Colin Crossf6566ed2015-03-24 11:13:38 -07001907 if ctx.Device() {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001908 if binary.buildStatic() {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001909 // Clang driver needs -static to create static executable.
1910 // However, bionic/linker uses -shared to overwrite.
1911 // Linker for x86 targets does not allow coexistance of -static and -shared,
1912 // so we add -static only if -shared is not used.
1913 if !inList("-shared", flags.LdFlags) {
1914 flags.LdFlags = append(flags.LdFlags, "-static")
1915 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001916
Colin Crossed4cf0b2015-03-26 14:43:45 -07001917 flags.LdFlags = append(flags.LdFlags,
1918 "-nostdlib",
1919 "-Bstatic",
1920 "-Wl,--gc-sections",
1921 )
1922
1923 } else {
Colin Cross16b23492016-01-06 14:41:07 -08001924 if flags.DynamicLinker == "" {
1925 flags.DynamicLinker = "/system/bin/linker"
1926 if flags.Toolchain.Is64Bit() {
1927 flags.DynamicLinker += "64"
1928 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001929 }
1930
1931 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08001932 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001933 "-nostdlib",
1934 "-Bdynamic",
Colin Crossed4cf0b2015-03-26 14:43:45 -07001935 "-Wl,--gc-sections",
1936 "-Wl,-z,nocopyreloc",
1937 )
1938 }
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001939 } else {
1940 if binary.staticBinary() {
1941 flags.LdFlags = append(flags.LdFlags, "-static")
1942 }
1943 if ctx.Darwin() {
1944 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
1945 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001946 }
1947
Colin Cross97ba0732015-03-23 17:50:24 -07001948 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001949}
1950
Colin Crossca860ac2016-01-04 14:34:37 -08001951func (binary *binaryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001952 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001953
Colin Cross665dce92016-04-28 14:50:03 -07001954 fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
Colin Cross635c3b02016-05-18 15:37:25 -07001955 outputFile := android.PathForModuleOut(ctx, fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001956 ret := outputFile
Colin Cross54c71122016-06-01 17:09:44 -07001957 if ctx.Os().Class == android.Host {
Colin Cross635c3b02016-05-18 15:37:25 -07001958 binary.hostToolPath = android.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08001959 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001960
Colin Cross635c3b02016-05-18 15:37:25 -07001961 var linkerDeps android.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001962
Colin Crossca860ac2016-01-04 14:34:37 -08001963 sharedLibs := deps.SharedLibs
1964 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
1965
Colin Cross16b23492016-01-06 14:41:07 -08001966 if flags.DynamicLinker != "" {
1967 flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
1968 }
1969
Colin Cross665dce92016-04-28 14:50:03 -07001970 builderFlags := flagsToBuilderFlags(flags)
1971
1972 if binary.stripper.needsStrip(ctx) {
1973 strippedOutputFile := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07001974 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001975 binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
1976 }
1977
1978 if binary.Properties.Prefix_symbols != "" {
1979 afterPrefixSymbols := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07001980 outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001981 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
1982 flagsToBuilderFlags(flags), afterPrefixSymbols)
1983 }
1984
Colin Crossca860ac2016-01-04 14:34:37 -08001985 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07001986 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Cross665dce92016-04-28 14:50:03 -07001987 builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001988
1989 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07001990}
Colin Cross3f40fa42015-01-30 17:27:36 -08001991
Colin Cross635c3b02016-05-18 15:37:25 -07001992func (binary *binaryLinker) HostToolPath() android.OptionalPath {
Colin Crossca860ac2016-01-04 14:34:37 -08001993 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07001994}
1995
Colin Cross665dce92016-04-28 14:50:03 -07001996type stripper struct {
1997 StripProperties StripProperties
1998}
1999
2000func (stripper *stripper) needsStrip(ctx ModuleContext) bool {
2001 return !ctx.AConfig().EmbeddedInMake() && !stripper.StripProperties.Strip.None
2002}
2003
Colin Cross635c3b02016-05-18 15:37:25 -07002004func (stripper *stripper) strip(ctx ModuleContext, in, out android.ModuleOutPath,
Colin Cross665dce92016-04-28 14:50:03 -07002005 flags builderFlags) {
Colin Crossb8ecdfe2016-05-03 15:10:29 -07002006 if ctx.Darwin() {
2007 TransformDarwinStrip(ctx, in, out)
2008 } else {
2009 flags.stripKeepSymbols = stripper.StripProperties.Strip.Keep_symbols
2010 // TODO(ccross): don't add gnu debuglink for user builds
2011 flags.stripAddGnuDebuglink = true
2012 TransformStrip(ctx, in, out, flags)
2013 }
Colin Cross665dce92016-04-28 14:50:03 -07002014}
2015
Colin Cross635c3b02016-05-18 15:37:25 -07002016func testPerSrcMutator(mctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002017 if m, ok := mctx.Module().(*Module); ok {
2018 if test, ok := m.linker.(*testLinker); ok {
2019 if Bool(test.Properties.Test_per_src) {
2020 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
2021 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2022 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
2023 }
2024 tests := mctx.CreateLocalVariations(testNames...)
2025 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2026 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
2027 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i]
2028 }
Colin Cross6002e052015-09-16 16:00:08 -07002029 }
2030 }
2031 }
Colin Cross7d5136f2015-05-11 13:39:40 -07002032}
2033
Colin Crossca860ac2016-01-04 14:34:37 -08002034type testLinker struct {
2035 binaryLinker
2036 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002037}
2038
Dan Willemsend30e6102016-03-30 17:35:50 -07002039func (test *testLinker) begin(ctx BaseModuleContext) {
2040 test.binaryLinker.begin(ctx)
2041
2042 runpath := "../../lib"
2043 if ctx.toolchain().Is64Bit() {
2044 runpath += "64"
2045 }
Colin Crossc99deeb2016-04-11 15:06:20 -07002046 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
Dan Willemsend30e6102016-03-30 17:35:50 -07002047}
2048
Colin Crossca860ac2016-01-04 14:34:37 -08002049func (test *testLinker) props() []interface{} {
2050 return append(test.binaryLinker.props(), &test.Properties)
Dan Albertc403f7c2015-03-18 14:01:18 -07002051}
2052
Colin Crossca860ac2016-01-04 14:34:37 -08002053func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
2054 flags = test.binaryLinker.flags(ctx, flags)
2055
2056 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002057 return flags
2058 }
Dan Albertc403f7c2015-03-18 14:01:18 -07002059
Colin Cross97ba0732015-03-23 17:50:24 -07002060 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07002061 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07002062 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002063
Colin Cross54c71122016-06-01 17:09:44 -07002064 switch ctx.Os() {
Colin Cross635c3b02016-05-18 15:37:25 -07002065 case android.Windows:
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002066 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
Colin Cross635c3b02016-05-18 15:37:25 -07002067 case android.Linux:
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002068 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
2069 flags.LdFlags = append(flags.LdFlags, "-lpthread")
Colin Cross635c3b02016-05-18 15:37:25 -07002070 case android.Darwin:
Dan Willemsen4a946832016-05-13 14:13:01 -07002071 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_MAC")
2072 flags.LdFlags = append(flags.LdFlags, "-lpthread")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002073 }
2074 } else {
2075 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07002076 }
2077
Colin Cross21b9a242015-03-24 14:15:58 -07002078 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07002079}
2080
Colin Crossca860ac2016-01-04 14:34:37 -08002081func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2082 if test.Properties.Gtest {
Dan Willemsen8146b2f2016-03-30 21:00:30 -07002083 if ctx.sdk() && ctx.Device() {
2084 switch ctx.selectedStl() {
2085 case "ndk_libc++_shared", "ndk_libc++_static":
2086 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_libcxx", "libgtest_ndk_libcxx")
2087 case "ndk_libgnustl_static":
2088 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_gnustl", "libgtest_ndk_gnustl")
2089 default:
2090 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk", "libgtest_ndk")
2091 }
2092 } else {
2093 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
2094 }
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002095 }
Colin Crossca860ac2016-01-04 14:34:37 -08002096 deps = test.binaryLinker.deps(ctx, deps)
2097 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07002098}
2099
Colin Crossca860ac2016-01-04 14:34:37 -08002100type testInstaller struct {
2101 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08002102}
2103
Colin Cross635c3b02016-05-18 15:37:25 -07002104func (installer *testInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08002105 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
2106 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
2107 installer.baseInstaller.install(ctx, file)
2108}
2109
Colin Cross635c3b02016-05-18 15:37:25 -07002110func NewTest(hod android.HostOrDeviceSupported) *Module {
2111 module := newModule(hod, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002112 module.compiler = &baseCompiler{}
2113 linker := &testLinker{}
2114 linker.Properties.Gtest = true
2115 module.linker = linker
2116 module.installer = &testInstaller{
2117 baseInstaller: baseInstaller{
2118 dir: "nativetest",
2119 dir64: "nativetest64",
2120 data: true,
2121 },
Dan Albertc403f7c2015-03-18 14:01:18 -07002122 }
Colin Crossca860ac2016-01-04 14:34:37 -08002123 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002124}
2125
Colin Crossca860ac2016-01-04 14:34:37 -08002126func testFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002127 module := NewTest(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002128 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07002129}
2130
Colin Crossca860ac2016-01-04 14:34:37 -08002131type benchmarkLinker struct {
2132 binaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07002133}
2134
Colin Crossca860ac2016-01-04 14:34:37 -08002135func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2136 deps = benchmark.binaryLinker.deps(ctx, deps)
2137 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase")
2138 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07002139}
2140
Colin Cross635c3b02016-05-18 15:37:25 -07002141func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
2142 module := newModule(hod, android.MultilibFirst)
Colin Crossca860ac2016-01-04 14:34:37 -08002143 module.compiler = &baseCompiler{}
2144 module.linker = &benchmarkLinker{}
2145 module.installer = &baseInstaller{
2146 dir: "nativetest",
2147 dir64: "nativetest64",
2148 data: true,
Colin Cross2ba19d92015-05-07 15:44:20 -07002149 }
Colin Crossca860ac2016-01-04 14:34:37 -08002150 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07002151}
2152
Colin Crossca860ac2016-01-04 14:34:37 -08002153func benchmarkFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002154 module := NewBenchmark(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002155 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002156}
2157
Colin Cross3f40fa42015-01-30 17:27:36 -08002158//
2159// Static library
2160//
2161
Colin Crossca860ac2016-01-04 14:34:37 -08002162func libraryStaticFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002163 module := NewLibrary(android.HostAndDeviceSupported, false, true)
Colin Crossca860ac2016-01-04 14:34:37 -08002164 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002165}
2166
2167//
2168// Shared libraries
2169//
2170
Colin Crossca860ac2016-01-04 14:34:37 -08002171func librarySharedFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002172 module := NewLibrary(android.HostAndDeviceSupported, true, false)
Colin Crossca860ac2016-01-04 14:34:37 -08002173 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002174}
2175
2176//
2177// Host static library
2178//
2179
Colin Crossca860ac2016-01-04 14:34:37 -08002180func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002181 module := NewLibrary(android.HostSupported, false, true)
Colin Crossca860ac2016-01-04 14:34:37 -08002182 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002183}
2184
2185//
2186// Host Shared libraries
2187//
2188
Colin Crossca860ac2016-01-04 14:34:37 -08002189func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002190 module := NewLibrary(android.HostSupported, true, false)
Colin Crossca860ac2016-01-04 14:34:37 -08002191 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002192}
2193
2194//
2195// Host Binaries
2196//
2197
Colin Crossca860ac2016-01-04 14:34:37 -08002198func binaryHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002199 module := NewBinary(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002200 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002201}
2202
2203//
Colin Cross1f8f2342015-03-26 16:09:47 -07002204// Host Tests
2205//
2206
Colin Crossca860ac2016-01-04 14:34:37 -08002207func testHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002208 module := NewTest(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002209 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07002210}
2211
2212//
Colin Cross2ba19d92015-05-07 15:44:20 -07002213// Host Benchmarks
2214//
2215
Colin Crossca860ac2016-01-04 14:34:37 -08002216func benchmarkHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002217 module := NewBenchmark(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002218 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002219}
2220
2221//
Colin Crosscfad1192015-11-02 16:43:11 -08002222// Defaults
2223//
Colin Crossca860ac2016-01-04 14:34:37 -08002224type Defaults struct {
Colin Cross635c3b02016-05-18 15:37:25 -07002225 android.ModuleBase
2226 android.DefaultsModule
Colin Crosscfad1192015-11-02 16:43:11 -08002227}
2228
Colin Cross635c3b02016-05-18 15:37:25 -07002229func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002230}
2231
Colin Crossca860ac2016-01-04 14:34:37 -08002232func defaultsFactory() (blueprint.Module, []interface{}) {
2233 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002234
2235 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002236 &BaseProperties{},
2237 &BaseCompilerProperties{},
2238 &BaseLinkerProperties{},
2239 &LibraryCompilerProperties{},
Colin Cross919281a2016-04-05 16:42:05 -07002240 &FlagExporterProperties{},
Colin Crossca860ac2016-01-04 14:34:37 -08002241 &LibraryLinkerProperties{},
2242 &BinaryLinkerProperties{},
2243 &TestLinkerProperties{},
2244 &UnusedProperties{},
2245 &StlProperties{},
Colin Cross16b23492016-01-06 14:41:07 -08002246 &SanitizeProperties{},
Colin Cross665dce92016-04-28 14:50:03 -07002247 &StripProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002248 }
2249
Colin Cross635c3b02016-05-18 15:37:25 -07002250 _, propertyStructs = android.InitAndroidArchModule(module, android.HostAndDeviceDefault,
2251 android.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002252
Colin Cross635c3b02016-05-18 15:37:25 -07002253 return android.InitDefaultsModule(module, module, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002254}
2255
2256//
Colin Cross3f40fa42015-01-30 17:27:36 -08002257// Device libraries shipped with gcc
2258//
2259
Colin Crossca860ac2016-01-04 14:34:37 -08002260type toolchainLibraryLinker struct {
2261 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002262}
2263
Colin Crossca860ac2016-01-04 14:34:37 -08002264var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2265
2266func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002267 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002268 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002269}
2270
Colin Crossca860ac2016-01-04 14:34:37 -08002271func (*toolchainLibraryLinker) buildStatic() bool {
2272 return true
2273}
Colin Cross3f40fa42015-01-30 17:27:36 -08002274
Colin Crossca860ac2016-01-04 14:34:37 -08002275func (*toolchainLibraryLinker) buildShared() bool {
2276 return false
2277}
2278
2279func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002280 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002281 module.compiler = &baseCompiler{}
2282 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002283 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002284 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002285}
2286
Colin Crossca860ac2016-01-04 14:34:37 -08002287func (library *toolchainLibraryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07002288 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002289
2290 libName := ctx.ModuleName() + staticLibraryExtension
Colin Cross635c3b02016-05-18 15:37:25 -07002291 outputFile := android.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002292
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002293 if flags.Clang {
2294 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2295 }
2296
Colin Crossca860ac2016-01-04 14:34:37 -08002297 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002298
2299 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002300
Colin Crossca860ac2016-01-04 14:34:37 -08002301 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002302}
2303
Colin Crossc99deeb2016-04-11 15:06:20 -07002304func (*toolchainLibraryLinker) installable() bool {
2305 return false
2306}
2307
Dan Albertbe961682015-03-18 23:38:50 -07002308// NDK prebuilt libraries.
2309//
2310// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2311// either (with the exception of the shared STLs, which are installed to the app's directory rather
2312// than to the system image).
2313
Colin Cross635c3b02016-05-18 15:37:25 -07002314func getNdkLibDir(ctx android.ModuleContext, toolchain Toolchain, version string) android.SourcePath {
Colin Crossc7fd91a2016-05-17 13:15:15 -07002315 suffix := ""
2316 // Most 64-bit NDK prebuilts store libraries in "lib64", except for arm64 which is not a
2317 // multilib toolchain and stores the libraries in "lib".
Colin Cross635c3b02016-05-18 15:37:25 -07002318 if toolchain.Is64Bit() && ctx.Arch().ArchType != android.Arm64 {
Colin Crossc7fd91a2016-05-17 13:15:15 -07002319 suffix = "64"
2320 }
Colin Cross635c3b02016-05-18 15:37:25 -07002321 return android.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib%s",
Colin Crossc7fd91a2016-05-17 13:15:15 -07002322 version, toolchain.Name(), suffix))
Dan Albertbe961682015-03-18 23:38:50 -07002323}
2324
Colin Cross635c3b02016-05-18 15:37:25 -07002325func ndkPrebuiltModuleToPath(ctx android.ModuleContext, toolchain Toolchain,
2326 ext string, version string) android.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002327
2328 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2329 // We want to translate to just NAME.EXT
2330 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2331 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002332 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002333}
2334
Colin Crossca860ac2016-01-04 14:34:37 -08002335type ndkPrebuiltObjectLinker struct {
2336 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002337}
2338
Colin Crossca860ac2016-01-04 14:34:37 -08002339func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002340 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002341 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002342}
2343
Colin Crossca860ac2016-01-04 14:34:37 -08002344func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002345 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002346 module.linker = &ndkPrebuiltObjectLinker{}
2347 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002348}
2349
Colin Crossca860ac2016-01-04 14:34:37 -08002350func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002351 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002352 // A null build step, but it sets up the output path.
2353 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2354 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2355 }
2356
Colin Crossca860ac2016-01-04 14:34:37 -08002357 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002358}
2359
Colin Crossca860ac2016-01-04 14:34:37 -08002360type ndkPrebuiltLibraryLinker struct {
2361 libraryLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002362}
2363
Colin Crossca860ac2016-01-04 14:34:37 -08002364var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2365var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002366
Colin Crossca860ac2016-01-04 14:34:37 -08002367func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Cross919281a2016-04-05 16:42:05 -07002368 return append(ndk.libraryLinker.props(), &ndk.Properties, &ndk.flagExporter.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002369}
2370
Colin Crossca860ac2016-01-04 14:34:37 -08002371func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002372 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002373 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002374}
2375
Colin Crossca860ac2016-01-04 14:34:37 -08002376func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002377 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002378 linker := &ndkPrebuiltLibraryLinker{}
2379 linker.dynamicProperties.BuildShared = true
2380 module.linker = linker
2381 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002382}
2383
Colin Crossca860ac2016-01-04 14:34:37 -08002384func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002385 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002386 // A null build step, but it sets up the output path.
2387 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2388 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2389 }
2390
Colin Cross919281a2016-04-05 16:42:05 -07002391 ndk.exportIncludes(ctx, "-isystem")
Dan Albertbe961682015-03-18 23:38:50 -07002392
Colin Crossca860ac2016-01-04 14:34:37 -08002393 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2394 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002395}
2396
2397// The NDK STLs are slightly different from the prebuilt system libraries:
2398// * Are not specific to each platform version.
2399// * The libraries are not in a predictable location for each STL.
2400
Colin Crossca860ac2016-01-04 14:34:37 -08002401type ndkPrebuiltStlLinker struct {
2402 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002403}
2404
Colin Crossca860ac2016-01-04 14:34:37 -08002405func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002406 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002407 linker := &ndkPrebuiltStlLinker{}
2408 linker.dynamicProperties.BuildShared = true
2409 module.linker = linker
2410 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002411}
2412
Colin Crossca860ac2016-01-04 14:34:37 -08002413func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002414 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002415 linker := &ndkPrebuiltStlLinker{}
2416 linker.dynamicProperties.BuildStatic = true
2417 module.linker = linker
2418 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002419}
2420
Colin Cross635c3b02016-05-18 15:37:25 -07002421func getNdkStlLibDir(ctx android.ModuleContext, toolchain Toolchain, stl string) android.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002422 gccVersion := toolchain.GccVersion()
2423 var libDir string
2424 switch stl {
2425 case "libstlport":
2426 libDir = "cxx-stl/stlport/libs"
2427 case "libc++":
2428 libDir = "cxx-stl/llvm-libc++/libs"
2429 case "libgnustl":
2430 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2431 }
2432
2433 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002434 ndkSrcRoot := "prebuilts/ndk/current/sources"
Colin Cross635c3b02016-05-18 15:37:25 -07002435 return android.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002436 }
2437
2438 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Colin Cross635c3b02016-05-18 15:37:25 -07002439 return android.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002440}
2441
Colin Crossca860ac2016-01-04 14:34:37 -08002442func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002443 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002444 // A null build step, but it sets up the output path.
2445 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2446 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2447 }
2448
Colin Cross919281a2016-04-05 16:42:05 -07002449 ndk.exportIncludes(ctx, "-I")
Dan Albertbe961682015-03-18 23:38:50 -07002450
2451 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002452 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002453 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002454 libExt = staticLibraryExtension
2455 }
2456
2457 stlName := strings.TrimSuffix(libName, "_shared")
2458 stlName = strings.TrimSuffix(stlName, "_static")
2459 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002460 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002461}
2462
Colin Cross635c3b02016-05-18 15:37:25 -07002463func linkageMutator(mctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002464 if m, ok := mctx.Module().(*Module); ok {
2465 if m.linker != nil {
2466 if linker, ok := m.linker.(baseLinkerInterface); ok {
2467 var modules []blueprint.Module
2468 if linker.buildStatic() && linker.buildShared() {
2469 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002470 static := modules[0].(*Module)
2471 shared := modules[1].(*Module)
2472
2473 static.linker.(baseLinkerInterface).setStatic(true)
2474 shared.linker.(baseLinkerInterface).setStatic(false)
2475
2476 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2477 sharedCompiler := shared.compiler.(*libraryCompiler)
2478 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2479 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2480 // Optimize out compiling common .o files twice for static+shared libraries
2481 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2482 sharedCompiler.baseCompiler.Properties.Srcs = nil
2483 }
2484 }
Colin Crossca860ac2016-01-04 14:34:37 -08002485 } else if linker.buildStatic() {
2486 modules = mctx.CreateLocalVariations("static")
2487 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2488 } else if linker.buildShared() {
2489 modules = mctx.CreateLocalVariations("shared")
2490 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2491 } else {
2492 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2493 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002494 }
2495 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002496 }
2497}
Colin Cross74d1ec02015-04-28 13:30:13 -07002498
2499// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2500// modifies the slice contents in place, and returns a subslice of the original slice
2501func lastUniqueElements(list []string) []string {
2502 totalSkip := 0
2503 for i := len(list) - 1; i >= totalSkip; i-- {
2504 skip := 0
2505 for j := i - 1; j >= totalSkip; j-- {
2506 if list[i] == list[j] {
2507 skip++
2508 } else {
2509 list[j+skip] = list[j]
2510 }
2511 }
2512 totalSkip += skip
2513 }
2514 return list[totalSkip:]
2515}
Colin Cross06a931b2015-10-28 17:23:31 -07002516
2517var Bool = proptools.Bool