blob: 5622149d0c35a1e94650b129d0e170377634630f [file] [log] [blame]
mtklein7fbfbbe2016-07-21 12:25:45 -07001# Copyright 2016 Google Inc.
2#
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6declare_args() {
mtklein349cece2016-08-26 08:13:04 -07007 ar = "ar"
mtklein7fbfbbe2016-07-21 12:25:45 -07008 cc = "cc"
9 cxx = "c++"
mtklein8079ba62016-08-16 09:31:16 -070010
mtklein7d6fb2c2016-08-25 14:50:44 -070011 if (is_android) {
mtklein349cece2016-08-26 08:13:04 -070012 ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar"
mtklein7d6fb2c2016-08-25 14:50:44 -070013 cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang"
14 cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++"
15 }
16
herbb6318bf2016-09-16 13:29:57 -070017 windk = ""
18
Mike Klein121563e2016-10-04 17:09:13 -040019 extra_cflags = []
20 extra_cflags_c = []
21 extra_cflags_cc = []
22 extra_ldflags = []
mtkleincab0bb72016-08-26 13:43:19 -070023
mtklein60b7ab72016-09-20 12:09:12 -070024 cc_wrapper = ""
mtklein7fbfbbe2016-07-21 12:25:45 -070025}
26
mtkleinf347c512016-09-26 08:40:12 -070027is_clang = exec_script("is_clang.py",
28 [
29 cc,
30 cxx,
31 ],
32 "value")
33
mtkleinb9be9792016-09-16 14:44:18 -070034config("default") {
35 asmflags = []
36 cflags = []
37 cflags_c = []
38 cflags_cc = []
39 defines = []
40 ldflags = []
41
42 if (is_win) {
43 cflags += [
44 "/FS", # Preserve previous PDB behavior.
herbb6318bf2016-09-16 13:29:57 -070045 "/bigobj", # Some of our files are bigger than the regular limits.
46 ]
mtkleinb9be9792016-09-16 14:44:18 -070047 cflags_c += [ "/TC" ]
48 cflags_cc += [ "/TP" ]
49 defines += [
50 "_HAS_EXCEPTIONS=0",
51 "WIN32_LEAN_AND_MEAN",
52 "NOMINMAX",
herbb6318bf2016-09-16 13:29:57 -070053 ]
mtkleinb9be9792016-09-16 14:44:18 -070054 } else {
55 cflags += [
herbb6318bf2016-09-16 13:29:57 -070056 "-O1",
57 "-fstrict-aliasing",
58 "-fPIC",
59 "-fvisibility=hidden",
mtklein2b3c2a32016-09-08 08:39:34 -070060
herbb6318bf2016-09-16 13:29:57 -070061 "-Werror",
62 "-Wall",
63 "-Wextra",
64 "-Winit-self",
65 "-Wpointer-arith",
66 "-Wsign-compare",
67 "-Wvla",
68
69 "-Wno-deprecated-declarations",
70 "-Wno-unused-parameter",
mtklein2b3c2a32016-09-08 08:39:34 -070071 ]
mtkleinb9be9792016-09-16 14:44:18 -070072 cflags_cc += [
herbb6318bf2016-09-16 13:29:57 -070073 "-std=c++11",
74 "-fno-exceptions",
75 "-fno-threadsafe-statics",
76 "-fvisibility-inlines-hidden",
77
78 "-Wnon-virtual-dtor",
79 ]
mtkleinf347c512016-09-26 08:40:12 -070080 if (is_clang) {
81 cflags += [
82 "-Weverything",
83 "-Wno-unknown-warning-option", # Let older Clangs ignore newer Clangs' warnings.
84 ]
85
Mike Klein7bfc08b2016-09-27 07:41:45 -040086 if (is_android && target_cpu == "x86") {
87 # Clang seems to think new/malloc will only be 4-byte aligned on x86 Android.
88 # We're pretty sure it's actually 8-byte alignment.
89 cflags += [ "-Wno-over-aligned" ]
90 }
mtkleinf347c512016-09-26 08:40:12 -070091
92 cflags += [
93 "-Wno-cast-align",
Mike Klein2cc7f8d2016-09-26 15:49:04 -040094 "-Wno-conditional-uninitialized",
mtkleinf347c512016-09-26 08:40:12 -070095 "-Wno-conversion",
96 "-Wno-disabled-macro-expansion",
97 "-Wno-documentation",
98 "-Wno-documentation-unknown-command",
99 "-Wno-double-promotion",
100 "-Wno-exit-time-destructors", # TODO: OK outside libskia
mtkleinf347c512016-09-26 08:40:12 -0700101 "-Wno-float-conversion",
102 "-Wno-float-equal",
Mike Klein2cc7f8d2016-09-26 15:49:04 -0400103 "-Wno-format-nonliteral",
mtkleinf347c512016-09-26 08:40:12 -0700104 "-Wno-global-constructors", # TODO: OK outside libskia
mtkleinf347c512016-09-26 08:40:12 -0700105 "-Wno-gnu-zero-variadic-macro-arguments",
106 "-Wno-missing-prototypes",
107 "-Wno-missing-variable-declarations",
mtkleinf347c512016-09-26 08:40:12 -0700108 "-Wno-pedantic",
109 "-Wno-reserved-id-macro",
Mike Klein2cc7f8d2016-09-26 15:49:04 -0400110 "-Wno-shadow",
111 "-Wno-shift-sign-overflow",
mtkleinf347c512016-09-26 08:40:12 -0700112 "-Wno-sign-conversion",
113 "-Wno-switch-enum",
114 "-Wno-undef",
115 "-Wno-unreachable-code",
116 "-Wno-unreachable-code-break",
117 "-Wno-unreachable-code-return",
118 "-Wno-unused-macros",
119 "-Wno-unused-member-function",
120 ]
121 cflags_cc += [
122 "-Wno-abstract-vbase-init",
123 "-Wno-range-loop-analysis",
124 "-Wno-weak-vtables",
125 ]
126
127 # We are unlikely to want to fix these.
128 cflags += [
Mike Klein2cc7f8d2016-09-26 15:49:04 -0400129 "-Wno-covered-switch-default",
130 "-Wno-deprecated",
mtkleinf347c512016-09-26 08:40:12 -0700131 "-Wno-implicit-fallthrough",
132 "-Wno-missing-noreturn",
133 "-Wno-old-style-cast",
134 "-Wno-padded",
135 ]
136 cflags_cc += [
137 "-Wno-c++98-compat",
138 "-Wno-c++98-compat-pedantic",
Mike Klein2cc7f8d2016-09-26 15:49:04 -0400139 "-Wno-undefined-func-template",
mtkleinf347c512016-09-26 08:40:12 -0700140 ]
141 }
mtkleinb9be9792016-09-16 14:44:18 -0700142 }
herbb6318bf2016-09-16 13:29:57 -0700143
mtkleinb9be9792016-09-16 14:44:18 -0700144 if (current_cpu == "arm") {
145 cflags += [
146 "-march=armv7-a",
147 "-mfpu=neon",
148 "-mthumb",
149 ]
150 } else if (current_cpu == "mipsel") {
151 cflags += [
152 "-march=mips32r2",
153 "-mdspr2",
154 ]
155 } else if (current_cpu == "x86") {
156 asmflags += [ "-m32" ]
157 cflags += [
158 "-m32",
159 "-msse2",
160 "-mfpmath=sse",
161 ]
162 ldflags += [ "-m32" ]
163 }
herbb6318bf2016-09-16 13:29:57 -0700164
mtkleinb9be9792016-09-16 14:44:18 -0700165 if (is_android) {
166 asmflags += [
167 "--target=$ndk_target",
168 "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin",
169 ]
170 cflags += [
171 "--sysroot=$ndk/platforms/$ndk_platform",
172 "--target=$ndk_target",
173 "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin",
174 ]
175 cflags_cc += [
176 "-isystem$ndk/sources/android/support/include",
177 "-isystem$ndk/sources/cxx-stl/llvm-libc++/libcxx/include",
178 ]
179 ldflags += [
180 "--sysroot=$ndk/platforms/$ndk_platform",
181 "--target=$ndk_target",
182 "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin",
183 "-pie",
184 ]
185 lib_dirs = [
186 "$ndk/sources/cxx-stl/llvm-libc++/libs/$ndk_stdlib",
187 "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/lib/gcc/$ndk_target/4.9.x",
188 ]
herbb6318bf2016-09-16 13:29:57 -0700189
mtkleinb9be9792016-09-16 14:44:18 -0700190 libs = [
191 # Order matters here! Keep these three in exactly this order.
192 "c++_static",
193 "c++abi",
194 "android_support",
195 ]
196 if (target_cpu == "arm") {
197 libs += [ "unwind" ]
mtklein2b3c2a32016-09-08 08:39:34 -0700198 }
199 }
mtklein7fbfbbe2016-07-21 12:25:45 -0700200
mtkleinb9be9792016-09-16 14:44:18 -0700201 if (is_linux) {
202 libs = [ "pthread" ]
203 }
204
205 if (sanitize != "") {
206 # You can either pass the sanitizers directly, e.g. "address,undefined",
207 # or pass one of the couple common aliases used by the bots.
208 sanitizers = sanitize
209 if (sanitize == "ASAN") {
210 sanitizers = "address,bool,function,integer-divide-by-zero,nonnull-attribute,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound,vptr"
211 } else if (sanitize == "TSAN") {
212 sanitizers = "thread"
213 } else if (sanitize == "MSAN") {
214 sanitizers = "memory"
215 }
216
217 cflags += [
218 "-fsanitize=$sanitizers",
219 "-fno-sanitize-recover=$sanitizers",
220 "-fsanitize-blacklist=" + rebase_path("../tools/xsan.blacklist"),
221 ]
222 ldflags += [ "-fsanitize=$sanitizers" ]
223 if (sanitizers == "memory") {
224 cflags += [ "-fsanitize-memory-track-origins" ]
225 cflags_cc += [ "-stdlib=libc++" ]
226 ldflags += [ "-stdlib=libc++" ]
227 }
228 }
229}
230
Mike Klein121563e2016-10-04 17:09:13 -0400231config("extra_flags") {
232 cflags = extra_cflags
233 cflags_c = extra_cflags_c
234 cflags_cc = extra_cflags_cc
235 ldflags = extra_ldflags
236}
237
mtkleinb9be9792016-09-16 14:44:18 -0700238config("debug_symbols") {
239 # It's annoying to wait for full debug symbols to push over
240 # to Android devices. -gline-tables-only is a lot slimmer.
241 if (is_android) {
242 cflags = [ "-gline-tables-only" ]
243 } else if (!is_win) {
244 cflags = [ "-g" ]
245 }
246}
247
248config("no_rtti") {
249 if (sanitize != "ASAN") { # -fsanitize=vptr requires RTTI
250 if (!is_win) {
251 cflags_cc = [ "-fno-rtti" ]
252 }
253 }
254}
255
256config("release") {
257 if (!is_win) {
herbb6318bf2016-09-16 13:29:57 -0700258 cflags = [ "-O3" ]
herbb6318bf2016-09-16 13:29:57 -0700259 }
mtkleinb9be9792016-09-16 14:44:18 -0700260 defines = [ "NDEBUG" ]
mtklein7fbfbbe2016-07-21 12:25:45 -0700261}
262
263config("executable") {
264 if (is_mac) {
265 ldflags = [ "-Wl,-rpath,@loader_path/." ]
266 } else if (is_linux) {
mtkleina846c722016-09-15 10:44:15 -0700267 ldflags = [
268 "-rdynamic",
269 "-Wl,-rpath,\$ORIGIN",
270 ]
mtklein7fbfbbe2016-07-21 12:25:45 -0700271 }
272}
273
herbb6318bf2016-09-16 13:29:57 -0700274toolchain("msvc") {
mtkleinb9be9792016-09-16 14:44:18 -0700275 vc = "$windk\VC\bin\amd64\cl.exe"
herbb6318bf2016-09-16 13:29:57 -0700276 vlink = "$windk\VC\bin\amd64\link.exe"
mtkleinb9be9792016-09-16 14:44:18 -0700277 vlib = "$windk\VC\bin\amd64\lib.exe"
278
herbb6318bf2016-09-16 13:29:57 -0700279 # TODO: add a python function that generates the includes using <VSPATH>/win_sdk/bin/SetEnv.<cpu>.json
280 windk_include_dirs = "/I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\um /I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\shared /I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\winrt /I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\ucrt /I$windk\win_sdk\bin\..\..\VC\include /I$windk\win_sdk\bin\..\..\VC\atlmfc\include "
281
282 tool("cc") {
283 rspfile = "{{output}}.rsp"
284 precompiled_header_type = "msvc"
285 pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
286
287 # Label names may have spaces in them so the pdbname must be quoted. The
288 # source and output don't need to be quoted because GN knows they're a
289 # full file name and will quote automatically when necessary.
mtkleinb9be9792016-09-16 14:44:18 -0700290
herbb6318bf2016-09-16 13:29:57 -0700291 command = "$vc /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
292 depsformat = "msvc"
293 description = "CC {{output}}"
294 outputs = [
295 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
296 # "$object_subdir/{{source_name_part}}.obj",
297 ]
298 rspfile_content = "$windk_include_dirs {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
299 }
300
301 tool("cxx") {
302 rspfile = "{{output}}.rsp"
303 precompiled_header_type = "msvc"
304 pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
305
306 # Label names may have spaces in them so the pdbname must be quoted. The
307 # source and output don't need to be quoted because GN knows they're a
308 # full file name and will quote automatically when necessary.
309 command = "$vc /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
310 depsformat = "msvc"
311 description = "C++ {{output}}"
312 outputs = [
313 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
314 ]
315 rspfile_content = "$windk_include_dirs {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
mtkleinb9be9792016-09-16 14:44:18 -0700316 }
herbb6318bf2016-09-16 13:29:57 -0700317
318 tool("alink") {
319 rspfile = "{{output}}.rsp"
mtkleinb9be9792016-09-16 14:44:18 -0700320
herbb6318bf2016-09-16 13:29:57 -0700321 # gyp_win_tool_path = rebase_path("../third_party/externals/gyp/pylib/gyp/win_tool.py")
322 command = "$vlib /nologo {{arflags}} /OUT:{{output}} @$rspfile"
323 description = "LIB {{output}}"
324 outputs = [
325 # Ignore {{output_extension}} and always use .lib, there's no reason to
326 # allow targets to override this extension on Windows.
327 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
328 ]
329 default_output_extension = ".lib"
330 default_output_dir = "{{target_out_dir}}"
331
332 # The use of inputs_newline is to work around a fixed per-line buffer
333 # size in the linker.
334 rspfile_content = "{{inputs_newline}}"
335 }
336
337 tool("link") {
338 exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
339 pdbname = "$exename.pdb"
340 rspfile = "$exename.rsp"
341
342 # gyp_win_tool_path = rebase_path("../third_party/externals/gyp/pylib/gyp/win_tool.py")
343 command = "$vlink /nologo /OUT:$exename /PDB:$pdbname @$rspfile"
344
345 default_output_extension = ".exe"
346 default_output_dir = "{{root_out_dir}}"
347 description = "LINK {{output}}"
348 outputs = [
349 #"{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
350 exename,
351 ]
mtkleinb9be9792016-09-16 14:44:18 -0700352
herbb6318bf2016-09-16 13:29:57 -0700353 #if (symbol_level != 0) {
354 # outputs += [ pdbname ]
355 #}
356 #runtime_outputs = outputs
357
358 # The use of inputs_newline is to work around a fixed per-line buffer
359 # size in the linker.
360 rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
361 }
362
herbb6318bf2016-09-16 13:29:57 -0700363 tool("stamp") {
364 win_stamp_path = rebase_path("win_stamp.py")
365 command = "python $win_stamp_path {{output}}"
366 }
367}
368
mtklein7fbfbbe2016-07-21 12:25:45 -0700369toolchain("gcc_like") {
370 lib_switch = "-l"
371 lib_dir_switch = "-L"
372
373 tool("cc") {
374 depfile = "{{output}}.d"
Mike Klein121563e2016-10-04 17:09:13 -0400375 command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700376 depsformat = "gcc"
377 outputs = [
378 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
379 ]
Mike Klein121563e2016-10-04 17:09:13 -0400380 description = "$cc_wrapper $cc ... -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700381 }
382
383 tool("cxx") {
384 depfile = "{{output}}.d"
Mike Klein121563e2016-10-04 17:09:13 -0400385 command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700386 depsformat = "gcc"
387 outputs = [
388 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
389 ]
Mike Klein121563e2016-10-04 17:09:13 -0400390 description = "$cc_wrapper $cxx ... -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700391 }
392
393 tool("asm") {
394 depfile = "{{output}}.d"
mtklein60b7ab72016-09-20 12:09:12 -0700395 command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700396 depsformat = "gcc"
397 outputs = [
398 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
399 ]
mtklein60b7ab72016-09-20 12:09:12 -0700400 description = "$cc_wrapper $cc ... -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700401 }
402
403 tool("alink") {
mtklein349cece2016-08-26 08:13:04 -0700404 command = "rm -f {{output}} && $ar rcs {{output}} {{inputs}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700405 outputs = [
mtklein5db44aa2016-07-29 09:10:31 -0700406 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
mtklein7fbfbbe2016-07-21 12:25:45 -0700407 ]
408 default_output_extension = ".a"
409 output_prefix = "lib"
mtklein349cece2016-08-26 08:13:04 -0700410 description = "$ar {{output}} ..."
mtklein7fbfbbe2016-07-21 12:25:45 -0700411 }
412
413 tool("solink") {
414 soname = "{{target_output_name}}{{output_extension}}"
415
416 rpath = "-Wl,-soname,$soname"
417 if (is_mac) {
418 rpath = "-Wl,-install_name,@rpath/$soname"
419 }
420
Mike Klein121563e2016-10-04 17:09:13 -0400421 command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700422 outputs = [
423 "{{root_out_dir}}/$soname",
424 ]
425 output_prefix = "lib"
426 default_output_extension = ".so"
Mike Klein121563e2016-10-04 17:09:13 -0400427 description = "$cc_wrapper $cxx -shared ... -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700428 }
429
430 tool("link") {
Mike Klein121563e2016-10-04 17:09:13 -0400431 command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700432 outputs = [
433 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
434 ]
Mike Klein121563e2016-10-04 17:09:13 -0400435 description = "$cc_wrapper $cxx ... -o {{output}}"
mtklein7fbfbbe2016-07-21 12:25:45 -0700436 }
437
438 tool("stamp") {
439 command = "touch {{output}}"
440 }
441
442 tool("copy") {
443 command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})"
444 }
445}