1# 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() {
7  extra_asmflags = []
8  extra_cflags = []
9  extra_cflags_c = []
10  extra_cflags_cc = []
11  extra_ldflags = []
12
13  malloc = ""
14}
15
16if (is_ios) {
17  if (is_tvos) {
18    sdk = "appletvos"
19    if (target_cpu == "x86" || target_cpu == "x64") {
20      sdk = "appletvsimulator"
21    }
22  } else {
23    sdk = "iphoneos"
24    if (target_cpu == "x86" || target_cpu == "x64") {
25      sdk = "iphonesimulator"
26    }
27  }
28  ios_sysroot = exec_script("find_ios_sysroot.py", [ sdk ], "trim string")
29}
30
31config("default") {
32  asmflags = []
33  cflags = []
34  cflags_c = []
35  cflags_cc = []
36  defines = []
37  ldflags = []
38  libs = []
39
40  if (is_win) {
41    cflags += [
42      "/bigobj",  # Some of our files are bigger than the regular limits.
43      "/WX",  # Treat warnings as errors.
44      "/utf-8",  # Set Source and Executable character sets to UTF-8.
45    ]
46    if (is_clang) {
47      cflags += [ "-fms-compatibility-version=19" ]  # 2015
48    }
49    defines += [
50      "_CRT_SECURE_NO_WARNINGS",  # Disables warnings about sscanf().
51      "_HAS_EXCEPTIONS=0",  # Disables exceptions in MSVC STL.
52      "WIN32_LEAN_AND_MEAN",
53      "NOMINMAX",
54    ]
55
56    if (msvc == 2015) {
57      _include_dirs = [ "$win_vc/include" ]
58    } else {  # 2017
59      _include_dirs = [ "$win_vc/Tools/MSVC/$win_toolchain_version/include" ]
60    }
61    _include_dirs += [
62      "$win_sdk/Include/$win_sdk_version/shared",
63      "$win_sdk/Include/$win_sdk_version/ucrt",
64      "$win_sdk/Include/$win_sdk_version/um",
65      "$win_sdk/Include/$win_sdk_version/winrt",
66    ]
67
68    if (is_clang) {
69      foreach(dir, _include_dirs) {
70        cflags += [
71          "-imsvc",
72          dir,
73        ]
74      }
75    } else {
76      include_dirs = _include_dirs
77    }
78
79    lib_dirs = [
80      "$win_sdk/Lib/$win_sdk_version/ucrt/$target_cpu",
81      "$win_sdk/Lib/$win_sdk_version/um/$target_cpu",
82    ]
83    if (msvc == 2015) {
84      if (target_cpu == "x86") {
85        lib_dirs += [ "$win_vc/lib" ]
86      } else {
87        lib_dirs += [ "$win_vc/lib/amd64" ]
88      }
89    } else {  # 2017
90      lib_dirs +=
91          [ "$win_vc/Tools/MSVC/$win_toolchain_version/lib/$target_cpu" ]
92    }
93  } else {
94    cflags += [
95      "-fstrict-aliasing",
96      "-fPIC",
97      "-Werror",
98    ]
99    cflags_cc += [ "-std=c++11" ]
100
101    # The main idea is to slim the exported API, but these flags also improve link time on Mac.
102    # These would make stack traces worse on Linux, so we don't just set them willy-nilly.
103    if (is_component_build || is_ios || is_mac) {
104      cflags += [ "-fvisibility=hidden" ]
105      cflags_cc += [ "-fvisibility-inlines-hidden" ]
106    }
107  }
108
109  if (current_cpu == "arm") {
110    cflags += [
111      "-march=armv7-a",
112      "-mfpu=neon",
113      "-mthumb",
114    ]
115  } else if (current_cpu == "x86" && !is_win) {
116    asmflags += [ "-m32" ]
117    cflags += [
118      "-m32",
119      "-msse2",
120      "-mfpmath=sse",
121    ]
122    ldflags += [ "-m32" ]
123  }
124
125  if (malloc != "" && !is_win) {
126    cflags += [
127      "-fno-builtin-malloc",
128      "-fno-builtin-calloc",
129      "-fno-builtin-realloc",
130      "-fno-builtin-free",
131    ]
132    libs += [ malloc ]
133  }
134
135  if (is_android) {
136    asmflags += [ "--target=$ndk_target" ]
137    cflags += [
138      "--sysroot=$ndk/sysroot",
139      "-isystem$ndk/sysroot/usr/include/$ndk_target",
140      "-D__ANDROID_API__=$ndk_api",
141      "--target=$ndk_target",
142    ]
143    cflags_cc += [
144      "-isystem$ndk/sources/cxx-stl/llvm-libc++/include",
145      "-isystem$ndk/sources/cxx-stl/llvm-libc++abi/include",
146      "-isystem$ndk/sources/android/support/include",
147    ]
148    ldflags += [
149      "--sysroot=$ndk/platforms/$ndk_platform",
150      "--target=$ndk_target",
151      "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin",
152    ]
153    lib_dirs = [
154      "$ndk/sources/cxx-stl/llvm-libc++/libs/$ndk_stdlib",
155      "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/lib/gcc/$ndk_target/4.9.x",
156    ]
157
158    libs += [
159      "c++_static",
160      "c++abi",
161      "android_support",
162    ]
163  }
164
165  if (is_ios) {
166    _target = target_cpu
167    if (target_cpu == "arm") {
168      _target = "armv7"
169    } else if (target_cpu == "x86") {
170      _target = "i386"
171    } else if (target_cpu == "x64") {
172      _target = "x86_64"
173    }
174    asmflags += [
175      "-isysroot",
176      ios_sysroot,
177      "-arch",
178      _target,
179    ]
180    cflags += [
181      "-isysroot",
182      ios_sysroot,
183      "-arch",
184      _target,
185    ]
186    cflags_cc += [ "-stdlib=libc++" ]
187    ldflags += [
188      "-isysroot",
189      ios_sysroot,
190      "-arch",
191      _target,
192      "-stdlib=libc++",
193    ]
194    libs += [ "objc" ]
195  }
196
197  if (is_linux) {
198    libs += [ "pthread" ]
199  }
200  if (is_mac) {
201    # Disable linker warnings.  They're usually just annoyances like,
202    #   ld: warning: text-based stub file
203    #     /System/Library/Frameworks/foo.framework/foo.tbd and library file
204    #     /System/Library/Frameworks/foo.framework/foo are out of sync.
205    #     Falling back to library file for linking.
206    ldflags += [ "-Wl,-w" ]
207  }
208
209  if (sanitize != "") {
210    # You can either pass the sanitizers directly, e.g. "address,undefined",
211    # or pass one of the couple common aliases used by the bots.
212    sanitizers = sanitize
213    if (sanitize == "ASAN" || sanitize == "UBSAN") {
214      # ASAN implicitly runs all UBSAN checks also.
215      sanitizers = "bool,float-cast-overflow,integer-divide-by-zero,nonnull-attribute,null,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound"
216      if (!is_mac && !is_win) {
217        sanitizers += ",function"  # Not supported on Mac or Win.
218      }
219      if (!is_win) {
220        sanitizers += ",vptr"  # Not supported on Win.
221      }
222      if (!is_debug && !is_win) {
223        # No-op with somewhat annoying warning at -O0.
224        # Seems to be broken on Win.
225        sanitizers += ",object-size"
226      }
227      if (sanitize == "ASAN") {
228        sanitizers += ",address"
229      }
230      if (is_android) {
231        # Android only easily supports address for now
232        # UBSAN runs into linking errors
233        sanitizers = "address"
234
235        # recommended by
236        # https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid
237        cflags += [ "-fno-omit-frame-pointer" ]
238      }
239    } else if (sanitize == "TSAN") {
240      sanitizers = "thread"
241    } else if (sanitize == "MSAN") {
242      sanitizers = "memory"
243    }
244
245    cflags += [
246      "-fsanitize=$sanitizers",
247      "-fno-sanitize-recover=$sanitizers",
248    ]
249    if (!is_win) {
250      cflags += [ "-fno-omit-frame-pointer" ]
251    }
252    if (is_linux) {
253      cflags_cc += [ "-stdlib=libc++" ]
254      ldflags += [ "-stdlib=libc++" ]
255    }
256    ldflags += [ "-fsanitize=$sanitizers" ]
257    if (sanitizers == "memory") {
258      cflags += [ "-fsanitize-memory-track-origins" ]
259    }
260  }
261}
262
263config("no_exceptions") {
264  # Exceptions are disabled by default on Windows.  (Use /EHsc to enable them.)
265  if (!is_win) {
266    cflags_cc = [ "-fno-exceptions" ]
267  }
268}
269
270config("warnings") {
271  cflags = []
272  cflags_cc = []
273  cflags_objc = []
274  cflags_objcc = []
275  if (is_win) {
276    cflags += [
277      "/W3",  # Turn on lots of warnings.
278
279      # Disable a bunch of warnings:
280      "/wd4244",  # conversion from 'float' to 'int', possible loss of data
281      "/wd4267",  # conversion from 'size_t' to 'int', possible loss of data
282      "/wd4800",  # forcing value to bool 'true' or 'false' (performance warning)
283
284      # Probably only triggers when /EHsc is enabled.
285      "/wd4291",  # no matching operator delete found;
286                  # memory will not be freed if initialization throws an exception
287    ]
288  } else {
289    cflags += [
290      "-Wall",
291      "-Wextra",
292      "-Winit-self",
293      "-Wpointer-arith",
294      "-Wsign-compare",
295      "-Wvla",
296
297      "-Wno-deprecated-declarations",
298      "-Wno-maybe-uninitialized",
299    ]
300    cflags_cc += [ "-Wnon-virtual-dtor" ]
301  }
302
303  if (is_clang) {
304    cflags += [
305      "-Weverything",
306      "-Wno-unknown-warning-option",  # Let older Clangs ignore newer Clangs' warnings.
307    ]
308
309    if (target_cpu == "arm" && is_ios) {
310      # Clang seems to think new/malloc will only be 4-byte aligned on 32-bit iOS.
311      # We're pretty sure it's actually 8-byte alignment.
312      cflags += [ "-Wno-over-aligned" ]
313    }
314    if (target_cpu == "x86" && is_android) {
315      # Clang seems to think new/malloc will only be 4-byte aligned on 32-bit x86 Android builds.
316      # We're pretty sure it's actually 8-byte alignment.  See OverAlignedTest.cpp for more info.
317      cflags += [ "-Wno-over-aligned" ]
318    }
319
320    # Shouldn't be necessary for local builds. With distributed Windows builds, files may lose
321    # their case during copy, causing case-sensitivity mismatch on remote machines.
322    cflags += [
323      "-Wno-nonportable-include-path",
324      "-Wno-nonportable-system-include-path",
325    ]
326
327    # TODO: These would all be really great warnings to turn on.
328    cflags += [
329      "-Wno-cast-align",
330      "-Wno-cast-qual",
331      "-Wno-conversion",
332      "-Wno-disabled-macro-expansion",
333      "-Wno-documentation",
334      "-Wno-documentation-unknown-command",
335      "-Wno-double-promotion",
336      "-Wno-exit-time-destructors",  # TODO: OK outside libskia
337      "-Wno-float-equal",
338      "-Wno-format-nonliteral",
339      "-Wno-global-constructors",  # TODO: OK outside libskia
340      "-Wno-missing-prototypes",
341      "-Wno-missing-variable-declarations",
342      "-Wno-pedantic",
343      "-Wno-reserved-id-macro",
344      "-Wno-shadow",
345      "-Wno-shift-sign-overflow",
346      "-Wno-signed-enum-bitfield",
347      "-Wno-switch-enum",
348      "-Wno-undef",
349      "-Wno-unreachable-code",
350      "-Wno-unreachable-code-break",
351      "-Wno-unreachable-code-return",
352      "-Wno-unused-macros",
353      "-Wno-unused-member-function",
354      "-Wno-unused-template",
355      "-Wno-zero-as-null-pointer-constant",
356    ]
357    cflags_cc += [
358      "-Wno-abstract-vbase-init",
359      "-Wno-weak-vtables",
360    ]
361
362    # We are unlikely to want to fix these.
363    cflags += [
364      "-Wno-covered-switch-default",
365      "-Wno-deprecated",
366      "-Wno-missing-noreturn",
367      "-Wno-old-style-cast",
368      "-Wno-padded",
369      "-Wno-newline-eof",
370    ]
371    cflags_cc += [
372      "-Wno-c++98-compat",
373      "-Wno-c++98-compat-pedantic",
374      "-Wno-undefined-func-template",
375    ]
376    cflags_objc += [
377      "-Wno-direct-ivar-access",
378      "-Wno-objc-interface-ivars",
379    ]
380    cflags_objcc += [
381      "-Wno-direct-ivar-access",
382      "-Wno-objcc-interface-ivars",
383    ]
384  }
385  if (!is_win || is_clang) {
386    cflags += [ "-Wno-implicit-fallthrough" ]
387  }
388}
389config("warnings_except_public_headers") {
390  if (!is_win || is_clang) {
391    cflags = [ "-Wno-unused-parameter" ]
392  }
393}
394
395config("extra_flags") {
396  asmflags = extra_asmflags
397  cflags = extra_cflags
398  cflags_c = extra_cflags_c
399  cflags_cc = extra_cflags_cc
400  ldflags = extra_ldflags
401}
402
403config("debug_symbols") {
404  # It's annoying to wait for full debug symbols to push over
405  # to Android devices.  -gline-tables-only is a lot slimmer.
406  if (is_android) {
407    cflags = [
408      "-gline-tables-only",
409      "-funwind-tables",  # Helps make in-process backtraces fuller.
410    ]
411  } else if (is_win) {
412    cflags = [ "/Z7" ]
413    ldflags = [ "/DEBUG:FASTLINK" ]
414  } else {
415    cflags = [ "-g" ]
416  }
417}
418
419config("no_rtti") {
420  if (sanitize != "ASAN") {  # -fsanitize=vptr requires RTTI
421    if (is_win) {
422      cflags_cc = [ "/GR-" ]
423    } else {
424      cflags_cc = [ "-fno-rtti" ]
425    }
426  }
427}
428
429config("release") {
430  if (is_win) {
431    cflags = [
432      "/O2",
433      "/Zc:inline",
434    ]
435    ldflags = [
436      "/OPT:ICF",
437      "/OPT:REF",
438    ]
439  } else {
440    cflags = [
441      "-O3",
442      "-fdata-sections",
443      "-ffunction-sections",
444    ]
445    if (is_mac || is_ios) {
446      ldflags = [ "-dead_strip" ]
447    } else {
448      ldflags = [ "-Wl,--gc-sections" ]
449    }
450    if (target_cpu == "wasm") {
451      # The compiler asks us to add an optimization flag to both cflags
452      # and ldflags to cut down on the local variables,
453      # for performance reasons.
454      # The "linking" step is the conversion to javascript.
455      ldflags += [ "-O3" ]
456    }
457  }
458  defines = [ "NDEBUG" ]
459}
460
461config("executable") {
462  if (is_android) {
463    ldflags = [
464      "-pie",
465      "-rdynamic",
466    ]
467  } else if (is_mac) {
468    ldflags = [ "-Wl,-rpath,@loader_path/." ]
469  } else if (is_linux) {
470    ldflags = [
471      "-rdynamic",
472      "-Wl,-rpath,\$ORIGIN",
473    ]
474  } else if (is_win) {
475    ldflags = [
476      "/SUBSYSTEM:CONSOLE",  # Quiet "no subsystem specified; CONSOLE assumed".
477      "/INCREMENTAL:NO",  # Quiet warnings about failing to incrementally link by never trying to.
478    ]
479  }
480}
481