blob: 60bc4d472450ab67b058d70b9cc142a2d9795735 [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)
Colin Crossc7a38dc2016-07-12 13:13:09 -070041 soong.RegisterModuleType("cc_test_library", testLibraryFactory)
Colin Crossca860ac2016-01-04 14:34:37 -080042 soong.RegisterModuleType("cc_benchmark", benchmarkFactory)
43 soong.RegisterModuleType("cc_defaults", defaultsFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070044
Colin Crossca860ac2016-01-04 14:34:37 -080045 soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
46 soong.RegisterModuleType("ndk_prebuilt_library", ndkPrebuiltLibraryFactory)
47 soong.RegisterModuleType("ndk_prebuilt_object", ndkPrebuiltObjectFactory)
48 soong.RegisterModuleType("ndk_prebuilt_static_stl", ndkPrebuiltStaticStlFactory)
49 soong.RegisterModuleType("ndk_prebuilt_shared_stl", ndkPrebuiltSharedStlFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070050
Colin Crossca860ac2016-01-04 14:34:37 -080051 soong.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory)
52 soong.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory)
53 soong.RegisterModuleType("cc_binary_host", binaryHostFactory)
54 soong.RegisterModuleType("cc_test_host", testHostFactory)
55 soong.RegisterModuleType("cc_benchmark_host", benchmarkHostFactory)
Colin Cross463a90e2015-06-17 14:20:06 -070056
57 // LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
58 // the Go initialization order because this package depends on common, so common's init
59 // functions will run first.
Colin Cross635c3b02016-05-18 15:37:25 -070060 android.RegisterBottomUpMutator("link", linkageMutator)
61 android.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
62 android.RegisterBottomUpMutator("deps", depsMutator)
Colin Cross16b23492016-01-06 14:41:07 -080063
Colin Cross635c3b02016-05-18 15:37:25 -070064 android.RegisterTopDownMutator("asan_deps", sanitizerDepsMutator(asan))
65 android.RegisterBottomUpMutator("asan", sanitizerMutator(asan))
Colin Cross16b23492016-01-06 14:41:07 -080066
Colin Cross635c3b02016-05-18 15:37:25 -070067 android.RegisterTopDownMutator("tsan_deps", sanitizerDepsMutator(tsan))
68 android.RegisterBottomUpMutator("tsan", sanitizerMutator(tsan))
Colin Cross463a90e2015-06-17 14:20:06 -070069}
70
Colin Cross3f40fa42015-01-30 17:27:36 -080071var (
Colin Cross635c3b02016-05-18 15:37:25 -070072 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
Colin Cross3f40fa42015-01-30 17:27:36 -080073)
74
75// Flags used by lots of devices. Putting them in package static variables will save bytes in
76// build.ninja so they aren't repeated for every file
77var (
78 commonGlobalCflags = []string{
79 "-DANDROID",
80 "-fmessage-length=0",
81 "-W",
82 "-Wall",
83 "-Wno-unused",
84 "-Winit-self",
85 "-Wpointer-arith",
86
87 // COMMON_RELEASE_CFLAGS
88 "-DNDEBUG",
89 "-UDEBUG",
90 }
91
92 deviceGlobalCflags = []string{
Dan Willemsen490fd492015-11-24 17:53:15 -080093 "-fdiagnostics-color",
94
Colin Cross3f40fa42015-01-30 17:27:36 -080095 // TARGET_ERROR_FLAGS
96 "-Werror=return-type",
97 "-Werror=non-virtual-dtor",
98 "-Werror=address",
99 "-Werror=sequence-point",
Dan Willemsena6084a32016-03-01 15:16:50 -0800100 "-Werror=date-time",
Colin Cross3f40fa42015-01-30 17:27:36 -0800101 }
102
103 hostGlobalCflags = []string{}
104
105 commonGlobalCppflags = []string{
106 "-Wsign-promo",
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700107 }
108
Dan Willemsenbe03f342016-03-03 17:21:04 -0800109 noOverrideGlobalCflags = []string{
110 "-Werror=int-to-pointer-cast",
111 "-Werror=pointer-to-int-cast",
112 }
113
Dan Willemsen3bf6b472015-09-11 17:41:10 -0700114 illegalFlags = []string{
115 "-w",
Colin Cross3f40fa42015-01-30 17:27:36 -0800116 }
Dan Willemsen97704ed2016-07-07 21:40:39 -0700117
118 ndkPrebuiltSharedLibs = []string{
119 "android",
120 "c",
121 "dl",
122 "EGL",
123 "GLESv1_CM",
124 "GLESv2",
125 "GLESv3",
126 "jnigraphics",
127 "log",
128 "mediandk",
129 "m",
130 "OpenMAXAL",
131 "OpenSLES",
132 "stdc++",
133 "vulkan",
134 "z",
135 }
136 ndkPrebuiltSharedLibraries = addPrefix(append([]string(nil), ndkPrebuiltSharedLibs...), "lib")
Colin Cross3f40fa42015-01-30 17:27:36 -0800137)
138
139func init() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700140 if android.BuildOs == android.Linux {
Dan Willemsen0c38c5e2016-03-29 17:31:57 -0700141 commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
142 }
143
Colin Cross3f40fa42015-01-30 17:27:36 -0800144 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
145 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
146 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800147 pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800148
149 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
150
151 pctx.StaticVariable("commonClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800152 strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800153 pctx.StaticVariable("deviceClangGlobalCflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800154 strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800155 pctx.StaticVariable("hostClangGlobalCflags",
156 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
Dan Willemsenbe03f342016-03-03 17:21:04 -0800157 pctx.StaticVariable("noOverrideClangGlobalCflags",
158 strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
159
Tim Kilbournf2948142015-03-11 12:03:03 -0700160 pctx.StaticVariable("commonClangGlobalCppflags",
Dan Willemsenac5e1cb2016-01-12 16:22:40 -0800161 strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
Colin Cross3f40fa42015-01-30 17:27:36 -0800162
163 // Everything in this list is a crime against abstraction and dependency tracking.
164 // Do not add anything to this list.
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800165 pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700166 []string{
167 "system/core/include",
Dan Willemsen98f93c72016-03-01 15:27:03 -0800168 "system/media/audio/include",
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700169 "hardware/libhardware/include",
170 "hardware/libhardware_legacy/include",
171 "hardware/ril/include",
172 "libnativehelper/include",
173 "frameworks/native/include",
174 "frameworks/native/opengl/include",
175 "frameworks/av/include",
176 "frameworks/base/include",
177 })
Dan Willemsene0378dd2016-01-07 17:42:34 -0800178 // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
179 // with this, since there is no associated library.
180 pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
181 []string{"libnativehelper/include/nativehelper"})
Colin Cross3f40fa42015-01-30 17:27:36 -0800182
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700183 pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
184 pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
Colin Cross635c3b02016-05-18 15:37:25 -0700185 if override := config.(android.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700186 return override, nil
187 }
188 return "${clangDefaultBase}", nil
189 })
190 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
Colin Cross635c3b02016-05-18 15:37:25 -0700191 if override := config.(android.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700192 return override, nil
193 }
Pirama Arumuga Nainara17442b2016-06-28 11:00:12 -0700194 return "clang-3016494", nil
Dan Willemsendc5d28a2016-03-16 11:37:17 -0700195 })
Colin Cross16b23492016-01-06 14:41:07 -0800196 pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}")
197 pctx.StaticVariable("clangBin", "${clangPath}/bin")
Colin Cross3f40fa42015-01-30 17:27:36 -0800198}
199
Colin Crossca860ac2016-01-04 14:34:37 -0800200type Deps struct {
201 SharedLibs, LateSharedLibs []string
202 StaticLibs, LateStaticLibs, WholeStaticLibs []string
Colin Crossc472d572015-03-17 15:06:21 -0700203
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700204 ReexportSharedLibHeaders, ReexportStaticLibHeaders []string
205
Colin Cross81413472016-04-11 14:37:39 -0700206 ObjFiles []string
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700207
Dan Willemsenb40aab62016-04-20 14:21:14 -0700208 GeneratedSources []string
209 GeneratedHeaders []string
210
Colin Cross97ba0732015-03-23 17:50:24 -0700211 CrtBegin, CrtEnd string
Colin Crossc472d572015-03-17 15:06:21 -0700212}
213
Colin Crossca860ac2016-01-04 14:34:37 -0800214type PathDeps struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700215 SharedLibs, LateSharedLibs android.Paths
216 StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700217
Colin Cross635c3b02016-05-18 15:37:25 -0700218 ObjFiles android.Paths
219 WholeStaticLibObjFiles android.Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700220
Colin Cross635c3b02016-05-18 15:37:25 -0700221 GeneratedSources android.Paths
222 GeneratedHeaders android.Paths
Dan Willemsenb40aab62016-04-20 14:21:14 -0700223
Dan Willemsen76f08272016-07-09 00:14:08 -0700224 Flags, ReexportedFlags []string
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700225
Colin Cross635c3b02016-05-18 15:37:25 -0700226 CrtBegin, CrtEnd android.OptionalPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700227}
228
Colin Crossca860ac2016-01-04 14:34:37 -0800229type Flags struct {
Colin Cross28344522015-04-22 13:07:53 -0700230 GlobalFlags []string // Flags that apply to C, C++, and assembly source files
231 AsFlags []string // Flags that apply to assembly source files
232 CFlags []string // Flags that apply to C and C++ source files
233 ConlyFlags []string // Flags that apply to C source files
234 CppFlags []string // Flags that apply to C++ source files
235 YaccFlags []string // Flags that apply to Yacc source files
236 LdFlags []string // Flags that apply to linker command lines
Colin Cross16b23492016-01-06 14:41:07 -0800237 libFlags []string // Flags to add libraries early to the link order
Colin Cross28344522015-04-22 13:07:53 -0700238
239 Nocrt bool
240 Toolchain Toolchain
241 Clang bool
Colin Crossca860ac2016-01-04 14:34:37 -0800242
243 RequiredInstructionSet string
Colin Cross16b23492016-01-06 14:41:07 -0800244 DynamicLinker string
245
Colin Cross635c3b02016-05-18 15:37:25 -0700246 CFlagsDeps android.Paths // Files depended on by compiler flags
Colin Crossc472d572015-03-17 15:06:21 -0700247}
248
Colin Crossca860ac2016-01-04 14:34:37 -0800249type BaseCompilerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700250 // 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 -0700251 Srcs []string `android:"arch_variant"`
252
253 // list of source files that should not be used to build the C/C++ module.
254 // This is most useful in the arch/multilib variants to remove non-common files
255 Exclude_srcs []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700256
257 // list of module-specific flags that will be used for C and C++ compiles.
258 Cflags []string `android:"arch_variant"`
259
260 // list of module-specific flags that will be used for C++ compiles
261 Cppflags []string `android:"arch_variant"`
262
263 // list of module-specific flags that will be used for C compiles
264 Conlyflags []string `android:"arch_variant"`
265
266 // list of module-specific flags that will be used for .S compiles
267 Asflags []string `android:"arch_variant"`
268
Colin Crossca860ac2016-01-04 14:34:37 -0800269 // list of module-specific flags that will be used for C and C++ compiles when
270 // compiling with clang
271 Clang_cflags []string `android:"arch_variant"`
272
273 // list of module-specific flags that will be used for .S compiles when
274 // compiling with clang
275 Clang_asflags []string `android:"arch_variant"`
276
Colin Cross7d5136f2015-05-11 13:39:40 -0700277 // list of module-specific flags that will be used for .y and .yy compiles
278 Yaccflags []string
279
Colin Cross7d5136f2015-05-11 13:39:40 -0700280 // the instruction set architecture to use to compile the C/C++
281 // module.
282 Instruction_set string `android:"arch_variant"`
283
284 // list of directories relative to the root of the source tree that will
285 // be added to the include path using -I.
286 // If possible, don't use this. If adding paths from the current directory use
287 // local_include_dirs, if adding paths from other modules use export_include_dirs in
288 // that module.
289 Include_dirs []string `android:"arch_variant"`
290
291 // list of directories relative to the Blueprints file that will
292 // be added to the include path using -I
293 Local_include_dirs []string `android:"arch_variant"`
294
Dan Willemsenb40aab62016-04-20 14:21:14 -0700295 // list of generated sources to compile. These are the names of gensrcs or
296 // genrule modules.
297 Generated_sources []string `android:"arch_variant"`
298
299 // list of generated headers to add to the include path. These are the names
300 // of genrule modules.
301 Generated_headers []string `android:"arch_variant"`
302
Colin Crossca860ac2016-01-04 14:34:37 -0800303 // pass -frtti instead of -fno-rtti
304 Rtti *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700305
Colin Crossca860ac2016-01-04 14:34:37 -0800306 Debug, Release struct {
307 // list of module-specific flags that will be used for C and C++ compiles in debug or
308 // release builds
309 Cflags []string `android:"arch_variant"`
310 } `android:"arch_variant"`
311}
Colin Cross7d5136f2015-05-11 13:39:40 -0700312
Colin Crossca860ac2016-01-04 14:34:37 -0800313type BaseLinkerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700314 // list of modules whose object files should be linked into this module
315 // in their entirety. For static library modules, all of the .o files from the intermediate
316 // directory of the dependency will be linked into this modules .a file. For a shared library,
317 // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
Colin Cross6ee75b62016-05-05 15:57:15 -0700318 Whole_static_libs []string `android:"arch_variant,variant_prepend"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700319
320 // list of modules that should be statically linked into this module.
Colin Cross6ee75b62016-05-05 15:57:15 -0700321 Static_libs []string `android:"arch_variant,variant_prepend"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700322
323 // list of modules that should be dynamically linked into this module.
324 Shared_libs []string `android:"arch_variant"`
325
Colin Crossca860ac2016-01-04 14:34:37 -0800326 // list of module-specific flags that will be used for all link steps
327 Ldflags []string `android:"arch_variant"`
328
329 // don't insert default compiler flags into asflags, cflags,
330 // cppflags, conlyflags, ldflags, or include_dirs
331 No_default_compiler_flags *bool
332
333 // list of system libraries that will be dynamically linked to
334 // shared library and executable modules. If unset, generally defaults to libc
335 // and libm. Set to [] to prevent linking against libc and libm.
336 System_shared_libs []string
337
Colin Cross7d5136f2015-05-11 13:39:40 -0700338 // allow the module to contain undefined symbols. By default,
339 // modules cannot contain undefined symbols that are not satisified by their immediate
340 // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
341 // This flag should only be necessary for compiling low-level libraries like libc.
Colin Cross06a931b2015-10-28 17:23:31 -0700342 Allow_undefined_symbols *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700343
Dan Willemsend67be222015-09-16 15:19:33 -0700344 // don't link in libgcc.a
Colin Cross06a931b2015-10-28 17:23:31 -0700345 No_libgcc *bool
Dan Willemsend67be222015-09-16 15:19:33 -0700346
Colin Cross7d5136f2015-05-11 13:39:40 -0700347 // -l arguments to pass to linker for host-provided shared libraries
348 Host_ldlibs []string `android:"arch_variant"`
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700349
350 // list of shared libraries to re-export include directories from. Entries must be
351 // present in shared_libs.
352 Export_shared_lib_headers []string `android:"arch_variant"`
353
354 // list of static libraries to re-export include directories from. Entries must be
355 // present in static_libs.
356 Export_static_lib_headers []string `android:"arch_variant"`
Colin Crossa89d2e12016-01-11 12:48:37 -0800357
358 // don't link in crt_begin and crt_end. This flag should only be necessary for
359 // compiling crt or libc.
360 Nocrt *bool `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800361}
Colin Cross7d5136f2015-05-11 13:39:40 -0700362
Colin Crossca860ac2016-01-04 14:34:37 -0800363type LibraryCompilerProperties struct {
364 Static struct {
365 Srcs []string `android:"arch_variant"`
366 Exclude_srcs []string `android:"arch_variant"`
367 Cflags []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700368 } `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800369 Shared struct {
370 Srcs []string `android:"arch_variant"`
371 Exclude_srcs []string `android:"arch_variant"`
372 Cflags []string `android:"arch_variant"`
373 } `android:"arch_variant"`
374}
375
Colin Cross919281a2016-04-05 16:42:05 -0700376type FlagExporterProperties struct {
377 // list of directories relative to the Blueprints file that will
378 // be added to the include path using -I for any module that links against this module
379 Export_include_dirs []string `android:"arch_variant"`
380}
381
Colin Crossca860ac2016-01-04 14:34:37 -0800382type LibraryLinkerProperties struct {
383 Static struct {
Dan Willemsenfed4d192016-07-06 21:48:39 -0700384 Enabled *bool `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800385 Whole_static_libs []string `android:"arch_variant"`
386 Static_libs []string `android:"arch_variant"`
387 Shared_libs []string `android:"arch_variant"`
388 } `android:"arch_variant"`
389 Shared struct {
Dan Willemsenfed4d192016-07-06 21:48:39 -0700390 Enabled *bool `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800391 Whole_static_libs []string `android:"arch_variant"`
392 Static_libs []string `android:"arch_variant"`
393 Shared_libs []string `android:"arch_variant"`
394 } `android:"arch_variant"`
395
396 // local file name to pass to the linker as --version_script
397 Version_script *string `android:"arch_variant"`
398 // local file name to pass to the linker as -unexported_symbols_list
399 Unexported_symbols_list *string `android:"arch_variant"`
400 // local file name to pass to the linker as -force_symbols_not_weak_list
401 Force_symbols_not_weak_list *string `android:"arch_variant"`
402 // local file name to pass to the linker as -force_symbols_weak_list
403 Force_symbols_weak_list *string `android:"arch_variant"`
404
Dan Willemsen648c8ae2016-07-21 16:42:14 -0700405 // rename host libraries to prevent overlap with system installed libraries
406 Unique_host_soname *bool
407
Colin Cross16b23492016-01-06 14:41:07 -0800408 VariantName string `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800409}
410
411type BinaryLinkerProperties struct {
412 // compile executable with -static
Dan Willemsen75ab8082016-07-12 15:36:34 -0700413 Static_executable *bool `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -0800414
415 // set the name of the output
416 Stem string `android:"arch_variant"`
417
418 // append to the name of the output
419 Suffix string `android:"arch_variant"`
420
421 // if set, add an extra objcopy --prefix-symbols= step
422 Prefix_symbols string
423}
424
425type TestLinkerProperties struct {
426 // if set, build against the gtest library. Defaults to true.
427 Gtest bool
428
429 // Create a separate binary for each source file. Useful when there is
430 // global state that can not be torn down and reset between each test suite.
431 Test_per_src *bool
432}
433
Colin Cross81413472016-04-11 14:37:39 -0700434type ObjectLinkerProperties struct {
435 // names of other cc_object modules to link into this module using partial linking
436 Objs []string `android:"arch_variant"`
437}
438
Colin Crossca860ac2016-01-04 14:34:37 -0800439// Properties used to compile all C or C++ modules
440type BaseProperties struct {
441 // compile module with clang instead of gcc
442 Clang *bool `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700443
444 // Minimum sdk version supported when compiling against the ndk
445 Sdk_version string
446
Colin Crossca860ac2016-01-04 14:34:37 -0800447 // don't insert default compiler flags into asflags, cflags,
448 // cppflags, conlyflags, ldflags, or include_dirs
449 No_default_compiler_flags *bool
Colin Crossc99deeb2016-04-11 15:06:20 -0700450
451 AndroidMkSharedLibs []string `blueprint:"mutated"`
Colin Crossbc6fb162016-05-24 15:39:04 -0700452 HideFromMake bool `blueprint:"mutated"`
Colin Crossca860ac2016-01-04 14:34:37 -0800453}
454
455type InstallerProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700456 // install to a subdirectory of the default install path for the module
457 Relative_install_path string
Colin Cross3854a602016-01-11 12:49:11 -0800458
459 // install symlinks to the module
460 Symlinks []string `android:"arch_variant"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700461}
462
Colin Cross665dce92016-04-28 14:50:03 -0700463type StripProperties struct {
464 Strip struct {
465 None bool
466 Keep_symbols bool
467 }
468}
469
Colin Crossca860ac2016-01-04 14:34:37 -0800470type UnusedProperties struct {
Colin Cross21b481b2016-04-15 16:27:17 -0700471 Native_coverage *bool
472 Required []string
Colin Cross21b481b2016-04-15 16:27:17 -0700473 Tags []string
Colin Crosscfad1192015-11-02 16:43:11 -0800474}
475
Colin Crossca860ac2016-01-04 14:34:37 -0800476type ModuleContextIntf interface {
Colin Crossca860ac2016-01-04 14:34:37 -0800477 static() bool
478 staticBinary() bool
479 clang() bool
480 toolchain() Toolchain
481 noDefaultCompilerFlags() bool
482 sdk() bool
483 sdkVersion() string
Dan Willemsen8146b2f2016-03-30 21:00:30 -0700484 selectedStl() string
Colin Crossca860ac2016-01-04 14:34:37 -0800485}
486
487type ModuleContext interface {
Colin Cross635c3b02016-05-18 15:37:25 -0700488 android.ModuleContext
Colin Crossca860ac2016-01-04 14:34:37 -0800489 ModuleContextIntf
490}
491
492type BaseModuleContext interface {
Colin Cross635c3b02016-05-18 15:37:25 -0700493 android.BaseContext
Colin Crossca860ac2016-01-04 14:34:37 -0800494 ModuleContextIntf
495}
496
Colin Cross76fada02016-07-27 10:31:13 -0700497type CustomizerFlagsContext interface {
498 BaseModuleContext
499 AppendCflags(...string)
500 AppendLdflags(...string)
501 AppendAsflags(...string)
502}
503
Colin Crossca860ac2016-01-04 14:34:37 -0800504type Customizer interface {
Colin Cross76fada02016-07-27 10:31:13 -0700505 Flags(CustomizerFlagsContext)
Colin Crossca860ac2016-01-04 14:34:37 -0800506 Properties() []interface{}
507}
508
509type feature interface {
510 begin(ctx BaseModuleContext)
511 deps(ctx BaseModuleContext, deps Deps) Deps
512 flags(ctx ModuleContext, flags Flags) Flags
513 props() []interface{}
514}
515
516type compiler interface {
517 feature
Colin Cross76fada02016-07-27 10:31:13 -0700518 appendCflags([]string)
519 appendAsflags([]string)
Colin Cross635c3b02016-05-18 15:37:25 -0700520 compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800521}
522
523type linker interface {
524 feature
Colin Cross635c3b02016-05-18 15:37:25 -0700525 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles android.Paths) android.Path
Colin Cross76fada02016-07-27 10:31:13 -0700526 appendLdflags([]string)
Colin Crossc99deeb2016-04-11 15:06:20 -0700527 installable() bool
Colin Crossca860ac2016-01-04 14:34:37 -0800528}
529
530type installer interface {
531 props() []interface{}
Colin Cross635c3b02016-05-18 15:37:25 -0700532 install(ctx ModuleContext, path android.Path)
Colin Crossca860ac2016-01-04 14:34:37 -0800533 inData() bool
534}
535
Colin Crossc99deeb2016-04-11 15:06:20 -0700536type dependencyTag struct {
537 blueprint.BaseDependencyTag
538 name string
539 library bool
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700540
541 reexportFlags bool
Colin Crossc99deeb2016-04-11 15:06:20 -0700542}
543
544var (
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700545 sharedDepTag = dependencyTag{name: "shared", library: true}
546 sharedExportDepTag = dependencyTag{name: "shared", library: true, reexportFlags: true}
547 lateSharedDepTag = dependencyTag{name: "late shared", library: true}
548 staticDepTag = dependencyTag{name: "static", library: true}
549 staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
550 lateStaticDepTag = dependencyTag{name: "late static", library: true}
551 wholeStaticDepTag = dependencyTag{name: "whole static", library: true, reexportFlags: true}
552 genSourceDepTag = dependencyTag{name: "gen source"}
553 genHeaderDepTag = dependencyTag{name: "gen header"}
554 objDepTag = dependencyTag{name: "obj"}
555 crtBeginDepTag = dependencyTag{name: "crtbegin"}
556 crtEndDepTag = dependencyTag{name: "crtend"}
557 reuseObjTag = dependencyTag{name: "reuse objects"}
Colin Crossc99deeb2016-04-11 15:06:20 -0700558)
559
Colin Crossca860ac2016-01-04 14:34:37 -0800560// Module contains the properties and members used by all C/C++ module types, and implements
561// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
562// to construct the output file. Behavior can be customized with a Customizer interface
563type Module struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700564 android.ModuleBase
565 android.DefaultableModule
Colin Crossc472d572015-03-17 15:06:21 -0700566
Colin Crossca860ac2016-01-04 14:34:37 -0800567 Properties BaseProperties
568 unused UnusedProperties
Colin Crossfa138792015-04-24 17:31:52 -0700569
Colin Crossca860ac2016-01-04 14:34:37 -0800570 // initialize before calling Init
Colin Cross635c3b02016-05-18 15:37:25 -0700571 hod android.HostOrDeviceSupported
572 multilib android.Multilib
Colin Crossc472d572015-03-17 15:06:21 -0700573
Colin Crossca860ac2016-01-04 14:34:37 -0800574 // delegates, initialize before calling Init
Colin Cross76fada02016-07-27 10:31:13 -0700575 Customizer Customizer
Colin Crossca860ac2016-01-04 14:34:37 -0800576 features []feature
577 compiler compiler
578 linker linker
579 installer installer
Colin Crossa8e07cc2016-04-04 15:07:06 -0700580 stl *stl
Colin Cross16b23492016-01-06 14:41:07 -0800581 sanitize *sanitize
582
583 androidMkSharedLibDeps []string
Colin Cross74d1ec02015-04-28 13:30:13 -0700584
Colin Cross635c3b02016-05-18 15:37:25 -0700585 outputFile android.OptionalPath
Colin Crossca860ac2016-01-04 14:34:37 -0800586
587 cachedToolchain Toolchain
Colin Crossc472d572015-03-17 15:06:21 -0700588}
589
Colin Crossca860ac2016-01-04 14:34:37 -0800590func (c *Module) Init() (blueprint.Module, []interface{}) {
591 props := []interface{}{&c.Properties, &c.unused}
Colin Cross76fada02016-07-27 10:31:13 -0700592 if c.Customizer != nil {
593 props = append(props, c.Customizer.Properties()...)
Colin Crossca860ac2016-01-04 14:34:37 -0800594 }
595 if c.compiler != nil {
596 props = append(props, c.compiler.props()...)
597 }
598 if c.linker != nil {
599 props = append(props, c.linker.props()...)
600 }
601 if c.installer != nil {
602 props = append(props, c.installer.props()...)
603 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700604 if c.stl != nil {
605 props = append(props, c.stl.props()...)
606 }
Colin Cross16b23492016-01-06 14:41:07 -0800607 if c.sanitize != nil {
608 props = append(props, c.sanitize.props()...)
609 }
Colin Crossca860ac2016-01-04 14:34:37 -0800610 for _, feature := range c.features {
611 props = append(props, feature.props()...)
612 }
Colin Crossc472d572015-03-17 15:06:21 -0700613
Colin Cross635c3b02016-05-18 15:37:25 -0700614 _, props = android.InitAndroidArchModule(c, c.hod, c.multilib, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700615
Colin Cross635c3b02016-05-18 15:37:25 -0700616 return android.InitDefaultableModule(c, c, props...)
Colin Crossc472d572015-03-17 15:06:21 -0700617}
618
Colin Crossca860ac2016-01-04 14:34:37 -0800619type baseModuleContext struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700620 android.BaseContext
Colin Crossca860ac2016-01-04 14:34:37 -0800621 moduleContextImpl
622}
623
624type moduleContext struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700625 android.ModuleContext
Colin Crossca860ac2016-01-04 14:34:37 -0800626 moduleContextImpl
627}
628
629type moduleContextImpl struct {
630 mod *Module
631 ctx BaseModuleContext
632}
633
Colin Cross76fada02016-07-27 10:31:13 -0700634func (ctx *moduleContextImpl) AppendCflags(flags ...string) {
635 CheckBadCompilerFlags(ctx.ctx, "", flags)
636 ctx.mod.compiler.appendCflags(flags)
637}
638
639func (ctx *moduleContextImpl) AppendAsflags(flags ...string) {
640 CheckBadCompilerFlags(ctx.ctx, "", flags)
641 ctx.mod.compiler.appendAsflags(flags)
642}
643
644func (ctx *moduleContextImpl) AppendLdflags(flags ...string) {
645 CheckBadLinkerFlags(ctx.ctx, "", flags)
646 ctx.mod.linker.appendLdflags(flags)
647}
648
Colin Crossca860ac2016-01-04 14:34:37 -0800649func (ctx *moduleContextImpl) clang() bool {
650 return ctx.mod.clang(ctx.ctx)
651}
652
653func (ctx *moduleContextImpl) toolchain() Toolchain {
654 return ctx.mod.toolchain(ctx.ctx)
655}
656
657func (ctx *moduleContextImpl) static() bool {
658 if ctx.mod.linker == nil {
659 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
660 }
661 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
662 return linker.static()
663 } else {
664 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
665 }
666}
667
668func (ctx *moduleContextImpl) staticBinary() bool {
669 if ctx.mod.linker == nil {
670 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
671 }
672 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
673 return linker.staticBinary()
674 } else {
675 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
676 }
677}
678
679func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
680 return Bool(ctx.mod.Properties.No_default_compiler_flags)
681}
682
683func (ctx *moduleContextImpl) sdk() bool {
Dan Willemsena96ff642016-06-07 12:34:45 -0700684 if ctx.ctx.Device() {
685 return ctx.mod.Properties.Sdk_version != ""
686 }
687 return false
Colin Crossca860ac2016-01-04 14:34:37 -0800688}
689
690func (ctx *moduleContextImpl) sdkVersion() string {
Dan Willemsena96ff642016-06-07 12:34:45 -0700691 if ctx.ctx.Device() {
692 return ctx.mod.Properties.Sdk_version
693 }
694 return ""
Colin Crossca860ac2016-01-04 14:34:37 -0800695}
696
Dan Willemsen8146b2f2016-03-30 21:00:30 -0700697func (ctx *moduleContextImpl) selectedStl() string {
698 if stl := ctx.mod.stl; stl != nil {
699 return stl.Properties.SelectedStl
700 }
701 return ""
702}
703
Colin Cross635c3b02016-05-18 15:37:25 -0700704func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
Colin Crossca860ac2016-01-04 14:34:37 -0800705 return &Module{
706 hod: hod,
707 multilib: multilib,
708 }
709}
710
Colin Cross635c3b02016-05-18 15:37:25 -0700711func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
Colin Crossca860ac2016-01-04 14:34:37 -0800712 module := newBaseModule(hod, multilib)
Colin Crossa8e07cc2016-04-04 15:07:06 -0700713 module.stl = &stl{}
Colin Cross16b23492016-01-06 14:41:07 -0800714 module.sanitize = &sanitize{}
Colin Crossca860ac2016-01-04 14:34:37 -0800715 return module
716}
717
Colin Cross635c3b02016-05-18 15:37:25 -0700718func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800719 ctx := &moduleContext{
Colin Cross635c3b02016-05-18 15:37:25 -0700720 ModuleContext: actx,
Colin Crossca860ac2016-01-04 14:34:37 -0800721 moduleContextImpl: moduleContextImpl{
722 mod: c,
723 },
724 }
725 ctx.ctx = ctx
726
Colin Cross76fada02016-07-27 10:31:13 -0700727 if c.Customizer != nil {
728 c.Customizer.Flags(ctx)
729 }
730
Colin Crossca860ac2016-01-04 14:34:37 -0800731 flags := Flags{
732 Toolchain: c.toolchain(ctx),
733 Clang: c.clang(ctx),
734 }
Colin Crossca860ac2016-01-04 14:34:37 -0800735 if c.compiler != nil {
736 flags = c.compiler.flags(ctx, flags)
737 }
738 if c.linker != nil {
739 flags = c.linker.flags(ctx, flags)
740 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700741 if c.stl != nil {
742 flags = c.stl.flags(ctx, flags)
743 }
Colin Cross16b23492016-01-06 14:41:07 -0800744 if c.sanitize != nil {
745 flags = c.sanitize.flags(ctx, flags)
746 }
Colin Crossca860ac2016-01-04 14:34:37 -0800747 for _, feature := range c.features {
748 flags = feature.flags(ctx, flags)
749 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800750 if ctx.Failed() {
751 return
752 }
753
Colin Crossca860ac2016-01-04 14:34:37 -0800754 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
755 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
756 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -0800757
Colin Crossca860ac2016-01-04 14:34:37 -0800758 // Optimization to reduce size of build.ninja
759 // Replace the long list of flags for each file with a module-local variable
760 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
761 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
762 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
763 flags.CFlags = []string{"$cflags"}
764 flags.CppFlags = []string{"$cppflags"}
765 flags.AsFlags = []string{"$asflags"}
766
Colin Crossc99deeb2016-04-11 15:06:20 -0700767 deps := c.depsToPaths(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800768 if ctx.Failed() {
769 return
770 }
771
Dan Willemsen76f08272016-07-09 00:14:08 -0700772 flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)
Colin Crossed9f8682015-03-18 17:17:35 -0700773
Colin Cross635c3b02016-05-18 15:37:25 -0700774 var objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -0800775 if c.compiler != nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -0700776 objFiles = c.compiler.compile(ctx, flags, deps)
Colin Crossca860ac2016-01-04 14:34:37 -0800777 if ctx.Failed() {
778 return
779 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800780 }
781
Colin Crossca860ac2016-01-04 14:34:37 -0800782 if c.linker != nil {
783 outputFile := c.linker.link(ctx, flags, deps, objFiles)
784 if ctx.Failed() {
785 return
786 }
Colin Cross635c3b02016-05-18 15:37:25 -0700787 c.outputFile = android.OptionalPathForPath(outputFile)
Colin Cross5049f022015-03-18 13:28:46 -0700788
Colin Crossc99deeb2016-04-11 15:06:20 -0700789 if c.installer != nil && c.linker.installable() {
Colin Crossca860ac2016-01-04 14:34:37 -0800790 c.installer.install(ctx, outputFile)
791 if ctx.Failed() {
792 return
793 }
794 }
Dan Albertc403f7c2015-03-18 14:01:18 -0700795 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800796}
797
Colin Crossca860ac2016-01-04 14:34:37 -0800798func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
799 if c.cachedToolchain == nil {
800 arch := ctx.Arch()
Colin Crossa1ad8d12016-06-01 17:09:44 -0700801 os := ctx.Os()
802 factory := toolchainFactories[os][arch.ArchType]
Colin Crossca860ac2016-01-04 14:34:37 -0800803 if factory == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700804 ctx.ModuleErrorf("Toolchain not found for %s arch %q", os.String(), arch.String())
Colin Crossca860ac2016-01-04 14:34:37 -0800805 return nil
806 }
807 c.cachedToolchain = factory(arch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800808 }
Colin Crossca860ac2016-01-04 14:34:37 -0800809 return c.cachedToolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800810}
811
Colin Crossca860ac2016-01-04 14:34:37 -0800812func (c *Module) begin(ctx BaseModuleContext) {
813 if c.compiler != nil {
814 c.compiler.begin(ctx)
Colin Cross21b9a242015-03-24 14:15:58 -0700815 }
Colin Crossca860ac2016-01-04 14:34:37 -0800816 if c.linker != nil {
817 c.linker.begin(ctx)
818 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700819 if c.stl != nil {
820 c.stl.begin(ctx)
821 }
Colin Cross16b23492016-01-06 14:41:07 -0800822 if c.sanitize != nil {
823 c.sanitize.begin(ctx)
824 }
Colin Crossca860ac2016-01-04 14:34:37 -0800825 for _, feature := range c.features {
826 feature.begin(ctx)
827 }
828}
829
Colin Crossc99deeb2016-04-11 15:06:20 -0700830func (c *Module) deps(ctx BaseModuleContext) Deps {
831 deps := Deps{}
832
833 if c.compiler != nil {
834 deps = c.compiler.deps(ctx, deps)
835 }
836 if c.linker != nil {
837 deps = c.linker.deps(ctx, deps)
838 }
Colin Crossa8e07cc2016-04-04 15:07:06 -0700839 if c.stl != nil {
840 deps = c.stl.deps(ctx, deps)
841 }
Colin Cross16b23492016-01-06 14:41:07 -0800842 if c.sanitize != nil {
843 deps = c.sanitize.deps(ctx, deps)
844 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700845 for _, feature := range c.features {
846 deps = feature.deps(ctx, deps)
847 }
848
849 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs)
850 deps.StaticLibs = lastUniqueElements(deps.StaticLibs)
851 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs)
852 deps.SharedLibs = lastUniqueElements(deps.SharedLibs)
853 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs)
854
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700855 for _, lib := range deps.ReexportSharedLibHeaders {
856 if !inList(lib, deps.SharedLibs) {
857 ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib)
858 }
859 }
860
861 for _, lib := range deps.ReexportStaticLibHeaders {
862 if !inList(lib, deps.StaticLibs) {
863 ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs: '%s'", lib)
864 }
865 }
866
Colin Crossc99deeb2016-04-11 15:06:20 -0700867 return deps
868}
869
Colin Cross635c3b02016-05-18 15:37:25 -0700870func (c *Module) depsMutator(actx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -0800871 ctx := &baseModuleContext{
Colin Cross635c3b02016-05-18 15:37:25 -0700872 BaseContext: actx,
Colin Crossca860ac2016-01-04 14:34:37 -0800873 moduleContextImpl: moduleContextImpl{
874 mod: c,
875 },
876 }
877 ctx.ctx = ctx
878
Colin Crossca860ac2016-01-04 14:34:37 -0800879 c.begin(ctx)
880
Colin Crossc99deeb2016-04-11 15:06:20 -0700881 deps := c.deps(ctx)
Colin Crossca860ac2016-01-04 14:34:37 -0800882
Colin Crossb5bc4b42016-07-11 16:11:59 -0700883 c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.SharedLibs...)
884 c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.LateSharedLibs...)
Dan Willemsen72d39932016-07-08 23:23:48 -0700885
886 if ctx.sdk() {
887 version := "." + ctx.sdkVersion()
888
889 rewriteNdkLibs := func(list []string) []string {
890 for i, entry := range list {
891 if inList(entry, ndkPrebuiltSharedLibraries) {
892 list[i] = "ndk_" + entry + version
893 }
894 }
895 return list
896 }
897
898 deps.SharedLibs = rewriteNdkLibs(deps.SharedLibs)
899 deps.LateSharedLibs = rewriteNdkLibs(deps.LateSharedLibs)
900 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700901
902 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag,
903 deps.WholeStaticLibs...)
904
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700905 for _, lib := range deps.StaticLibs {
906 depTag := staticDepTag
907 if inList(lib, deps.ReexportStaticLibHeaders) {
908 depTag = staticExportDepTag
909 }
Colin Cross15a0d462016-07-14 14:49:58 -0700910 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, depTag, lib)
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700911 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700912
913 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag,
914 deps.LateStaticLibs...)
915
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700916 for _, lib := range deps.SharedLibs {
917 depTag := sharedDepTag
918 if inList(lib, deps.ReexportSharedLibHeaders) {
919 depTag = sharedExportDepTag
920 }
Colin Cross15a0d462016-07-14 14:49:58 -0700921 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, depTag, lib)
Dan Willemsen490a8dc2016-06-06 18:22:19 -0700922 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700923
924 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
925 deps.LateSharedLibs...)
926
Colin Cross68861832016-07-08 10:41:41 -0700927 actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
928 actx.AddDependency(c, genHeaderDepTag, deps.GeneratedHeaders...)
Dan Willemsenb40aab62016-04-20 14:21:14 -0700929
Colin Cross68861832016-07-08 10:41:41 -0700930 actx.AddDependency(c, objDepTag, deps.ObjFiles...)
Colin Crossc99deeb2016-04-11 15:06:20 -0700931
932 if deps.CrtBegin != "" {
Colin Cross68861832016-07-08 10:41:41 -0700933 actx.AddDependency(c, crtBeginDepTag, deps.CrtBegin)
Colin Crossca860ac2016-01-04 14:34:37 -0800934 }
Colin Crossc99deeb2016-04-11 15:06:20 -0700935 if deps.CrtEnd != "" {
Colin Cross68861832016-07-08 10:41:41 -0700936 actx.AddDependency(c, crtEndDepTag, deps.CrtEnd)
Colin Cross21b9a242015-03-24 14:15:58 -0700937 }
Colin Cross6362e272015-10-29 15:25:03 -0700938}
Colin Cross21b9a242015-03-24 14:15:58 -0700939
Colin Cross635c3b02016-05-18 15:37:25 -0700940func depsMutator(ctx android.BottomUpMutatorContext) {
Dan Willemsen3f32f032016-07-11 14:36:48 -0700941 if c, ok := ctx.Module().(*Module); ok && c.Enabled() {
Colin Cross6362e272015-10-29 15:25:03 -0700942 c.depsMutator(ctx)
943 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800944}
945
Colin Crossca860ac2016-01-04 14:34:37 -0800946func (c *Module) clang(ctx BaseModuleContext) bool {
947 clang := Bool(c.Properties.Clang)
948
949 if c.Properties.Clang == nil {
950 if ctx.Host() {
951 clang = true
952 }
953
954 if ctx.Device() && ctx.AConfig().DeviceUsesClang() {
955 clang = true
956 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800957 }
Colin Cross28344522015-04-22 13:07:53 -0700958
Colin Crossca860ac2016-01-04 14:34:37 -0800959 if !c.toolchain(ctx).ClangSupported() {
960 clang = false
961 }
962
963 return clang
964}
965
Colin Crossc99deeb2016-04-11 15:06:20 -0700966// Convert dependencies to paths. Returns a PathDeps containing paths
Colin Cross635c3b02016-05-18 15:37:25 -0700967func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
Colin Crossca860ac2016-01-04 14:34:37 -0800968 var depPaths PathDeps
Colin Crossca860ac2016-01-04 14:34:37 -0800969
Dan Willemsena96ff642016-06-07 12:34:45 -0700970 // Whether a module can link to another module, taking into
971 // account NDK linking.
972 linkTypeOk := func(from, to *Module) bool {
973 if from.Target().Os != android.Android {
974 // Host code is not restricted
975 return true
976 }
977 if from.Properties.Sdk_version == "" {
978 // Platform code can link to anything
979 return true
980 }
981 if _, ok := to.linker.(*toolchainLibraryLinker); ok {
982 // These are always allowed
983 return true
984 }
985 if _, ok := to.linker.(*ndkPrebuiltLibraryLinker); ok {
986 // These are allowed, but don't set sdk_version
987 return true
988 }
Dan Willemsen3c316bc2016-07-07 20:41:36 -0700989 if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok {
990 // These are allowed, but don't set sdk_version
991 return true
992 }
993 return to.Properties.Sdk_version != ""
Dan Willemsena96ff642016-06-07 12:34:45 -0700994 }
995
Colin Crossc99deeb2016-04-11 15:06:20 -0700996 ctx.VisitDirectDeps(func(m blueprint.Module) {
997 name := ctx.OtherModuleName(m)
998 tag := ctx.OtherModuleDependencyTag(m)
Colin Crossca860ac2016-01-04 14:34:37 -0800999
Colin Cross635c3b02016-05-18 15:37:25 -07001000 a, _ := m.(android.Module)
Colin Crossc99deeb2016-04-11 15:06:20 -07001001 if a == nil {
1002 ctx.ModuleErrorf("module %q not an android module", name)
1003 return
Colin Crossca860ac2016-01-04 14:34:37 -08001004 }
Colin Crossca860ac2016-01-04 14:34:37 -08001005
Dan Willemsena96ff642016-06-07 12:34:45 -07001006 cc, _ := m.(*Module)
1007 if cc == nil {
Dan Willemsenb40aab62016-04-20 14:21:14 -07001008 switch tag {
Colin Cross635c3b02016-05-18 15:37:25 -07001009 case android.DefaultsDepTag:
Dan Willemsenb40aab62016-04-20 14:21:14 -07001010 case genSourceDepTag:
1011 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
1012 depPaths.GeneratedSources = append(depPaths.GeneratedSources,
1013 genRule.GeneratedSourceFiles()...)
1014 } else {
1015 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
1016 }
1017 case genHeaderDepTag:
1018 if genRule, ok := m.(genrule.SourceFileGenerator); ok {
1019 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
1020 genRule.GeneratedSourceFiles()...)
Dan Willemsen76f08272016-07-09 00:14:08 -07001021 depPaths.Flags = append(depPaths.Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07001022 includeDirsToFlags(android.Paths{genRule.GeneratedHeaderDir()}))
Dan Willemsenb40aab62016-04-20 14:21:14 -07001023 } else {
1024 ctx.ModuleErrorf("module %q is not a genrule", name)
1025 }
1026 default:
Colin Crossc99deeb2016-04-11 15:06:20 -07001027 ctx.ModuleErrorf("depends on non-cc module %q", name)
Colin Crossca860ac2016-01-04 14:34:37 -08001028 }
Colin Crossc99deeb2016-04-11 15:06:20 -07001029 return
1030 }
1031
1032 if !a.Enabled() {
1033 ctx.ModuleErrorf("depends on disabled module %q", name)
1034 return
1035 }
1036
Colin Crossa1ad8d12016-06-01 17:09:44 -07001037 if a.Target().Os != ctx.Os() {
1038 ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), name)
1039 return
1040 }
1041
1042 if a.Target().Arch.ArchType != ctx.Arch().ArchType {
1043 ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), name)
Colin Crossc99deeb2016-04-11 15:06:20 -07001044 return
1045 }
1046
Dan Willemsena96ff642016-06-07 12:34:45 -07001047 if !cc.outputFile.Valid() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001048 ctx.ModuleErrorf("module %q missing output file", name)
1049 return
1050 }
1051
1052 if tag == reuseObjTag {
1053 depPaths.ObjFiles = append(depPaths.ObjFiles,
Dan Willemsena96ff642016-06-07 12:34:45 -07001054 cc.compiler.(*libraryCompiler).reuseObjFiles...)
Colin Crossc99deeb2016-04-11 15:06:20 -07001055 return
1056 }
1057
Dan Willemsen490a8dc2016-06-06 18:22:19 -07001058 if t, ok := tag.(dependencyTag); ok && t.library {
Dan Willemsena96ff642016-06-07 12:34:45 -07001059 if i, ok := cc.linker.(exportedFlagsProducer); ok {
Dan Willemsen76f08272016-07-09 00:14:08 -07001060 flags := i.exportedFlags()
1061 depPaths.Flags = append(depPaths.Flags, flags...)
Dan Willemsen490a8dc2016-06-06 18:22:19 -07001062
1063 if t.reexportFlags {
Dan Willemsen76f08272016-07-09 00:14:08 -07001064 depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
Dan Willemsen490a8dc2016-06-06 18:22:19 -07001065 }
Colin Crossc99deeb2016-04-11 15:06:20 -07001066 }
Dan Willemsena96ff642016-06-07 12:34:45 -07001067
1068 if !linkTypeOk(c, cc) {
1069 ctx.ModuleErrorf("depends on non-NDK-built library %q", name)
1070 }
Colin Crossc99deeb2016-04-11 15:06:20 -07001071 }
1072
Colin Cross635c3b02016-05-18 15:37:25 -07001073 var depPtr *android.Paths
Colin Crossc99deeb2016-04-11 15:06:20 -07001074
1075 switch tag {
Dan Willemsen490a8dc2016-06-06 18:22:19 -07001076 case sharedDepTag, sharedExportDepTag:
Colin Crossc99deeb2016-04-11 15:06:20 -07001077 depPtr = &depPaths.SharedLibs
1078 case lateSharedDepTag:
1079 depPtr = &depPaths.LateSharedLibs
Dan Willemsen490a8dc2016-06-06 18:22:19 -07001080 case staticDepTag, staticExportDepTag:
Colin Crossc99deeb2016-04-11 15:06:20 -07001081 depPtr = &depPaths.StaticLibs
1082 case lateStaticDepTag:
1083 depPtr = &depPaths.LateStaticLibs
1084 case wholeStaticDepTag:
1085 depPtr = &depPaths.WholeStaticLibs
Colin Crossc7a38dc2016-07-12 13:13:09 -07001086 staticLib, _ := cc.linker.(libraryInterface)
Colin Crossc99deeb2016-04-11 15:06:20 -07001087 if staticLib == nil || !staticLib.static() {
Dan Willemsena96ff642016-06-07 12:34:45 -07001088 ctx.ModuleErrorf("module %q not a static library", name)
Colin Crossc99deeb2016-04-11 15:06:20 -07001089 return
1090 }
1091
1092 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
1093 postfix := " (required by " + ctx.OtherModuleName(m) + ")"
1094 for i := range missingDeps {
1095 missingDeps[i] += postfix
1096 }
1097 ctx.AddMissingDependencies(missingDeps)
1098 }
1099 depPaths.WholeStaticLibObjFiles =
Colin Crossc7a38dc2016-07-12 13:13:09 -07001100 append(depPaths.WholeStaticLibObjFiles, staticLib.objs()...)
Colin Crossc99deeb2016-04-11 15:06:20 -07001101 case objDepTag:
1102 depPtr = &depPaths.ObjFiles
1103 case crtBeginDepTag:
Dan Willemsena96ff642016-06-07 12:34:45 -07001104 depPaths.CrtBegin = cc.outputFile
Colin Crossc99deeb2016-04-11 15:06:20 -07001105 case crtEndDepTag:
Dan Willemsena96ff642016-06-07 12:34:45 -07001106 depPaths.CrtEnd = cc.outputFile
Colin Crossc99deeb2016-04-11 15:06:20 -07001107 default:
Dan Willemsen490a8dc2016-06-06 18:22:19 -07001108 panic(fmt.Errorf("unknown dependency tag: %s", tag))
Colin Crossc99deeb2016-04-11 15:06:20 -07001109 }
1110
1111 if depPtr != nil {
Dan Willemsena96ff642016-06-07 12:34:45 -07001112 *depPtr = append(*depPtr, cc.outputFile.Path())
Colin Crossca860ac2016-01-04 14:34:37 -08001113 }
1114 })
1115
1116 return depPaths
1117}
1118
1119func (c *Module) InstallInData() bool {
1120 if c.installer == nil {
1121 return false
1122 }
1123 return c.installer.inData()
1124}
1125
1126// Compiler
1127
1128type baseCompiler struct {
1129 Properties BaseCompilerProperties
1130}
1131
1132var _ compiler = (*baseCompiler)(nil)
1133
Colin Cross76fada02016-07-27 10:31:13 -07001134func (compiler *baseCompiler) appendCflags(flags []string) {
1135 compiler.Properties.Cflags = append(compiler.Properties.Cflags, flags...)
1136}
1137
1138func (compiler *baseCompiler) appendAsflags(flags []string) {
1139 compiler.Properties.Asflags = append(compiler.Properties.Asflags, flags...)
1140}
1141
Colin Crossca860ac2016-01-04 14:34:37 -08001142func (compiler *baseCompiler) props() []interface{} {
1143 return []interface{}{&compiler.Properties}
1144}
1145
Dan Willemsenb40aab62016-04-20 14:21:14 -07001146func (compiler *baseCompiler) begin(ctx BaseModuleContext) {}
1147
1148func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps {
1149 deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
1150 deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
1151
1152 return deps
1153}
Colin Crossca860ac2016-01-04 14:34:37 -08001154
1155// Create a Flags struct that collects the compile flags from global values,
1156// per-target values, module type values, and per-module Blueprints properties
1157func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1158 toolchain := ctx.toolchain()
1159
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001160 CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
1161 CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
1162 CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
1163 CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
1164
Colin Crossca860ac2016-01-04 14:34:37 -08001165 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...)
1166 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...)
1167 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...)
1168 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...)
1169 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...)
1170
Colin Cross28344522015-04-22 13:07:53 -07001171 // Include dir cflags
Colin Cross635c3b02016-05-18 15:37:25 -07001172 rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
1173 localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
Colin Cross28344522015-04-22 13:07:53 -07001174 flags.GlobalFlags = append(flags.GlobalFlags,
Dan Willemsen1e898b92015-09-23 15:26:32 -07001175 includeDirsToFlags(localIncludeDirs),
1176 includeDirsToFlags(rootIncludeDirs))
Colin Cross28344522015-04-22 13:07:53 -07001177
Colin Crossca860ac2016-01-04 14:34:37 -08001178 if !ctx.noDefaultCompilerFlags() {
1179 if !ctx.sdk() || ctx.Host() {
Colin Cross28344522015-04-22 13:07:53 -07001180 flags.GlobalFlags = append(flags.GlobalFlags,
1181 "${commonGlobalIncludes}",
1182 toolchain.IncludeFlags(),
Dan Willemsene0378dd2016-01-07 17:42:34 -08001183 "${commonNativehelperInclude}")
Colin Cross28344522015-04-22 13:07:53 -07001184 }
1185
1186 flags.GlobalFlags = append(flags.GlobalFlags, []string{
Colin Cross635c3b02016-05-18 15:37:25 -07001187 "-I" + android.PathForModuleSrc(ctx).String(),
1188 "-I" + android.PathForModuleOut(ctx).String(),
1189 "-I" + android.PathForModuleGen(ctx).String(),
Colin Cross28344522015-04-22 13:07:53 -07001190 }...)
1191 }
1192
Colin Crossca860ac2016-01-04 14:34:37 -08001193 instructionSet := compiler.Properties.Instruction_set
1194 if flags.RequiredInstructionSet != "" {
1195 instructionSet = flags.RequiredInstructionSet
Colin Cross3f40fa42015-01-30 17:27:36 -08001196 }
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001197 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
1198 if flags.Clang {
1199 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
1200 }
1201 if err != nil {
1202 ctx.ModuleErrorf("%s", err)
1203 }
1204
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001205 CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags)
1206
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001207 // TODO: debug
Colin Crossca860ac2016-01-04 14:34:37 -08001208 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...)
Dan Willemsen6d11dd82015-11-03 14:27:00 -08001209
Colin Cross97ba0732015-03-23 17:50:24 -07001210 if flags.Clang {
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001211 CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
1212 CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
1213
Colin Cross97ba0732015-03-23 17:50:24 -07001214 flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001215 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
1216 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
Colin Cross97ba0732015-03-23 17:50:24 -07001217 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
1218 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
1219 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001220
1221 target := "-target " + toolchain.ClangTriple()
Dan Willemsen3772da12016-05-16 18:01:46 -07001222 var gccPrefix string
1223 if !ctx.Darwin() {
1224 gccPrefix = "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
1225 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001226
Colin Cross97ba0732015-03-23 17:50:24 -07001227 flags.CFlags = append(flags.CFlags, target, gccPrefix)
1228 flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
1229 flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
Colin Cross3f40fa42015-01-30 17:27:36 -08001230 }
1231
Colin Crossa1ad8d12016-06-01 17:09:44 -07001232 hod := "host"
1233 if ctx.Os().Class == android.Device {
1234 hod = "device"
1235 }
1236
Colin Crossca860ac2016-01-04 14:34:37 -08001237 if !ctx.noDefaultCompilerFlags() {
Colin Cross56b4d452015-04-21 17:38:44 -07001238 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
1239
Colin Cross97ba0732015-03-23 17:50:24 -07001240 if flags.Clang {
Dan Willemsen32968a22016-01-12 22:25:34 -08001241 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
Colin Cross97ba0732015-03-23 17:50:24 -07001242 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001243 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001244 toolchain.ClangCflags(),
1245 "${commonClangGlobalCflags}",
Colin Crossa1ad8d12016-06-01 17:09:44 -07001246 fmt.Sprintf("${%sClangGlobalCflags}", hod))
Dan Willemsenac5e1cb2016-01-12 16:22:40 -08001247
1248 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
Colin Cross3f40fa42015-01-30 17:27:36 -08001249 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001250 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
Colin Cross56b4d452015-04-21 17:38:44 -07001251 flags.GlobalFlags = append(flags.GlobalFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -08001252 toolchain.Cflags(),
1253 "${commonGlobalCflags}",
Colin Crossa1ad8d12016-06-01 17:09:44 -07001254 fmt.Sprintf("${%sGlobalCflags}", hod))
Colin Cross3f40fa42015-01-30 17:27:36 -08001255 }
1256
Colin Cross7b66f152015-12-15 16:07:43 -08001257 if Bool(ctx.AConfig().ProductVariables.Brillo) {
1258 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__")
1259 }
1260
Colin Crossf6566ed2015-03-24 11:13:38 -07001261 if ctx.Device() {
Colin Crossca860ac2016-01-04 14:34:37 -08001262 if Bool(compiler.Properties.Rtti) {
Colin Cross97ba0732015-03-23 17:50:24 -07001263 flags.CppFlags = append(flags.CppFlags, "-frtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001264 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001265 flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
Colin Cross3f40fa42015-01-30 17:27:36 -08001266 }
1267 }
1268
Colin Cross97ba0732015-03-23 17:50:24 -07001269 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
Colin Cross3f40fa42015-01-30 17:27:36 -08001270
Colin Cross97ba0732015-03-23 17:50:24 -07001271 if flags.Clang {
1272 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
Colin Cross3f40fa42015-01-30 17:27:36 -08001273 } else {
Colin Cross97ba0732015-03-23 17:50:24 -07001274 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
Colin Cross28344522015-04-22 13:07:53 -07001275 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001276 }
1277
Colin Crossc4bde762015-11-23 16:11:30 -08001278 if flags.Clang {
1279 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
1280 } else {
1281 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
Colin Crossc4bde762015-11-23 16:11:30 -08001282 }
1283
Colin Crossca860ac2016-01-04 14:34:37 -08001284 if !ctx.sdk() {
Dan Willemsen3bf6b472015-09-11 17:41:10 -07001285 if ctx.Host() && !flags.Clang {
1286 // The host GCC doesn't support C++14 (and is deprecated, so likely
1287 // never will). Build these modules with C++11.
1288 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
1289 } else {
1290 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
1291 }
1292 }
1293
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001294 // We can enforce some rules more strictly in the code we own. strict
1295 // indicates if this is code that we can be stricter with. If we have
1296 // rules that we want to apply to *our* code (but maybe can't for
1297 // vendor/device specific things), we could extend this to be a ternary
1298 // value.
1299 strict := true
Colin Cross635c3b02016-05-18 15:37:25 -07001300 if strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "external/") {
Dan Willemsen52b1cd22016-03-01 13:36:34 -08001301 strict = false
1302 }
1303
1304 // Can be used to make some annotations stricter for code we can fix
1305 // (such as when we mark functions as deprecated).
1306 if strict {
1307 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
1308 }
1309
Colin Cross3f40fa42015-01-30 17:27:36 -08001310 return flags
1311}
1312
Colin Cross635c3b02016-05-18 15:37:25 -07001313func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
Colin Crossca860ac2016-01-04 14:34:37 -08001314 // Compile files listed in c.Properties.Srcs into objects
Dan Willemsenb40aab62016-04-20 14:21:14 -07001315 objFiles := compiler.compileObjs(ctx, flags, "",
1316 compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
1317 deps.GeneratedSources, deps.GeneratedHeaders)
1318
Colin Crossca860ac2016-01-04 14:34:37 -08001319 if ctx.Failed() {
1320 return nil
1321 }
1322
Colin Crossca860ac2016-01-04 14:34:37 -08001323 return objFiles
Colin Cross3f40fa42015-01-30 17:27:36 -08001324}
1325
1326// Compile a list of source files into objects a specified subdirectory
Colin Cross635c3b02016-05-18 15:37:25 -07001327func (compiler *baseCompiler) compileObjs(ctx android.ModuleContext, flags Flags,
1328 subdir string, srcFiles, excludes []string, extraSrcs, deps android.Paths) android.Paths {
Colin Cross581c1892015-04-07 16:50:10 -07001329
Colin Crossca860ac2016-01-04 14:34:37 -08001330 buildFlags := flagsToBuilderFlags(flags)
Colin Cross3f40fa42015-01-30 17:27:36 -08001331
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001332 inputFiles := ctx.ExpandSources(srcFiles, excludes)
Dan Willemsenb40aab62016-04-20 14:21:14 -07001333 inputFiles = append(inputFiles, extraSrcs...)
1334 srcPaths, gendeps := genSources(ctx, inputFiles, buildFlags)
1335
1336 deps = append(deps, gendeps...)
Colin Cross16b23492016-01-06 14:41:07 -08001337 deps = append(deps, flags.CFlagsDeps...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001338
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001339 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
Colin Cross3f40fa42015-01-30 17:27:36 -08001340}
1341
Colin Crossca860ac2016-01-04 14:34:37 -08001342// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
1343type baseLinker struct {
1344 Properties BaseLinkerProperties
1345 dynamicProperties struct {
Colin Crossc99deeb2016-04-11 15:06:20 -07001346 VariantIsShared bool `blueprint:"mutated"`
1347 VariantIsStatic bool `blueprint:"mutated"`
1348 VariantIsStaticBinary bool `blueprint:"mutated"`
1349 RunPaths []string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -08001350 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001351}
1352
Colin Cross76fada02016-07-27 10:31:13 -07001353func (linker *baseLinker) appendLdflags(flags []string) {
1354 linker.Properties.Ldflags = append(linker.Properties.Ldflags, flags...)
1355}
1356
Dan Willemsend30e6102016-03-30 17:35:50 -07001357func (linker *baseLinker) begin(ctx BaseModuleContext) {
1358 if ctx.toolchain().Is64Bit() {
Colin Crossc99deeb2016-04-11 15:06:20 -07001359 linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001360 } else {
Colin Crossc99deeb2016-04-11 15:06:20 -07001361 linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
Dan Willemsend30e6102016-03-30 17:35:50 -07001362 }
1363}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001364
Colin Crossca860ac2016-01-04 14:34:37 -08001365func (linker *baseLinker) props() []interface{} {
1366 return []interface{}{&linker.Properties, &linker.dynamicProperties}
Colin Crossed4cf0b2015-03-26 14:43:45 -07001367}
1368
Colin Crossca860ac2016-01-04 14:34:37 -08001369func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1370 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
1371 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
1372 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001373
Dan Willemsen490a8dc2016-06-06 18:22:19 -07001374 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, linker.Properties.Export_static_lib_headers...)
1375 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, linker.Properties.Export_shared_lib_headers...)
1376
Dan Willemsena96ff642016-06-07 12:34:45 -07001377 if !ctx.sdk() && ctx.ModuleName() != "libcompiler_rt-extras" {
Stephen Hines10347862016-07-18 15:54:54 -07001378 deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt-extras")
Colin Cross74d1ec02015-04-28 13:30:13 -07001379 }
1380
Colin Crossf6566ed2015-03-24 11:13:38 -07001381 if ctx.Device() {
Colin Cross77b00fa2015-03-16 16:15:49 -07001382 // libgcc and libatomic have to be last on the command line
Colin Crossca860ac2016-01-04 14:34:37 -08001383 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
1384 if !Bool(linker.Properties.No_libgcc) {
1385 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
Dan Willemsend67be222015-09-16 15:19:33 -07001386 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001387
Colin Crossca860ac2016-01-04 14:34:37 -08001388 if !linker.static() {
1389 if linker.Properties.System_shared_libs != nil {
1390 deps.LateSharedLibs = append(deps.LateSharedLibs,
1391 linker.Properties.System_shared_libs...)
1392 } else if !ctx.sdk() {
1393 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm")
1394 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07001395 }
Colin Cross577f6e42015-03-27 18:23:34 -07001396
Colin Crossca860ac2016-01-04 14:34:37 -08001397 if ctx.sdk() {
Colin Crossca860ac2016-01-04 14:34:37 -08001398 deps.SharedLibs = append(deps.SharedLibs,
Dan Willemsen97704ed2016-07-07 21:40:39 -07001399 "libc",
1400 "libm",
Colin Cross577f6e42015-03-27 18:23:34 -07001401 )
1402 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001403 }
1404
Colin Crossca860ac2016-01-04 14:34:37 -08001405 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001406}
1407
Colin Crossca860ac2016-01-04 14:34:37 -08001408func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags {
1409 toolchain := ctx.toolchain()
1410
Colin Crossa89d2e12016-01-11 12:48:37 -08001411 flags.Nocrt = Bool(linker.Properties.Nocrt)
1412
Colin Crossca860ac2016-01-04 14:34:37 -08001413 if !ctx.noDefaultCompilerFlags() {
1414 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) {
1415 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
1416 }
1417
1418 if flags.Clang {
1419 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
1420 } else {
1421 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
1422 }
1423
1424 if ctx.Host() {
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001425 CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)
1426
Colin Crossca860ac2016-01-04 14:34:37 -08001427 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...)
1428 }
1429 }
1430
Dan Willemsen20acc5c2016-05-25 14:47:21 -07001431 CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)
1432
Dan Willemsen00ced762016-05-10 17:31:21 -07001433 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
1434
Dan Willemsend30e6102016-03-30 17:35:50 -07001435 if ctx.Host() && !linker.static() {
1436 rpath_prefix := `\$$ORIGIN/`
1437 if ctx.Darwin() {
1438 rpath_prefix = "@loader_path/"
1439 }
1440
Colin Crossc99deeb2016-04-11 15:06:20 -07001441 for _, rpath := range linker.dynamicProperties.RunPaths {
Dan Willemsend30e6102016-03-30 17:35:50 -07001442 flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
1443 }
1444 }
1445
Dan Willemsene7174922016-03-30 17:33:52 -07001446 if flags.Clang {
1447 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags())
1448 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001449 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags())
1450 }
1451
1452 return flags
1453}
1454
1455func (linker *baseLinker) static() bool {
1456 return linker.dynamicProperties.VariantIsStatic
1457}
1458
1459func (linker *baseLinker) staticBinary() bool {
1460 return linker.dynamicProperties.VariantIsStaticBinary
1461}
1462
1463func (linker *baseLinker) setStatic(static bool) {
1464 linker.dynamicProperties.VariantIsStatic = static
1465}
1466
Colin Cross16b23492016-01-06 14:41:07 -08001467func (linker *baseLinker) isDependencyRoot() bool {
1468 return false
1469}
1470
Colin Crossca860ac2016-01-04 14:34:37 -08001471type baseLinkerInterface interface {
Colin Crossed4cf0b2015-03-26 14:43:45 -07001472 // Returns true if the build options for the module have selected a static or shared build
1473 buildStatic() bool
1474 buildShared() bool
1475
1476 // Sets whether a specific variant is static or shared
Colin Cross18b6dc52015-04-28 13:20:37 -07001477 setStatic(bool)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001478
Colin Cross18b6dc52015-04-28 13:20:37 -07001479 // Returns whether a specific variant is a static library or binary
Colin Crossed4cf0b2015-03-26 14:43:45 -07001480 static() bool
Colin Cross18b6dc52015-04-28 13:20:37 -07001481
1482 // Returns whether a module is a static binary
1483 staticBinary() bool
Colin Cross16b23492016-01-06 14:41:07 -08001484
1485 // Returns true for dependency roots (binaries)
1486 // TODO(ccross): also handle dlopenable libraries
1487 isDependencyRoot() bool
Colin Crossed4cf0b2015-03-26 14:43:45 -07001488}
1489
Colin Crossca860ac2016-01-04 14:34:37 -08001490type baseInstaller struct {
1491 Properties InstallerProperties
1492
1493 dir string
1494 dir64 string
1495 data bool
1496
Colin Cross635c3b02016-05-18 15:37:25 -07001497 path android.OutputPath
Colin Crossca860ac2016-01-04 14:34:37 -08001498}
1499
1500var _ installer = (*baseInstaller)(nil)
1501
1502func (installer *baseInstaller) props() []interface{} {
1503 return []interface{}{&installer.Properties}
1504}
1505
Colin Cross635c3b02016-05-18 15:37:25 -07001506func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08001507 subDir := installer.dir
1508 if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
1509 subDir = installer.dir64
1510 }
Dan Willemsen17f05262016-05-31 16:27:00 -07001511 if !ctx.Host() && !ctx.Arch().Native {
1512 subDir = filepath.Join(subDir, ctx.Arch().ArchType.String())
1513 }
Colin Cross635c3b02016-05-18 15:37:25 -07001514 dir := android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path)
Colin Crossca860ac2016-01-04 14:34:37 -08001515 installer.path = ctx.InstallFile(dir, file)
Colin Cross3854a602016-01-11 12:49:11 -08001516 for _, symlink := range installer.Properties.Symlinks {
1517 ctx.InstallSymlink(dir, symlink, installer.path)
1518 }
Colin Crossca860ac2016-01-04 14:34:37 -08001519}
1520
1521func (installer *baseInstaller) inData() bool {
1522 return installer.data
1523}
1524
Colin Cross3f40fa42015-01-30 17:27:36 -08001525//
1526// Combined static+shared libraries
1527//
1528
Colin Cross919281a2016-04-05 16:42:05 -07001529type flagExporter struct {
1530 Properties FlagExporterProperties
1531
1532 flags []string
1533}
1534
1535func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
Colin Cross635c3b02016-05-18 15:37:25 -07001536 includeDirs := android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
Dan Willemsene6c7f182016-07-13 10:45:01 -07001537 for _, dir := range includeDirs.Strings() {
Colin Crossf87b2612016-07-13 18:55:43 -07001538 f.flags = append(f.flags, inc+dir)
Dan Willemsene6c7f182016-07-13 10:45:01 -07001539 }
Colin Cross919281a2016-04-05 16:42:05 -07001540}
1541
1542func (f *flagExporter) reexportFlags(flags []string) {
1543 f.flags = append(f.flags, flags...)
1544}
1545
1546func (f *flagExporter) exportedFlags() []string {
1547 return f.flags
1548}
1549
1550type exportedFlagsProducer interface {
1551 exportedFlags() []string
1552}
1553
1554var _ exportedFlagsProducer = (*flagExporter)(nil)
1555
Colin Crossca860ac2016-01-04 14:34:37 -08001556type libraryCompiler struct {
1557 baseCompiler
Colin Crossaee540a2015-07-06 17:48:31 -07001558
Colin Crossca860ac2016-01-04 14:34:37 -08001559 linker *libraryLinker
1560 Properties LibraryCompilerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001561
Colin Crossca860ac2016-01-04 14:34:37 -08001562 // For reusing static library objects for shared library
Colin Cross635c3b02016-05-18 15:37:25 -07001563 reuseObjFiles android.Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001564}
1565
Colin Crossca860ac2016-01-04 14:34:37 -08001566var _ compiler = (*libraryCompiler)(nil)
1567
1568func (library *libraryCompiler) props() []interface{} {
1569 props := library.baseCompiler.props()
1570 return append(props, &library.Properties)
Colin Crossed4cf0b2015-03-26 14:43:45 -07001571}
1572
Colin Crossca860ac2016-01-04 14:34:37 -08001573func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags {
1574 flags = library.baseCompiler.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07001575
Dan Willemsen490fd492015-11-24 17:53:15 -08001576 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
1577 // all code is position independent, and then those warnings get promoted to
1578 // errors.
Colin Crossa1ad8d12016-06-01 17:09:44 -07001579 if ctx.Os() != android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08001580 flags.CFlags = append(flags.CFlags, "-fPIC")
1581 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001582
Colin Crossca860ac2016-01-04 14:34:37 -08001583 if library.linker.static() {
1584 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001585 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001586 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
Colin Crossd8e780d2015-04-28 17:39:43 -07001587 }
1588
Colin Crossca860ac2016-01-04 14:34:37 -08001589 return flags
1590}
1591
Colin Cross635c3b02016-05-18 15:37:25 -07001592func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
1593 var objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -08001594
Dan Willemsenb40aab62016-04-20 14:21:14 -07001595 objFiles = library.baseCompiler.compile(ctx, flags, deps)
Colin Crossc99deeb2016-04-11 15:06:20 -07001596 library.reuseObjFiles = objFiles
Colin Crossca860ac2016-01-04 14:34:37 -08001597
1598 if library.linker.static() {
Colin Cross635c3b02016-05-18 15:37:25 -07001599 objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceStaticLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001600 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
1601 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001602 } else {
Colin Cross635c3b02016-05-18 15:37:25 -07001603 objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceSharedLibrary,
Dan Willemsenb40aab62016-04-20 14:21:14 -07001604 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
1605 nil, deps.GeneratedHeaders)...)
Colin Crossca860ac2016-01-04 14:34:37 -08001606 }
1607
1608 return objFiles
1609}
1610
1611type libraryLinker struct {
1612 baseLinker
Colin Cross919281a2016-04-05 16:42:05 -07001613 flagExporter
Colin Cross665dce92016-04-28 14:50:03 -07001614 stripper
Colin Crossca860ac2016-01-04 14:34:37 -08001615
1616 Properties LibraryLinkerProperties
1617
1618 dynamicProperties struct {
1619 BuildStatic bool `blueprint:"mutated"`
1620 BuildShared bool `blueprint:"mutated"`
1621 }
1622
Colin Crossca860ac2016-01-04 14:34:37 -08001623 // If we're used as a whole_static_lib, our missing dependencies need
1624 // to be given
1625 wholeStaticMissingDeps []string
1626
1627 // For whole_static_libs
Colin Cross635c3b02016-05-18 15:37:25 -07001628 objFiles android.Paths
Colin Crossca860ac2016-01-04 14:34:37 -08001629}
1630
1631var _ linker = (*libraryLinker)(nil)
Colin Crossca860ac2016-01-04 14:34:37 -08001632
Colin Crossc7a38dc2016-07-12 13:13:09 -07001633type libraryInterface interface {
1634 getWholeStaticMissingDeps() []string
1635 static() bool
1636 objs() android.Paths
1637}
1638
Colin Crossca860ac2016-01-04 14:34:37 -08001639func (library *libraryLinker) props() []interface{} {
1640 props := library.baseLinker.props()
Colin Cross919281a2016-04-05 16:42:05 -07001641 return append(props,
1642 &library.Properties,
1643 &library.dynamicProperties,
Colin Cross665dce92016-04-28 14:50:03 -07001644 &library.flagExporter.Properties,
1645 &library.stripper.StripProperties)
Colin Crossca860ac2016-01-04 14:34:37 -08001646}
1647
Dan Willemsen648c8ae2016-07-21 16:42:14 -07001648func (library *libraryLinker) getLibName(ctx ModuleContext) string {
1649 name := ctx.ModuleName()
1650
Dan Willemsen627d83d2016-07-22 13:40:59 -07001651 if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
Dan Willemsen648c8ae2016-07-21 16:42:14 -07001652 if !strings.HasSuffix(name, "-host") {
1653 name = name + "-host"
1654 }
1655 }
1656
1657 return name + library.Properties.VariantName
1658}
1659
Colin Crossca860ac2016-01-04 14:34:37 -08001660func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
1661 flags = library.baseLinker.flags(ctx, flags)
1662
Colin Crossca860ac2016-01-04 14:34:37 -08001663 if !library.static() {
Dan Willemsen648c8ae2016-07-21 16:42:14 -07001664 libName := library.getLibName(ctx)
Colin Cross3f40fa42015-01-30 17:27:36 -08001665 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
1666 sharedFlag := "-Wl,-shared"
Dan Willemsendd0e2c32015-10-20 14:29:35 -07001667 if flags.Clang || ctx.Host() {
Colin Cross3f40fa42015-01-30 17:27:36 -08001668 sharedFlag = "-shared"
1669 }
Colin Crossf87b2612016-07-13 18:55:43 -07001670 var f []string
Colin Crossf6566ed2015-03-24 11:13:38 -07001671 if ctx.Device() {
Colin Crossf87b2612016-07-13 18:55:43 -07001672 f = append(f,
Dan Willemsen99db8c32016-03-03 18:05:38 -08001673 "-nostdlib",
1674 "-Wl,--gc-sections",
1675 )
Colin Cross3f40fa42015-01-30 17:27:36 -08001676 }
Colin Cross97ba0732015-03-23 17:50:24 -07001677
Colin Cross0af4b842015-04-30 16:36:18 -07001678 if ctx.Darwin() {
Colin Crossf87b2612016-07-13 18:55:43 -07001679 f = append(f,
Colin Cross0af4b842015-04-30 16:36:18 -07001680 "-dynamiclib",
1681 "-single_module",
1682 //"-read_only_relocs suppress",
Dan Willemsen490fd492015-11-24 17:53:15 -08001683 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
Colin Cross0af4b842015-04-30 16:36:18 -07001684 )
1685 } else {
Colin Crossf87b2612016-07-13 18:55:43 -07001686 f = append(f,
Colin Cross0af4b842015-04-30 16:36:18 -07001687 sharedFlag,
Colin Crossf87b2612016-07-13 18:55:43 -07001688 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
Colin Cross0af4b842015-04-30 16:36:18 -07001689 }
Colin Crossf87b2612016-07-13 18:55:43 -07001690
1691 flags.LdFlags = append(f, flags.LdFlags...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001692 }
Colin Cross97ba0732015-03-23 17:50:24 -07001693
1694 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08001695}
1696
Colin Crossca860ac2016-01-04 14:34:37 -08001697func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1698 deps = library.baseLinker.deps(ctx, deps)
1699 if library.static() {
1700 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
1701 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
1702 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
1703 } else {
Colin Crossa89d2e12016-01-11 12:48:37 -08001704 if ctx.Device() && !Bool(library.baseLinker.Properties.Nocrt) {
Colin Crossca860ac2016-01-04 14:34:37 -08001705 if !ctx.sdk() {
1706 deps.CrtBegin = "crtbegin_so"
1707 deps.CrtEnd = "crtend_so"
1708 } else {
1709 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion()
1710 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion()
1711 }
1712 }
1713 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
1714 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
1715 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
1716 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001717
Colin Crossca860ac2016-01-04 14:34:37 -08001718 return deps
1719}
Colin Cross3f40fa42015-01-30 17:27:36 -08001720
Colin Crossca860ac2016-01-04 14:34:37 -08001721func (library *libraryLinker) linkStatic(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001722 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Crossca860ac2016-01-04 14:34:37 -08001723
Colin Cross635c3b02016-05-18 15:37:25 -07001724 library.objFiles = append(android.Paths{}, deps.WholeStaticLibObjFiles...)
Dan Willemsen025b4802016-05-11 17:25:48 -07001725 library.objFiles = append(library.objFiles, objFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001726
Colin Cross635c3b02016-05-18 15:37:25 -07001727 outputFile := android.PathForModuleOut(ctx,
Colin Cross16b23492016-01-06 14:41:07 -08001728 ctx.ModuleName()+library.Properties.VariantName+staticLibraryExtension)
Colin Cross3f40fa42015-01-30 17:27:36 -08001729
Colin Cross0af4b842015-04-30 16:36:18 -07001730 if ctx.Darwin() {
Dan Willemsen025b4802016-05-11 17:25:48 -07001731 TransformDarwinObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001732 } else {
Dan Willemsen025b4802016-05-11 17:25:48 -07001733 TransformObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile)
Colin Cross0af4b842015-04-30 16:36:18 -07001734 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001735
Colin Crossca860ac2016-01-04 14:34:37 -08001736 library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001737
1738 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001739
1740 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001741}
1742
Colin Crossca860ac2016-01-04 14:34:37 -08001743func (library *libraryLinker) linkShared(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001744 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001745
Colin Cross635c3b02016-05-18 15:37:25 -07001746 var linkerDeps android.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07001747
Colin Cross635c3b02016-05-18 15:37:25 -07001748 versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
1749 unexportedSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
1750 forceNotWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list)
1751 forceWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list)
Dan Willemsen93c28312015-12-04 14:59:08 -08001752 if !ctx.Darwin() {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001753 if versionScript.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001754 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001755 linkerDeps = append(linkerDeps, versionScript.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001756 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001757 if unexportedSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001758 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
1759 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001760 if forceNotWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001761 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
1762 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001763 if forceWeakSymbols.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001764 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
1765 }
1766 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001767 if versionScript.Valid() {
Dan Willemsen93c28312015-12-04 14:59:08 -08001768 ctx.PropertyErrorf("version_script", "Not supported on Darwin")
1769 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001770 if unexportedSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001771 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001772 linkerDeps = append(linkerDeps, unexportedSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001773 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001774 if forceNotWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001775 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001776 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001777 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001778 if forceWeakSymbols.Valid() {
Colin Crossca860ac2016-01-04 14:34:37 -08001779 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001780 linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
Dan Willemsen93c28312015-12-04 14:59:08 -08001781 }
Colin Crossaee540a2015-07-06 17:48:31 -07001782 }
1783
Dan Willemsen648c8ae2016-07-21 16:42:14 -07001784 fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
Colin Cross635c3b02016-05-18 15:37:25 -07001785 outputFile := android.PathForModuleOut(ctx, fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001786 ret := outputFile
1787
1788 builderFlags := flagsToBuilderFlags(flags)
1789
1790 if library.stripper.needsStrip(ctx) {
1791 strippedOutputFile := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07001792 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07001793 library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
1794 }
1795
Colin Crossca860ac2016-01-04 14:34:37 -08001796 sharedLibs := deps.SharedLibs
1797 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001798
Colin Crossca860ac2016-01-04 14:34:37 -08001799 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs,
1800 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
Colin Cross665dce92016-04-28 14:50:03 -07001801 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001802
Colin Cross665dce92016-04-28 14:50:03 -07001803 return ret
Colin Cross3f40fa42015-01-30 17:27:36 -08001804}
1805
Colin Crossca860ac2016-01-04 14:34:37 -08001806func (library *libraryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001807 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001808
Colin Crossc99deeb2016-04-11 15:06:20 -07001809 objFiles = append(objFiles, deps.ObjFiles...)
1810
Colin Cross635c3b02016-05-18 15:37:25 -07001811 var out android.Path
Colin Crossca860ac2016-01-04 14:34:37 -08001812 if library.static() {
1813 out = library.linkStatic(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001814 } else {
Colin Crossca860ac2016-01-04 14:34:37 -08001815 out = library.linkShared(ctx, flags, deps, objFiles)
Colin Cross3f40fa42015-01-30 17:27:36 -08001816 }
1817
Colin Cross919281a2016-04-05 16:42:05 -07001818 library.exportIncludes(ctx, "-I")
Dan Willemsen76f08272016-07-09 00:14:08 -07001819 library.reexportFlags(deps.ReexportedFlags)
Colin Crossca860ac2016-01-04 14:34:37 -08001820
1821 return out
1822}
1823
1824func (library *libraryLinker) buildStatic() bool {
Colin Cross68861832016-07-08 10:41:41 -07001825 return library.dynamicProperties.BuildStatic &&
1826 (library.Properties.Static.Enabled == nil || *library.Properties.Static.Enabled)
Colin Crossca860ac2016-01-04 14:34:37 -08001827}
1828
1829func (library *libraryLinker) buildShared() bool {
Colin Cross68861832016-07-08 10:41:41 -07001830 return library.dynamicProperties.BuildShared &&
1831 (library.Properties.Shared.Enabled == nil || *library.Properties.Shared.Enabled)
Colin Crossca860ac2016-01-04 14:34:37 -08001832}
1833
1834func (library *libraryLinker) getWholeStaticMissingDeps() []string {
1835 return library.wholeStaticMissingDeps
1836}
1837
Colin Crossc99deeb2016-04-11 15:06:20 -07001838func (library *libraryLinker) installable() bool {
1839 return !library.static()
1840}
1841
Colin Crossc7a38dc2016-07-12 13:13:09 -07001842func (library *libraryLinker) objs() android.Paths {
1843 return library.objFiles
1844}
1845
Colin Crossca860ac2016-01-04 14:34:37 -08001846type libraryInstaller struct {
1847 baseInstaller
1848
Colin Cross30d5f512016-05-03 18:02:42 -07001849 linker *libraryLinker
1850 sanitize *sanitize
Colin Crossca860ac2016-01-04 14:34:37 -08001851}
1852
Colin Cross635c3b02016-05-18 15:37:25 -07001853func (library *libraryInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08001854 if !library.linker.static() {
1855 library.baseInstaller.install(ctx, file)
Colin Cross3f40fa42015-01-30 17:27:36 -08001856 }
1857}
1858
Colin Cross30d5f512016-05-03 18:02:42 -07001859func (library *libraryInstaller) inData() bool {
1860 return library.baseInstaller.inData() || library.sanitize.inData()
1861}
1862
Colin Cross635c3b02016-05-18 15:37:25 -07001863func NewLibrary(hod android.HostOrDeviceSupported, shared, static bool) *Module {
1864 module := newModule(hod, android.MultilibBoth)
Dan Albertc403f7c2015-03-18 14:01:18 -07001865
Colin Crossca860ac2016-01-04 14:34:37 -08001866 linker := &libraryLinker{}
1867 linker.dynamicProperties.BuildShared = shared
1868 linker.dynamicProperties.BuildStatic = static
1869 module.linker = linker
1870
1871 module.compiler = &libraryCompiler{
1872 linker: linker,
1873 }
1874 module.installer = &libraryInstaller{
1875 baseInstaller: baseInstaller{
1876 dir: "lib",
1877 dir64: "lib64",
1878 },
Colin Cross30d5f512016-05-03 18:02:42 -07001879 linker: linker,
1880 sanitize: module.sanitize,
Dan Albertc403f7c2015-03-18 14:01:18 -07001881 }
1882
Colin Crossca860ac2016-01-04 14:34:37 -08001883 return module
Dan Albertc403f7c2015-03-18 14:01:18 -07001884}
1885
Colin Crossca860ac2016-01-04 14:34:37 -08001886func libraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001887 module := NewLibrary(android.HostAndDeviceSupported, true, true)
Colin Crossca860ac2016-01-04 14:34:37 -08001888 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07001889}
1890
Colin Cross3f40fa42015-01-30 17:27:36 -08001891//
1892// Objects (for crt*.o)
1893//
1894
Colin Crossca860ac2016-01-04 14:34:37 -08001895type objectLinker struct {
Colin Cross81413472016-04-11 14:37:39 -07001896 Properties ObjectLinkerProperties
Dan Albertc3144b12015-04-28 18:17:56 -07001897}
1898
Colin Crossca860ac2016-01-04 14:34:37 -08001899func objectFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07001900 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08001901 module.compiler = &baseCompiler{}
1902 module.linker = &objectLinker{}
1903 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08001904}
1905
Colin Cross76fada02016-07-27 10:31:13 -07001906func (object *objectLinker) appendLdflags(flags []string) {
1907 panic(fmt.Errorf("appendLdflags on object Linker not supported"))
1908}
1909
Colin Cross81413472016-04-11 14:37:39 -07001910func (object *objectLinker) props() []interface{} {
1911 return []interface{}{&object.Properties}
Dan Albertc3144b12015-04-28 18:17:56 -07001912}
1913
Colin Crossca860ac2016-01-04 14:34:37 -08001914func (*objectLinker) begin(ctx BaseModuleContext) {}
Colin Cross3f40fa42015-01-30 17:27:36 -08001915
Colin Cross81413472016-04-11 14:37:39 -07001916func (object *objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1917 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
Colin Crossca860ac2016-01-04 14:34:37 -08001918 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08001919}
1920
Colin Crossca860ac2016-01-04 14:34:37 -08001921func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags {
Dan Willemsene7174922016-03-30 17:33:52 -07001922 if flags.Clang {
1923 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
1924 } else {
1925 flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainLdflags())
1926 }
1927
Colin Crossca860ac2016-01-04 14:34:37 -08001928 return flags
1929}
1930
1931func (object *objectLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07001932 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08001933
Colin Cross97ba0732015-03-23 17:50:24 -07001934 objFiles = append(objFiles, deps.ObjFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001935
Colin Cross635c3b02016-05-18 15:37:25 -07001936 var outputFile android.Path
Colin Cross3f40fa42015-01-30 17:27:36 -08001937 if len(objFiles) == 1 {
1938 outputFile = objFiles[0]
1939 } else {
Colin Cross635c3b02016-05-18 15:37:25 -07001940 output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
Colin Crossca860ac2016-01-04 14:34:37 -08001941 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001942 outputFile = output
Colin Cross3f40fa42015-01-30 17:27:36 -08001943 }
1944
Colin Cross3f40fa42015-01-30 17:27:36 -08001945 ctx.CheckbuildFile(outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08001946 return outputFile
Colin Cross3f40fa42015-01-30 17:27:36 -08001947}
1948
Colin Crossc99deeb2016-04-11 15:06:20 -07001949func (*objectLinker) installable() bool {
1950 return false
1951}
1952
Colin Cross3f40fa42015-01-30 17:27:36 -08001953//
1954// Executables
1955//
1956
Colin Crossca860ac2016-01-04 14:34:37 -08001957type binaryLinker struct {
1958 baseLinker
Colin Cross665dce92016-04-28 14:50:03 -07001959 stripper
Colin Cross7d5136f2015-05-11 13:39:40 -07001960
Colin Crossca860ac2016-01-04 14:34:37 -08001961 Properties BinaryLinkerProperties
Colin Cross7d5136f2015-05-11 13:39:40 -07001962
Colin Cross635c3b02016-05-18 15:37:25 -07001963 hostToolPath android.OptionalPath
Colin Cross7d5136f2015-05-11 13:39:40 -07001964}
1965
Colin Crossca860ac2016-01-04 14:34:37 -08001966var _ linker = (*binaryLinker)(nil)
1967
1968func (binary *binaryLinker) props() []interface{} {
Colin Cross665dce92016-04-28 14:50:03 -07001969 return append(binary.baseLinker.props(),
1970 &binary.Properties,
1971 &binary.stripper.StripProperties)
1972
Colin Cross3f40fa42015-01-30 17:27:36 -08001973}
1974
Colin Crossca860ac2016-01-04 14:34:37 -08001975func (binary *binaryLinker) buildStatic() bool {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001976 return binary.baseLinker.staticBinary()
Colin Crossed4cf0b2015-03-26 14:43:45 -07001977}
1978
Colin Crossca860ac2016-01-04 14:34:37 -08001979func (binary *binaryLinker) buildShared() bool {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07001980 return !binary.baseLinker.staticBinary()
Colin Crossed4cf0b2015-03-26 14:43:45 -07001981}
1982
Colin Crossca860ac2016-01-04 14:34:37 -08001983func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
Colin Cross4ae185c2015-03-26 15:12:10 -07001984 stem := ctx.ModuleName()
Colin Crossca860ac2016-01-04 14:34:37 -08001985 if binary.Properties.Stem != "" {
1986 stem = binary.Properties.Stem
Colin Cross3f40fa42015-01-30 17:27:36 -08001987 }
Colin Cross4ae185c2015-03-26 15:12:10 -07001988
Colin Crossca860ac2016-01-04 14:34:37 -08001989 return stem + binary.Properties.Suffix
Colin Cross3f40fa42015-01-30 17:27:36 -08001990}
1991
Colin Crossca860ac2016-01-04 14:34:37 -08001992func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
1993 deps = binary.baseLinker.deps(ctx, deps)
Colin Crossf6566ed2015-03-24 11:13:38 -07001994 if ctx.Device() {
Colin Crossa89d2e12016-01-11 12:48:37 -08001995 if !Bool(binary.baseLinker.Properties.Nocrt) {
1996 if !ctx.sdk() {
1997 if binary.buildStatic() {
1998 deps.CrtBegin = "crtbegin_static"
1999 } else {
2000 deps.CrtBegin = "crtbegin_dynamic"
2001 }
2002 deps.CrtEnd = "crtend_android"
Dan Albertc3144b12015-04-28 18:17:56 -07002003 } else {
Colin Crossa89d2e12016-01-11 12:48:37 -08002004 if binary.buildStatic() {
2005 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
2006 } else {
2007 if Bool(binary.Properties.Static_executable) {
2008 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
2009 } else {
2010 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
2011 }
2012 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion()
2013 }
Dan Albertc3144b12015-04-28 18:17:56 -07002014 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002015 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07002016
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002017 if binary.buildStatic() {
Colin Crossca860ac2016-01-04 14:34:37 -08002018 if inList("libc++_static", deps.StaticLibs) {
2019 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Cross74d1ec02015-04-28 13:30:13 -07002020 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07002021 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
2022 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
2023 // move them to the beginning of deps.LateStaticLibs
2024 var groupLibs []string
Colin Crossca860ac2016-01-04 14:34:37 -08002025 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
Colin Crossed4cf0b2015-03-26 14:43:45 -07002026 []string{"libc", "libc_nomalloc", "libcompiler_rt"})
Colin Crossca860ac2016-01-04 14:34:37 -08002027 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
Colin Crossed4cf0b2015-03-26 14:43:45 -07002028 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002029 }
Colin Crossca860ac2016-01-04 14:34:37 -08002030
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002031 if binary.buildShared() && inList("libc", deps.StaticLibs) {
Colin Crossca860ac2016-01-04 14:34:37 -08002032 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
2033 "from static libs or set static_executable: true")
2034 }
2035 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002036}
2037
Colin Crossc99deeb2016-04-11 15:06:20 -07002038func (*binaryLinker) installable() bool {
2039 return true
2040}
2041
Colin Cross16b23492016-01-06 14:41:07 -08002042func (binary *binaryLinker) isDependencyRoot() bool {
2043 return true
2044}
2045
Colin Cross635c3b02016-05-18 15:37:25 -07002046func NewBinary(hod android.HostOrDeviceSupported) *Module {
2047 module := newModule(hod, android.MultilibFirst)
Colin Crossca860ac2016-01-04 14:34:37 -08002048 module.compiler = &baseCompiler{}
2049 module.linker = &binaryLinker{}
2050 module.installer = &baseInstaller{
2051 dir: "bin",
2052 }
2053 return module
Colin Cross3f40fa42015-01-30 17:27:36 -08002054}
2055
Colin Crossca860ac2016-01-04 14:34:37 -08002056func binaryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002057 module := NewBinary(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002058 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002059}
2060
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002061func (binary *binaryLinker) begin(ctx BaseModuleContext) {
2062 binary.baseLinker.begin(ctx)
2063
2064 static := Bool(binary.Properties.Static_executable)
2065 if ctx.Host() {
Colin Crossa1ad8d12016-06-01 17:09:44 -07002066 if ctx.Os() == android.Linux {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002067 if binary.Properties.Static_executable == nil && Bool(ctx.AConfig().ProductVariables.HostStaticBinaries) {
2068 static = true
2069 }
2070 } else {
2071 // Static executables are not supported on Darwin or Windows
2072 static = false
2073 }
Colin Cross0af4b842015-04-30 16:36:18 -07002074 }
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002075 if static {
2076 binary.dynamicProperties.VariantIsStatic = true
Colin Crossca860ac2016-01-04 14:34:37 -08002077 binary.dynamicProperties.VariantIsStaticBinary = true
Colin Cross18b6dc52015-04-28 13:20:37 -07002078 }
2079}
2080
Colin Crossca860ac2016-01-04 14:34:37 -08002081func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
2082 flags = binary.baseLinker.flags(ctx, flags)
Colin Cross21b9a242015-03-24 14:15:58 -07002083
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002084 if ctx.Host() && !binary.staticBinary() {
Dan Willemsen490fd492015-11-24 17:53:15 -08002085 flags.LdFlags = append(flags.LdFlags, "-pie")
Colin Crossa1ad8d12016-06-01 17:09:44 -07002086 if ctx.Os() == android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08002087 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
2088 }
2089 }
2090
2091 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
2092 // all code is position independent, and then those warnings get promoted to
2093 // errors.
Colin Crossa1ad8d12016-06-01 17:09:44 -07002094 if ctx.Os() != android.Windows {
Dan Willemsen490fd492015-11-24 17:53:15 -08002095 flags.CFlags = append(flags.CFlags, "-fpie")
2096 }
Colin Cross97ba0732015-03-23 17:50:24 -07002097
Colin Crossf6566ed2015-03-24 11:13:38 -07002098 if ctx.Device() {
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002099 if binary.buildStatic() {
Colin Crossed4cf0b2015-03-26 14:43:45 -07002100 // Clang driver needs -static to create static executable.
2101 // However, bionic/linker uses -shared to overwrite.
2102 // Linker for x86 targets does not allow coexistance of -static and -shared,
2103 // so we add -static only if -shared is not used.
2104 if !inList("-shared", flags.LdFlags) {
2105 flags.LdFlags = append(flags.LdFlags, "-static")
2106 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002107
Colin Crossed4cf0b2015-03-26 14:43:45 -07002108 flags.LdFlags = append(flags.LdFlags,
2109 "-nostdlib",
2110 "-Bstatic",
2111 "-Wl,--gc-sections",
2112 )
2113
2114 } else {
Colin Cross16b23492016-01-06 14:41:07 -08002115 if flags.DynamicLinker == "" {
2116 flags.DynamicLinker = "/system/bin/linker"
2117 if flags.Toolchain.Is64Bit() {
2118 flags.DynamicLinker += "64"
2119 }
Colin Crossed4cf0b2015-03-26 14:43:45 -07002120 }
2121
2122 flags.LdFlags = append(flags.LdFlags,
Colin Cross979422c2015-12-01 14:09:48 -08002123 "-pie",
Colin Crossed4cf0b2015-03-26 14:43:45 -07002124 "-nostdlib",
2125 "-Bdynamic",
Colin Crossed4cf0b2015-03-26 14:43:45 -07002126 "-Wl,--gc-sections",
2127 "-Wl,-z,nocopyreloc",
2128 )
2129 }
Dan Willemsen36cff8b2016-05-17 16:35:02 -07002130 } else {
2131 if binary.staticBinary() {
2132 flags.LdFlags = append(flags.LdFlags, "-static")
2133 }
2134 if ctx.Darwin() {
2135 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
2136 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002137 }
2138
Colin Cross97ba0732015-03-23 17:50:24 -07002139 return flags
Colin Cross3f40fa42015-01-30 17:27:36 -08002140}
2141
Colin Crossca860ac2016-01-04 14:34:37 -08002142func (binary *binaryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07002143 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002144
Colin Cross665dce92016-04-28 14:50:03 -07002145 fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
Colin Cross635c3b02016-05-18 15:37:25 -07002146 outputFile := android.PathForModuleOut(ctx, fileName)
Colin Cross665dce92016-04-28 14:50:03 -07002147 ret := outputFile
Colin Crossa1ad8d12016-06-01 17:09:44 -07002148 if ctx.Os().Class == android.Host {
Colin Cross635c3b02016-05-18 15:37:25 -07002149 binary.hostToolPath = android.OptionalPathForPath(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002150 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002151
Colin Cross635c3b02016-05-18 15:37:25 -07002152 var linkerDeps android.Paths
Colin Crossaee540a2015-07-06 17:48:31 -07002153
Colin Crossca860ac2016-01-04 14:34:37 -08002154 sharedLibs := deps.SharedLibs
2155 sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
2156
Colin Cross16b23492016-01-06 14:41:07 -08002157 if flags.DynamicLinker != "" {
2158 flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
2159 }
2160
Colin Cross665dce92016-04-28 14:50:03 -07002161 builderFlags := flagsToBuilderFlags(flags)
2162
2163 if binary.stripper.needsStrip(ctx) {
2164 strippedOutputFile := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07002165 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07002166 binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
2167 }
2168
2169 if binary.Properties.Prefix_symbols != "" {
2170 afterPrefixSymbols := outputFile
Colin Cross635c3b02016-05-18 15:37:25 -07002171 outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName)
Colin Cross665dce92016-04-28 14:50:03 -07002172 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile,
2173 flagsToBuilderFlags(flags), afterPrefixSymbols)
2174 }
2175
Colin Crossca860ac2016-01-04 14:34:37 -08002176 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs,
Colin Crossaee540a2015-07-06 17:48:31 -07002177 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
Colin Cross665dce92016-04-28 14:50:03 -07002178 builderFlags, outputFile)
Colin Crossca860ac2016-01-04 14:34:37 -08002179
2180 return ret
Dan Albertc403f7c2015-03-18 14:01:18 -07002181}
Colin Cross3f40fa42015-01-30 17:27:36 -08002182
Colin Cross635c3b02016-05-18 15:37:25 -07002183func (binary *binaryLinker) HostToolPath() android.OptionalPath {
Colin Crossca860ac2016-01-04 14:34:37 -08002184 return binary.hostToolPath
Colin Crossd350ecd2015-04-28 13:25:36 -07002185}
2186
Colin Cross665dce92016-04-28 14:50:03 -07002187type stripper struct {
2188 StripProperties StripProperties
2189}
2190
2191func (stripper *stripper) needsStrip(ctx ModuleContext) bool {
2192 return !ctx.AConfig().EmbeddedInMake() && !stripper.StripProperties.Strip.None
2193}
2194
Colin Cross635c3b02016-05-18 15:37:25 -07002195func (stripper *stripper) strip(ctx ModuleContext, in, out android.ModuleOutPath,
Colin Cross665dce92016-04-28 14:50:03 -07002196 flags builderFlags) {
Colin Crossb8ecdfe2016-05-03 15:10:29 -07002197 if ctx.Darwin() {
2198 TransformDarwinStrip(ctx, in, out)
2199 } else {
2200 flags.stripKeepSymbols = stripper.StripProperties.Strip.Keep_symbols
2201 // TODO(ccross): don't add gnu debuglink for user builds
2202 flags.stripAddGnuDebuglink = true
2203 TransformStrip(ctx, in, out, flags)
2204 }
Colin Cross665dce92016-04-28 14:50:03 -07002205}
2206
Colin Cross635c3b02016-05-18 15:37:25 -07002207func testPerSrcMutator(mctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002208 if m, ok := mctx.Module().(*Module); ok {
Colin Crossc7a38dc2016-07-12 13:13:09 -07002209 if test, ok := m.linker.(*testBinaryLinker); ok {
2210 if Bool(test.testLinker.Properties.Test_per_src) {
Colin Crossca860ac2016-01-04 14:34:37 -08002211 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
2212 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2213 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
2214 }
2215 tests := mctx.CreateLocalVariations(testNames...)
2216 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
2217 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
Colin Crossc7a38dc2016-07-12 13:13:09 -07002218 tests[i].(*Module).linker.(*testBinaryLinker).binaryLinker.Properties.Stem = testNames[i]
Colin Crossca860ac2016-01-04 14:34:37 -08002219 }
Colin Cross6002e052015-09-16 16:00:08 -07002220 }
2221 }
2222 }
Colin Cross7d5136f2015-05-11 13:39:40 -07002223}
2224
Colin Crossca860ac2016-01-04 14:34:37 -08002225type testLinker struct {
Colin Crossca860ac2016-01-04 14:34:37 -08002226 Properties TestLinkerProperties
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002227}
2228
Colin Crossca860ac2016-01-04 14:34:37 -08002229func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags {
Colin Crossca860ac2016-01-04 14:34:37 -08002230 if !test.Properties.Gtest {
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002231 return flags
2232 }
Dan Albertc403f7c2015-03-18 14:01:18 -07002233
Colin Cross97ba0732015-03-23 17:50:24 -07002234 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
Colin Crossf6566ed2015-03-24 11:13:38 -07002235 if ctx.Host() {
Colin Cross97ba0732015-03-23 17:50:24 -07002236 flags.CFlags = append(flags.CFlags, "-O0", "-g")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002237
Colin Crossa1ad8d12016-06-01 17:09:44 -07002238 switch ctx.Os() {
Colin Cross635c3b02016-05-18 15:37:25 -07002239 case android.Windows:
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002240 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS")
Colin Cross635c3b02016-05-18 15:37:25 -07002241 case android.Linux:
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002242 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX")
2243 flags.LdFlags = append(flags.LdFlags, "-lpthread")
Colin Cross635c3b02016-05-18 15:37:25 -07002244 case android.Darwin:
Dan Willemsen4a946832016-05-13 14:13:01 -07002245 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_MAC")
2246 flags.LdFlags = append(flags.LdFlags, "-lpthread")
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002247 }
2248 } else {
2249 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID")
Dan Albertc403f7c2015-03-18 14:01:18 -07002250 }
2251
Colin Cross21b9a242015-03-24 14:15:58 -07002252 return flags
Dan Albertc403f7c2015-03-18 14:01:18 -07002253}
2254
Colin Crossca860ac2016-01-04 14:34:37 -08002255func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2256 if test.Properties.Gtest {
Dan Willemsen8146b2f2016-03-30 21:00:30 -07002257 if ctx.sdk() && ctx.Device() {
2258 switch ctx.selectedStl() {
2259 case "ndk_libc++_shared", "ndk_libc++_static":
2260 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_libcxx", "libgtest_ndk_libcxx")
2261 case "ndk_libgnustl_static":
2262 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_gnustl", "libgtest_ndk_gnustl")
2263 default:
2264 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk", "libgtest_ndk")
2265 }
2266 } else {
2267 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
2268 }
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002269 }
Colin Crossc7a38dc2016-07-12 13:13:09 -07002270 return deps
2271}
2272
2273type testBinaryLinker struct {
2274 testLinker
2275 binaryLinker
2276}
2277
2278func (test *testBinaryLinker) begin(ctx BaseModuleContext) {
2279 test.binaryLinker.begin(ctx)
2280 runpath := "../../lib"
2281 if ctx.toolchain().Is64Bit() {
2282 runpath += "64"
2283 }
2284 test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
2285}
2286
2287func (test *testBinaryLinker) props() []interface{} {
2288 return append(test.binaryLinker.props(), &test.testLinker.Properties)
2289}
2290
2291func (test *testBinaryLinker) flags(ctx ModuleContext, flags Flags) Flags {
2292 flags = test.binaryLinker.flags(ctx, flags)
2293 flags = test.testLinker.flags(ctx, flags)
2294 return flags
2295}
2296
2297func (test *testBinaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2298 deps = test.testLinker.deps(ctx, deps)
Colin Crossca860ac2016-01-04 14:34:37 -08002299 deps = test.binaryLinker.deps(ctx, deps)
2300 return deps
Dan Albertc403f7c2015-03-18 14:01:18 -07002301}
2302
Colin Crossc7a38dc2016-07-12 13:13:09 -07002303type testLibraryLinker struct {
2304 testLinker
2305 *libraryLinker
2306}
2307
2308func (test *testLibraryLinker) props() []interface{} {
2309 return append(test.libraryLinker.props(), &test.testLinker.Properties)
2310}
2311
2312func (test *testLibraryLinker) flags(ctx ModuleContext, flags Flags) Flags {
2313 flags = test.libraryLinker.flags(ctx, flags)
2314 flags = test.testLinker.flags(ctx, flags)
2315 return flags
2316}
2317
2318func (test *testLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
2319 deps = test.testLinker.deps(ctx, deps)
2320 deps = test.libraryLinker.deps(ctx, deps)
2321 return deps
2322}
2323
Colin Crossca860ac2016-01-04 14:34:37 -08002324type testInstaller struct {
2325 baseInstaller
Dan Willemsen782a2d12015-12-21 14:55:28 -08002326}
2327
Colin Cross635c3b02016-05-18 15:37:25 -07002328func (installer *testInstaller) install(ctx ModuleContext, file android.Path) {
Colin Crossca860ac2016-01-04 14:34:37 -08002329 installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
2330 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
2331 installer.baseInstaller.install(ctx, file)
2332}
2333
Colin Cross635c3b02016-05-18 15:37:25 -07002334func NewTest(hod android.HostOrDeviceSupported) *Module {
2335 module := newModule(hod, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002336 module.compiler = &baseCompiler{}
Colin Crossc7a38dc2016-07-12 13:13:09 -07002337 linker := &testBinaryLinker{}
2338 linker.testLinker.Properties.Gtest = true
Colin Crossca860ac2016-01-04 14:34:37 -08002339 module.linker = linker
2340 module.installer = &testInstaller{
2341 baseInstaller: baseInstaller{
2342 dir: "nativetest",
2343 dir64: "nativetest64",
2344 data: true,
2345 },
Dan Albertc403f7c2015-03-18 14:01:18 -07002346 }
Colin Crossca860ac2016-01-04 14:34:37 -08002347 return module
Dan Willemsen10d52fd2015-12-21 15:25:58 -08002348}
2349
Colin Crossca860ac2016-01-04 14:34:37 -08002350func testFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002351 module := NewTest(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002352 return module.Init()
Dan Albertc403f7c2015-03-18 14:01:18 -07002353}
2354
Colin Crossc7a38dc2016-07-12 13:13:09 -07002355func NewTestLibrary(hod android.HostOrDeviceSupported) *Module {
2356 module := NewLibrary(android.HostAndDeviceSupported, false, true)
2357 linker := &testLibraryLinker{
2358 libraryLinker: module.linker.(*libraryLinker),
2359 }
2360 linker.testLinker.Properties.Gtest = true
2361 module.linker = linker
2362 module.installer = &testInstaller{
2363 baseInstaller: baseInstaller{
2364 dir: "nativetest",
2365 dir64: "nativetest64",
2366 data: true,
2367 },
2368 }
2369 return module
2370}
2371
2372func testLibraryFactory() (blueprint.Module, []interface{}) {
2373 module := NewTestLibrary(android.HostAndDeviceSupported)
2374 return module.Init()
2375}
2376
Colin Crossca860ac2016-01-04 14:34:37 -08002377type benchmarkLinker struct {
Colin Crossaa3bf372016-07-14 10:27:10 -07002378 testBinaryLinker
Colin Cross9ffb4f52015-04-24 17:48:09 -07002379}
2380
Colin Crossca860ac2016-01-04 14:34:37 -08002381func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Crossaa3bf372016-07-14 10:27:10 -07002382 deps = benchmark.testBinaryLinker.deps(ctx, deps)
Colin Cross26832742016-07-11 14:57:56 -07002383 deps.StaticLibs = append(deps.StaticLibs, "libgoogle-benchmark")
Colin Crossca860ac2016-01-04 14:34:37 -08002384 return deps
Colin Cross9ffb4f52015-04-24 17:48:09 -07002385}
2386
Colin Cross635c3b02016-05-18 15:37:25 -07002387func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
2388 module := newModule(hod, android.MultilibFirst)
Colin Crossca860ac2016-01-04 14:34:37 -08002389 module.compiler = &baseCompiler{}
2390 module.linker = &benchmarkLinker{}
Colin Cross624b8ed2016-07-11 17:20:09 -07002391 module.installer = &testInstaller{
2392 baseInstaller: baseInstaller{
2393 dir: "nativetest",
2394 dir64: "nativetest64",
2395 data: true,
2396 },
Colin Cross2ba19d92015-05-07 15:44:20 -07002397 }
Colin Crossca860ac2016-01-04 14:34:37 -08002398 return module
Colin Cross2ba19d92015-05-07 15:44:20 -07002399}
2400
Colin Crossca860ac2016-01-04 14:34:37 -08002401func benchmarkFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002402 module := NewBenchmark(android.HostAndDeviceSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002403 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002404}
2405
Colin Cross3f40fa42015-01-30 17:27:36 -08002406//
2407// Static library
2408//
2409
Colin Crossca860ac2016-01-04 14:34:37 -08002410func libraryStaticFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002411 module := NewLibrary(android.HostAndDeviceSupported, false, true)
Colin Crossca860ac2016-01-04 14:34:37 -08002412 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002413}
2414
2415//
2416// Shared libraries
2417//
2418
Colin Crossca860ac2016-01-04 14:34:37 -08002419func librarySharedFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002420 module := NewLibrary(android.HostAndDeviceSupported, true, false)
Colin Crossca860ac2016-01-04 14:34:37 -08002421 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002422}
2423
2424//
2425// Host static library
2426//
2427
Colin Crossca860ac2016-01-04 14:34:37 -08002428func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002429 module := NewLibrary(android.HostSupported, false, true)
Colin Crossca860ac2016-01-04 14:34:37 -08002430 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002431}
2432
2433//
2434// Host Shared libraries
2435//
2436
Colin Crossca860ac2016-01-04 14:34:37 -08002437func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002438 module := NewLibrary(android.HostSupported, true, false)
Colin Crossca860ac2016-01-04 14:34:37 -08002439 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002440}
2441
2442//
2443// Host Binaries
2444//
2445
Colin Crossca860ac2016-01-04 14:34:37 -08002446func binaryHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002447 module := NewBinary(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002448 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002449}
2450
2451//
Colin Cross1f8f2342015-03-26 16:09:47 -07002452// Host Tests
2453//
2454
Colin Crossca860ac2016-01-04 14:34:37 -08002455func testHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002456 module := NewTest(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002457 return module.Init()
Colin Cross1f8f2342015-03-26 16:09:47 -07002458}
2459
2460//
Colin Cross2ba19d92015-05-07 15:44:20 -07002461// Host Benchmarks
2462//
2463
Colin Crossca860ac2016-01-04 14:34:37 -08002464func benchmarkHostFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002465 module := NewBenchmark(android.HostSupported)
Colin Crossca860ac2016-01-04 14:34:37 -08002466 return module.Init()
Colin Cross2ba19d92015-05-07 15:44:20 -07002467}
2468
2469//
Colin Crosscfad1192015-11-02 16:43:11 -08002470// Defaults
2471//
Colin Crossca860ac2016-01-04 14:34:37 -08002472type Defaults struct {
Colin Cross635c3b02016-05-18 15:37:25 -07002473 android.ModuleBase
2474 android.DefaultsModule
Colin Crosscfad1192015-11-02 16:43:11 -08002475}
2476
Colin Cross635c3b02016-05-18 15:37:25 -07002477func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crosscfad1192015-11-02 16:43:11 -08002478}
2479
Colin Crossca860ac2016-01-04 14:34:37 -08002480func defaultsFactory() (blueprint.Module, []interface{}) {
2481 module := &Defaults{}
Colin Crosscfad1192015-11-02 16:43:11 -08002482
2483 propertyStructs := []interface{}{
Colin Crossca860ac2016-01-04 14:34:37 -08002484 &BaseProperties{},
2485 &BaseCompilerProperties{},
2486 &BaseLinkerProperties{},
2487 &LibraryCompilerProperties{},
Colin Cross919281a2016-04-05 16:42:05 -07002488 &FlagExporterProperties{},
Colin Crossca860ac2016-01-04 14:34:37 -08002489 &LibraryLinkerProperties{},
2490 &BinaryLinkerProperties{},
2491 &TestLinkerProperties{},
2492 &UnusedProperties{},
2493 &StlProperties{},
Colin Cross16b23492016-01-06 14:41:07 -08002494 &SanitizeProperties{},
Colin Cross665dce92016-04-28 14:50:03 -07002495 &StripProperties{},
Colin Crosscfad1192015-11-02 16:43:11 -08002496 }
2497
Colin Cross635c3b02016-05-18 15:37:25 -07002498 _, propertyStructs = android.InitAndroidArchModule(module, android.HostAndDeviceDefault,
2499 android.MultilibDefault, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002500
Colin Cross635c3b02016-05-18 15:37:25 -07002501 return android.InitDefaultsModule(module, module, propertyStructs...)
Colin Crosscfad1192015-11-02 16:43:11 -08002502}
2503
2504//
Colin Cross3f40fa42015-01-30 17:27:36 -08002505// Device libraries shipped with gcc
2506//
2507
Colin Crossca860ac2016-01-04 14:34:37 -08002508type toolchainLibraryLinker struct {
2509 baseLinker
Colin Cross3f40fa42015-01-30 17:27:36 -08002510}
2511
Colin Crossca860ac2016-01-04 14:34:37 -08002512var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
2513
2514func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Cross3f40fa42015-01-30 17:27:36 -08002515 // toolchain libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002516 return deps
Colin Cross3f40fa42015-01-30 17:27:36 -08002517}
2518
Colin Crossca860ac2016-01-04 14:34:37 -08002519func (*toolchainLibraryLinker) buildStatic() bool {
2520 return true
2521}
Colin Cross3f40fa42015-01-30 17:27:36 -08002522
Colin Crossca860ac2016-01-04 14:34:37 -08002523func (*toolchainLibraryLinker) buildShared() bool {
2524 return false
2525}
2526
2527func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002528 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002529 module.compiler = &baseCompiler{}
2530 module.linker = &toolchainLibraryLinker{}
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002531 module.Properties.Clang = proptools.BoolPtr(false)
Colin Crossca860ac2016-01-04 14:34:37 -08002532 return module.Init()
Colin Cross3f40fa42015-01-30 17:27:36 -08002533}
2534
Colin Crossca860ac2016-01-04 14:34:37 -08002535func (library *toolchainLibraryLinker) link(ctx ModuleContext,
Colin Cross635c3b02016-05-18 15:37:25 -07002536 flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
Colin Cross3f40fa42015-01-30 17:27:36 -08002537
2538 libName := ctx.ModuleName() + staticLibraryExtension
Colin Cross635c3b02016-05-18 15:37:25 -07002539 outputFile := android.PathForModuleOut(ctx, libName)
Colin Cross3f40fa42015-01-30 17:27:36 -08002540
Dan Willemsenfc9c28c2016-01-12 16:22:40 -08002541 if flags.Clang {
2542 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
2543 }
2544
Colin Crossca860ac2016-01-04 14:34:37 -08002545 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002546
2547 ctx.CheckbuildFile(outputFile)
Colin Cross3f40fa42015-01-30 17:27:36 -08002548
Colin Crossca860ac2016-01-04 14:34:37 -08002549 return outputFile
Dan Albertc403f7c2015-03-18 14:01:18 -07002550}
2551
Colin Crossc99deeb2016-04-11 15:06:20 -07002552func (*toolchainLibraryLinker) installable() bool {
2553 return false
2554}
2555
Dan Albertbe961682015-03-18 23:38:50 -07002556// NDK prebuilt libraries.
2557//
2558// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
2559// either (with the exception of the shared STLs, which are installed to the app's directory rather
2560// than to the system image).
2561
Colin Cross635c3b02016-05-18 15:37:25 -07002562func getNdkLibDir(ctx android.ModuleContext, toolchain Toolchain, version string) android.SourcePath {
Colin Crossc7fd91a2016-05-17 13:15:15 -07002563 suffix := ""
2564 // Most 64-bit NDK prebuilts store libraries in "lib64", except for arm64 which is not a
2565 // multilib toolchain and stores the libraries in "lib".
Colin Cross635c3b02016-05-18 15:37:25 -07002566 if toolchain.Is64Bit() && ctx.Arch().ArchType != android.Arm64 {
Colin Crossc7fd91a2016-05-17 13:15:15 -07002567 suffix = "64"
2568 }
Colin Cross635c3b02016-05-18 15:37:25 -07002569 return android.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib%s",
Colin Crossc7fd91a2016-05-17 13:15:15 -07002570 version, toolchain.Name(), suffix))
Dan Albertbe961682015-03-18 23:38:50 -07002571}
2572
Colin Cross635c3b02016-05-18 15:37:25 -07002573func ndkPrebuiltModuleToPath(ctx android.ModuleContext, toolchain Toolchain,
2574 ext string, version string) android.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002575
2576 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
2577 // We want to translate to just NAME.EXT
2578 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
2579 dir := getNdkLibDir(ctx, toolchain, version)
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002580 return dir.Join(ctx, name+ext)
Dan Albertc3144b12015-04-28 18:17:56 -07002581}
2582
Colin Crossca860ac2016-01-04 14:34:37 -08002583type ndkPrebuiltObjectLinker struct {
2584 objectLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002585}
2586
Colin Crossca860ac2016-01-04 14:34:37 -08002587func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertc3144b12015-04-28 18:17:56 -07002588 // NDK objects can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002589 return deps
Dan Albertc3144b12015-04-28 18:17:56 -07002590}
2591
Colin Crossca860ac2016-01-04 14:34:37 -08002592func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002593 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002594 module.linker = &ndkPrebuiltObjectLinker{}
Dan Willemsen72d39932016-07-08 23:23:48 -07002595 module.Properties.HideFromMake = true
Colin Crossca860ac2016-01-04 14:34:37 -08002596 return module.Init()
Dan Albertc3144b12015-04-28 18:17:56 -07002597}
2598
Colin Crossca860ac2016-01-04 14:34:37 -08002599func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002600 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertc3144b12015-04-28 18:17:56 -07002601 // A null build step, but it sets up the output path.
2602 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
2603 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
2604 }
2605
Colin Crossca860ac2016-01-04 14:34:37 -08002606 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
Dan Albertc3144b12015-04-28 18:17:56 -07002607}
2608
Colin Crossca860ac2016-01-04 14:34:37 -08002609type ndkPrebuiltLibraryLinker struct {
2610 libraryLinker
Dan Albertc3144b12015-04-28 18:17:56 -07002611}
2612
Colin Crossca860ac2016-01-04 14:34:37 -08002613var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
2614var _ exportedFlagsProducer = (*libraryLinker)(nil)
Dan Albertc3144b12015-04-28 18:17:56 -07002615
Colin Crossca860ac2016-01-04 14:34:37 -08002616func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} {
Colin Cross919281a2016-04-05 16:42:05 -07002617 return append(ndk.libraryLinker.props(), &ndk.Properties, &ndk.flagExporter.Properties)
Dan Albertbe961682015-03-18 23:38:50 -07002618}
2619
Colin Crossca860ac2016-01-04 14:34:37 -08002620func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps {
Dan Albertbe961682015-03-18 23:38:50 -07002621 // NDK libraries can't have any dependencies
Colin Crossca860ac2016-01-04 14:34:37 -08002622 return deps
Dan Albertbe961682015-03-18 23:38:50 -07002623}
2624
Colin Crossca860ac2016-01-04 14:34:37 -08002625func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002626 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002627 linker := &ndkPrebuiltLibraryLinker{}
2628 linker.dynamicProperties.BuildShared = true
2629 module.linker = linker
Dan Willemsen72d39932016-07-08 23:23:48 -07002630 module.Properties.HideFromMake = true
Colin Crossca860ac2016-01-04 14:34:37 -08002631 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002632}
2633
Colin Crossca860ac2016-01-04 14:34:37 -08002634func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002635 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002636 // A null build step, but it sets up the output path.
2637 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2638 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2639 }
2640
Colin Cross919281a2016-04-05 16:42:05 -07002641 ndk.exportIncludes(ctx, "-isystem")
Dan Albertbe961682015-03-18 23:38:50 -07002642
Colin Crossca860ac2016-01-04 14:34:37 -08002643 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
2644 ctx.sdkVersion())
Dan Albertbe961682015-03-18 23:38:50 -07002645}
2646
2647// The NDK STLs are slightly different from the prebuilt system libraries:
2648// * Are not specific to each platform version.
2649// * The libraries are not in a predictable location for each STL.
2650
Colin Crossca860ac2016-01-04 14:34:37 -08002651type ndkPrebuiltStlLinker struct {
2652 ndkPrebuiltLibraryLinker
Dan Albertbe961682015-03-18 23:38:50 -07002653}
2654
Colin Crossca860ac2016-01-04 14:34:37 -08002655func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002656 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002657 linker := &ndkPrebuiltStlLinker{}
2658 linker.dynamicProperties.BuildShared = true
2659 module.linker = linker
Dan Willemsen72d39932016-07-08 23:23:48 -07002660 module.Properties.HideFromMake = true
Colin Crossca860ac2016-01-04 14:34:37 -08002661 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002662}
2663
Colin Crossca860ac2016-01-04 14:34:37 -08002664func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
Colin Cross635c3b02016-05-18 15:37:25 -07002665 module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
Colin Crossca860ac2016-01-04 14:34:37 -08002666 linker := &ndkPrebuiltStlLinker{}
2667 linker.dynamicProperties.BuildStatic = true
2668 module.linker = linker
Dan Willemsen72d39932016-07-08 23:23:48 -07002669 module.Properties.HideFromMake = true
Colin Crossca860ac2016-01-04 14:34:37 -08002670 return module.Init()
Dan Albertbe961682015-03-18 23:38:50 -07002671}
2672
Colin Cross635c3b02016-05-18 15:37:25 -07002673func getNdkStlLibDir(ctx android.ModuleContext, toolchain Toolchain, stl string) android.SourcePath {
Dan Albertbe961682015-03-18 23:38:50 -07002674 gccVersion := toolchain.GccVersion()
2675 var libDir string
2676 switch stl {
2677 case "libstlport":
2678 libDir = "cxx-stl/stlport/libs"
2679 case "libc++":
2680 libDir = "cxx-stl/llvm-libc++/libs"
2681 case "libgnustl":
2682 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
2683 }
2684
2685 if libDir != "" {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07002686 ndkSrcRoot := "prebuilts/ndk/current/sources"
Colin Cross635c3b02016-05-18 15:37:25 -07002687 return android.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
Dan Albertbe961682015-03-18 23:38:50 -07002688 }
2689
2690 ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
Colin Cross635c3b02016-05-18 15:37:25 -07002691 return android.PathForSource(ctx, "")
Dan Albertbe961682015-03-18 23:38:50 -07002692}
2693
Colin Crossca860ac2016-01-04 14:34:37 -08002694func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
Colin Cross635c3b02016-05-18 15:37:25 -07002695 deps PathDeps, objFiles android.Paths) android.Path {
Dan Albertbe961682015-03-18 23:38:50 -07002696 // A null build step, but it sets up the output path.
2697 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
2698 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
2699 }
2700
Colin Cross919281a2016-04-05 16:42:05 -07002701 ndk.exportIncludes(ctx, "-I")
Dan Albertbe961682015-03-18 23:38:50 -07002702
2703 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
Dan Willemsen490fd492015-11-24 17:53:15 -08002704 libExt := flags.Toolchain.ShlibSuffix()
Colin Crossca860ac2016-01-04 14:34:37 -08002705 if ndk.dynamicProperties.BuildStatic {
Dan Albertbe961682015-03-18 23:38:50 -07002706 libExt = staticLibraryExtension
2707 }
2708
2709 stlName := strings.TrimSuffix(libName, "_shared")
2710 stlName = strings.TrimSuffix(stlName, "_static")
2711 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
Colin Crossca860ac2016-01-04 14:34:37 -08002712 return libDir.Join(ctx, libName+libExt)
Dan Albertbe961682015-03-18 23:38:50 -07002713}
2714
Colin Cross635c3b02016-05-18 15:37:25 -07002715func linkageMutator(mctx android.BottomUpMutatorContext) {
Colin Crossca860ac2016-01-04 14:34:37 -08002716 if m, ok := mctx.Module().(*Module); ok {
2717 if m.linker != nil {
2718 if linker, ok := m.linker.(baseLinkerInterface); ok {
2719 var modules []blueprint.Module
2720 if linker.buildStatic() && linker.buildShared() {
2721 modules = mctx.CreateLocalVariations("static", "shared")
Colin Crossc99deeb2016-04-11 15:06:20 -07002722 static := modules[0].(*Module)
2723 shared := modules[1].(*Module)
2724
2725 static.linker.(baseLinkerInterface).setStatic(true)
2726 shared.linker.(baseLinkerInterface).setStatic(false)
2727
2728 if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
2729 sharedCompiler := shared.compiler.(*libraryCompiler)
2730 if len(staticCompiler.Properties.Static.Cflags) == 0 &&
2731 len(sharedCompiler.Properties.Shared.Cflags) == 0 {
2732 // Optimize out compiling common .o files twice for static+shared libraries
2733 mctx.AddInterVariantDependency(reuseObjTag, shared, static)
2734 sharedCompiler.baseCompiler.Properties.Srcs = nil
Colin Cross5dab8402016-07-27 10:30:21 -07002735 sharedCompiler.baseCompiler.Properties.Generated_sources = nil
Colin Crossc99deeb2016-04-11 15:06:20 -07002736 }
2737 }
Colin Crossca860ac2016-01-04 14:34:37 -08002738 } else if linker.buildStatic() {
2739 modules = mctx.CreateLocalVariations("static")
2740 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
2741 } else if linker.buildShared() {
2742 modules = mctx.CreateLocalVariations("shared")
2743 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
2744 } else {
2745 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
2746 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002747 }
2748 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002749 }
2750}
Colin Cross74d1ec02015-04-28 13:30:13 -07002751
2752// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
2753// modifies the slice contents in place, and returns a subslice of the original slice
2754func lastUniqueElements(list []string) []string {
2755 totalSkip := 0
2756 for i := len(list) - 1; i >= totalSkip; i-- {
2757 skip := 0
2758 for j := i - 1; j >= totalSkip; j-- {
2759 if list[i] == list[j] {
2760 skip++
2761 } else {
2762 list[j+skip] = list[j]
2763 }
2764 }
2765 totalSkip += skip
2766 }
2767 return list[totalSkip:]
2768}
Colin Cross06a931b2015-10-28 17:23:31 -07002769
2770var Bool = proptools.Bool