• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/c++/c++.gni")
6import("//build/config/clang/clang.gni")
7import("//build/config/compiler/compiler.gni")
8import("//build/config/coverage/coverage.gni")
9import("//build/config/sanitizers/sanitizers.gni")
10import("//build/toolchain/cc_wrapper.gni")
11import("//build/toolchain/toolchain.gni")
12
13import("//build/misc/overrides/build.gni")
14
15if (current_cpu == "arm" || current_cpu == "arm64") {
16  import("//build/config/arm.gni")
17}
18if (is_ohos) {
19  import("//build/config/ohos/config.gni")
20}
21if (is_mac) {
22  import("//build/config/mac/symbols.gni")
23}
24
25declare_args() {
26  # Default to warnings as errors for default workflow, where we catch
27  # warnings with known toolchains. Allow overriding this e.g. for Chromium
28  # builds on Linux that could use a different version of the compiler.
29  # With GCC, warnings in no-Chromium code are always not treated as errors.
30  treat_warnings_as_errors = true
31
32  # Whether to use the binary binutils checked into third_party/binutils.
33  # These are not multi-arch so cannot be used except on x86 and x86-64 (the
34  # only two architectures that are currently checked in). Turn this off when
35  # you are using a custom toolchain and need to control -B in cflags.
36  linux_use_bundled_binutils =
37      linux_use_bundled_binutils_override && is_linux &&
38      (current_cpu == "x64" || current_cpu == "x86")
39  binutils_path = rebase_path("//third_party/binutils/Linux_x64/Release/bin",
40                              root_build_dir)
41
42  # Compile in such a way as to make it possible for the profiler to unwind full
43  # stack frames. Setting this flag has a large effect on the performance of the
44  # generated code than just setting profiling, but gives the profiler more
45  # information to analyze.
46  # Requires profiling to be set to true.
47  enable_full_stack_frames_for_profiling = false
48
49  # When we are going to use gold we need to find it.
50  # This is initialized below, after use_gold might have been overridden.
51  gold_path = false
52
53  if (is_win) {
54    # Whether the VS xtree header has been patched to disable warning 4702. If
55    # it has, then we don't need to disable 4702 (unreachable code warning).
56    # The patch is preapplied to the internal toolchain and hence all bots.
57    msvs_xtree_patched = false
58  }
59
60  # Enable fatal linker warnings. Building Chromium with certain versions
61  # of binutils can cause linker warning.
62  # See: https://bugs.chromium.org/p/chromium/issues/detail?id=457359
63  fatal_linker_warnings = true
64
65  # Build with C++ RTTI enabled. Chromium builds without RTTI by default,
66  # but some sanitizers are known to require it, like CFI diagnostics
67  # and UBsan variants.
68  use_rtti = use_cfi_diag || is_ubsan_vptr || is_ubsan_security
69
70  # AFDO (Automatic Feedback Directed Optimizer) is a form of profile-guided
71  # optimization that GCC supports. It used by ChromeOS in their official
72  # builds. To use it, set auto_profile_path to the path to a file containing
73  # the needed gcov profiling data.
74  auto_profile_path = ""
75
76  # Optimize symbol files for maximizing goma cache hit rate. This is on by
77  # default when goma is enabled on Linux and Windows.
78  # But setting this to true may make it harder to debug binaries on Linux.
79  # See below reference for detail.
80  strip_absolute_paths_from_debug_symbols = false
81
82  # Allow projects that wish to stay on C++11 to override Chromium's default.
83  use_cxx11 = false
84
85  # Path to an AFDO profile to use while building with clang, if any. Empty
86  # implies none.
87  clang_sample_profile_path = ""
88
89  # Some configurations have default sample profiles. If this is true and
90  # clang_sample_profile_path is empty, we'll fall back to the default.
91  #
92  # We currently only have default profiles for Chromium in-tree, so we disable
93  # this by default for all downstream projects, since these profiles are likely
94  # nonsensical for said projects.
95  clang_use_default_sample_profile =
96      is_official_build && (is_ohos || is_desktop_linux)
97
98  # Turn this on to have the compiler output extra timing information.
99  compiler_timing = false
100
101  # Set to true to pass --no-rosegment to lld. This is a workaround
102  # for a KI issue in Valgrind,
103  # https://bugs.kde.org/show_bug.cgi?id=384727
104  ro_segment_workaround_for_valgrind = false
105
106  # Turn this on to use ghash feature of lld for faster debug link on Windows.
107  # http://blog.llvm.org/2018/01/improving-link-time-on-windows-with.html
108  use_ghash = false
109
110  # Whether to enable ThinLTO optimizations. Turning ThinLTO optimizations on
111  # can substantially increase link time and binary size, but they generally
112  # also make binaries a fair bit faster.
113  thin_lto_enable_optimizations = is_chromeos
114
115  # By default only the binaries in official builds get build IDs.
116  force_local_build_id = true
117}
118
119declare_args() {
120  use_cxx11_on_ohos = use_cxx11
121}
122
123declare_args() {
124  # Set to true to use icf, Identical Code Folding.
125  #
126  # icf=all is broken in older golds, see
127  # https://sourceware.org/bugzilla/show_bug.cgi?id=17704
128  # See also https://crbug.com/663886
129  # `linux_use_bundled_binutils` is to avoid breaking Linux destroys which may
130  # still have a buggy gold.
131  # chromeos binutils has been patched with the fix, so always use icf there.
132  # The bug only affects x86 and x64, so we can still use ICF when targeting
133  # other architectures.
134  #
135  # lld doesn't have the bug.
136  use_icf =
137      is_posix && !using_sanitizer && !use_clang_coverage &&
138      !(is_ohos && use_order_profiling) &&
139      (use_lld ||
140       (use_gold && ((!is_ohos && linux_use_bundled_binutils) || is_chromeos ||
141                     !(current_cpu == "x86" || current_cpu == "x64"))))
142}
143
144# Apply the default logic for these values if they were not set explicitly.
145if (gold_path == false) {
146  if (use_gold) {
147    gold_path = rebase_path("//third_party/binutils/Linux_x64/Release/bin",
148                            root_build_dir)
149  } else {
150    gold_path = ""
151  }
152}
153
154if (use_debug_fission == "default") {
155  use_debug_fission = is_debug && !is_ohos && !is_win &&
156                      (use_gold || use_lld) && cc_wrapper == ""
157}
158
159# default_include_dirs ---------------------------------------------------------
160#
161# This is a separate config so that third_party code (which would not use the
162# source root and might have conflicting versions of some headers) can remove
163# this and specify their own include paths.
164config("default_include_dirs") {
165  include_dirs = [
166    "${root_out_dir}/override/third_party",
167    "//",
168    root_gen_dir,
169  ]
170}
171
172# compiler ---------------------------------------------------------------------
173#
174# Base compiler configuration.
175#
176# See also "runtime_library" below for related stuff and a discussion about
177# where stuff should go. Put warning related stuff in the "warnings" config.
178
179config("compiler") {
180  asmflags = []
181  cflags = []
182  cflags_c = []
183  cflags_cc = []
184  cflags_objc = []
185  cflags_objcc = []
186  ldflags = []
187  defines = []
188  configs = []
189  inputs = []
190
191  # System-specific flags. If your compiler flags apply to one of the
192  # categories here, add it to the associated file to keep this shared config
193  # smaller.
194  if (is_win) {
195    configs += [ "//build/config/win:compiler" ]
196  } else if (is_ohos) {
197    configs += [ "//build/config/ohos:compiler" ]
198  } else if (is_linux) {
199    configs += [ "//build/config/linux:compiler" ]
200  } else if (is_nacl) {
201    configs += [ "//build/config/nacl:compiler" ]
202  } else if (is_mac) {
203    configs += [ "//build/config/mac:compiler" ]
204  } else if (current_os == "aix") {
205    configs += [ "//build/config/aix:compiler" ]
206  } else if (is_mingw) {
207    configs += [ "//build/config/mingw:compiler" ]
208  }
209
210  configs += [
211    # See the definitions below.
212    ":compiler_cpu_abi",
213    ":compiler_codegen",
214  ]
215
216  if (is_ohos && is_standard_system && is_clang &&
217      (target_cpu == "arm" || target_cpu == "arm64")) {
218    ldflags += [ "-Wl,--pack-dyn-relocs=android+relr" ]
219  }
220
221  # In general, Windows is totally different, but all the other builds share
222  # some common GCC configuration.
223  if (!is_win) {
224    # Common POSIX compiler flags setup.
225    # --------------------------------
226    cflags += [ "-fno-strict-aliasing" ]  # See http://crbug.com/32204
227
228    # Stack protection.
229    if (is_mac) {
230      # The strong variant of the stack protector significantly increases
231      # binary size, so only enable it in debug mode.
232      if (is_debug) {
233        cflags += [ "-fstack-protector-strong" ]
234      } else {
235        cflags += [ "-fstack-protector" ]
236      }
237    } else if (is_posix && !is_chromeos && !is_nacl) {
238      cflags += [ "--param=ssp-buffer-size=4" ]
239
240      # The x86 toolchain currently has problems with stack-protector.
241      if (is_ohos && current_cpu == "x86") {
242        cflags += [ "-fno-stack-protector" ]
243      } else if (is_mingw) {
244        cflags += [ "-fno-stack-protector" ]
245      } else if (current_os != "aix") {
246        # Not available on aix.
247        cflags += [ "-fstack-protector-strong" ]
248      }
249    }
250
251    # Linker warnings.
252    if (fatal_linker_warnings && !(is_chromeos && current_cpu == "arm") &&
253        !(is_ohos && use_order_profiling) && !is_mac && current_os != "aix" &&
254        !is_mingw) {
255      ldflags += [ "-Wl,--fatal-warnings" ]
256    }
257  } else {
258    cflags += [
259      # Assume UTF-8 by default to avoid code page dependencies.
260      "/utf-8",
261    ]
262    if (is_clang) {
263      # Don't look for includes in %INCLUDE%.
264      cflags += [ "/X" ]
265    }
266  }
267
268  # Eliminate build metadata (__DATE__, __TIME__ and __TIMESTAMP__) for
269  # deterministic build.  See https://crbug.com/314403
270  if (!is_official_build) {
271    if (is_win && !is_clang) {
272      cflags += [
273        "/wd4117",  # Trying to define or undefine a predefined macro.
274        "/D__DATE__=",
275        "/D__TIME__=",
276        "/D__TIMESTAMP__=",
277      ]
278    } else {
279      cflags += [
280        "-Wno-builtin-macro-redefined",
281        "-D__DATE__=",
282        "-D__TIME__=",
283        "-D__TIMESTAMP__=",
284      ]
285    }
286  }
287
288  if (is_clang && is_debug) {
289    # Allow comparing the address of references and 'this' against 0
290    # in debug builds. Technically, these can never be null in
291    # well-defined C/C++ and Clang can optimize such checks away in
292    # release builds, but they may be used in asserts in debug builds.
293    cflags_cc += [
294      "-Wno-undefined-bool-conversion",
295      "-Wno-tautological-undefined-compare",
296    ]
297  }
298
299  if (is_posix && !is_mac) {
300    if (enable_profiling) {
301      if (!is_debug) {
302        cflags += [ "-g" ]
303
304        if (enable_full_stack_frames_for_profiling) {
305          cflags += [
306            "-fno-inline",
307            "-fno-optimize-sibling-calls",
308          ]
309        }
310      }
311    }
312
313    if (!is_mingw && (is_official_build || force_local_build_id)) {
314      # Explicitly pass --build-id to ld. Compilers used to always pass this
315      # implicitly but don't any more (in particular clang when built without
316      # ENABLE_LINKER_BUILD_ID=ON). The crash infrastructure does need a build
317      # id, so explicitly enable it in official builds. It's not needed in
318      # unofficial builds and computing it does slow down the link, so go with
319      # faster links in unofficial builds.
320      ldflags += [ "-Wl,--build-id=md5" ]
321    }
322
323    if (!is_ohos) {
324      defines += [
325        "_FILE_OFFSET_BITS=64",
326        "_LARGEFILE_SOURCE",
327        "_LARGEFILE64_SOURCE",
328      ]
329    }
330
331    if (!is_nacl) {
332      cflags += [ "-funwind-tables" ]
333    }
334  }
335
336  if (is_linux || is_ohos) {
337    if (use_pic) {
338      cflags += [ "-fPIC" ]
339      ldflags += [ "-fPIC" ]
340    }
341
342    if (!is_clang) {
343      # Use pipes for communicating between sub-processes. Faster.
344      # (This flag doesn't do anything with Clang.)
345      cflags += [ "-pipe" ]
346    }
347
348    ldflags += [
349      "-Wl,-z,noexecstack",
350      "-Wl,-z,now",
351      "-Wl,-z,relro",
352    ]
353
354    # Compiler instrumentation can introduce dependencies in DSOs to symbols in
355    # the executable they are loaded into, so they are unresolved at link-time.
356    if (is_ohos || (!using_sanitizer && !is_safestack)) {
357      ldflags += [
358        "-Wl,-z,defs",
359        "-Wl,--as-needed",
360      ]
361    }
362
363    # Change default thread stack size to 2MB for asan.
364    if (is_ohos && using_sanitizer) {
365      ldflags += [ "-Wl,-z,stack-size=2097152" ]
366    }
367  }
368
369  if ((is_posix && use_lld) || (target_os == "chromeos" && is_ohos)) {
370    # NOTE: Some Chrome OS builds globally disable LLD, but they also build some
371    # targets against ohos toolchains which should use LLD. Therefore we
372    # explicitly select LLD in these cases.
373    ldflags += [ "-fuse-ld=lld" ]
374    if (current_cpu == "arm64") {
375      # Reduce the page size from 65536 in order to reduce binary size slightly
376      # by shrinking the alignment gap between segments. This also causes all
377      # segments to be mapped adjacently, which breakpad relies on.
378      ldflags += [ "-Wl,-z,max-page-size=4096" ]
379    }
380  } else if (use_gold) {
381    ldflags += [ "-fuse-ld=gold" ]
382    if (!is_ohos) {
383      # On ohos, this isn't needed.  gcc in the NDK knows to look next to
384      # it with -fuse-ld=gold, and clang gets a --gcc-toolchain flag passed
385      # above.
386      ldflags += [ "-B$gold_path" ]
387
388      if (linux_use_bundled_binutils) {
389        ldflags += [
390          # Experimentation found that using four linking threads
391          # saved ~20% of link time.
392          # Only apply this to the target linker, since the host
393          # linker might not be gold, but isn't used much anyway.
394          "-Wl,--threads",
395          "-Wl,--thread-count=4",
396        ]
397      }
398    }
399  } else if (linux_use_bundled_binutils) {
400    # Gold is the default linker for the bundled binutils so we explicitly
401    # enable the bfd linker when use_gold is not set.
402    ldflags += [ "-fuse-ld=bfd" ]
403  }
404
405  if (use_icf) {
406    ldflags += [ "-Wl,--icf=all" ]
407  }
408
409  if (linux_use_bundled_binutils) {
410    cflags += [ "-B$binutils_path" ]
411  }
412
413  if (is_linux) {
414    cflags += [ "-pthread" ]
415    # Do not use the -pthread ldflag here since it becomes a no-op
416    # when using -nodefaultlibs, which would cause an unused argument
417    # error.  "-lpthread" is added in //build/config:default_libs.
418  }
419
420  # Clang-specific compiler flags setup.
421  # ------------------------------------
422  if (is_clang) {
423    cflags += [ "-fcolor-diagnostics" ]
424
425    # Enable -fmerge-all-constants. This used to be the default in clang
426    # for over a decade. It makes clang non-conforming, but is fairly safe
427    # in practice and saves some binary size. We might want to consider
428    # disabling this (https://bugs.llvm.org/show_bug.cgi?id=18538#c13),
429    # but for now it looks like our build might rely on it
430    # (https://crbug.com/829795).
431    cflags += [ "-fmerge-all-constants" ]
432  }
433
434  if (use_lld) {
435    if (is_win) {
436      # On Windows, we call the linker directly, instead of calling it through
437      # the driver.
438      ldflags += [ "--color-diagnostics" ]
439    } else {
440      ldflags += [ "-Wl,--color-diagnostics" ]
441    }
442  }
443
444  if (is_clang && !is_nacl && !use_xcode_clang) {
445    cflags += [
446      "-Xclang",
447      "-mllvm",
448      "-Xclang",
449      "-instcombine-lower-dbg-declare=0",
450    ]
451  }
452
453  # Print absolute paths in diagnostics. There is no precedent for doing this
454  # on Linux/Mac (GCC doesn't support it), but MSVC does this with /FC and
455  # Windows developers rely on it (crbug.com/636109) so only do this on Windows.
456  if (msvc_use_absolute_paths && is_clang && is_win) {
457    cflags += [ "-fdiagnostics-absolute-paths" ]
458  }
459
460  # Makes builds independent of absolute file path.
461  # Currently disabled for nacl since its toolchain lacks this flag (too old).
462  if (symbol_level != 0 && is_clang && !is_nacl && !is_mac &&
463      strip_absolute_paths_from_debug_symbols) {
464    # If debug option is given, clang includes $cwd in debug info by default.
465    # For such build, this flag generates reproducible obj files even we use
466    # different build directory like "out/feature_a" and "out/feature_b" if
467    # we build same files with same compile flag.
468    # Other paths are already given in relative, no need to normalize them.
469    cflags += [
470      "-Xclang",
471      "-fdebug-compilation-dir",
472      "-Xclang",
473      ".",
474    ]
475
476    if (is_win && use_lld) {
477      if (symbol_level == 2 || (is_clang && using_sanitizer)) {
478        # Absolutize source file path for PDB. Pass the real build directory
479        # if the pdb contains source-level debug information.
480        ldflags += [ "/PDBSourcePath:" + rebase_path(root_build_dir) ]
481      } else {
482        # On Windows, (non-sanitizier) symbol_level 1 builds don't contain
483        # debug information in obj files; the linker just creates enough
484        # debug info at link time to produce symbolized stacks (without line
485        # numbers). In that case, there's no downside in using a fake fixed
486        # base directory for paths in the pdb. This makes the pdb output
487        # fully deterministic and independent of the build directory.
488        assert(symbol_level == 1 && !(is_clang && using_sanitizer))
489        ldflags += [ "/PDBSourcePath:o:\fake\prefix" ]
490      }
491    }
492  }
493
494  # Tells the compiler not to use absolute paths when passing the default
495  # paths to the tools it invokes. We don't want this because we don't
496  # really need it and it can mess up the goma cache entries.
497  if (is_clang && !is_nacl) {
498    cflags += [ "-no-canonical-prefixes" ]
499  }
500
501  # C11/C++11 compiler flags setup.
502  # ---------------------------
503  if (is_linux || is_ohos || (is_nacl && is_clang) || current_os == "aix") {
504    if (target_os == "ohos") {
505      cxx11_override = use_cxx11_on_ohos
506    } else {
507      cxx11_override = use_cxx11
508    }
509
510    if (is_clang) {
511      standard_prefix = "c"
512
513      # Since we build with -std=c* and not -std=gnu*, _GNU_SOURCE will not be
514      # defined by the compiler.  However, lots of code relies on the
515      # non-standard features that _GNU_SOURCE enables, so define it manually.
516      defines += [ "_GNU_SOURCE" ]
517
518      if (is_nacl) {
519        # Undefine __STRICT_ANSI__ to get non-standard features which would
520        # otherwise not be enabled by NaCl's sysroots.
521        cflags += [ "-U__STRICT_ANSI__" ]
522      }
523    } else {
524      # Gcc does not support ##__VA_ARGS__ when in standards-conforming mode,
525      # but we use this feature in several places in Chromium.
526      standard_prefix = "gnu"
527    }
528
529    #   cflags_c += [ "-std=${standard_prefix}11" ]
530    if (cxx11_override) {
531      # Override Chromium's default for projects that wish to stay on C++11.
532      cflags_cc += [ "-std=${standard_prefix}++11" ]
533    } else {
534      cflags_cc += [ "-std=${standard_prefix}++17" ]
535    }
536  } else if (!is_win && !is_nacl && !is_mingw) {
537    if (target_os == "ohos") {
538      cxx11_override = use_cxx11_on_ohos
539    } else {
540      cxx11_override = use_cxx11
541    }
542
543    if (cxx11_override) {
544      cflags_cc += [ "-std=c++11" ]
545    } else {
546      cflags_cc += [ "-std=c++17" ]
547    }
548  }
549
550  if (is_mac) {
551    # The system libc++ on Mac doesn't have aligned allocation in C++17.
552    defines += [ "_LIBCPP_HAS_NO_ALIGNED_ALLOCATION" ]
553    cflags_cc += [ "-stdlib=libc++" ]
554    ldflags += [ "-stdlib=libc++" ]
555  }
556
557  # Add flags for link-time optimization. These flags enable
558  # optimizations/transformations that require whole-program visibility at link
559  # time, so they need to be applied to all translation units, and we may end up
560  # with miscompiles if only part of the program is compiled with LTO flags. For
561  # that reason, we cannot allow targets to enable or disable these flags, for
562  # example by disabling the optimize configuration.
563  if (!is_debug && use_thin_lto &&
564      (current_toolchain == default_toolchain ||
565       (is_ohos && defined(ohoa_secondary_abi_toolchain) &&
566        current_toolchain == ohos_secondary_abi_toolchain))) {
567    assert(use_lld || target_os == "chromeos",
568           "gold plugin only supported with ChromeOS")
569
570    cflags += [ "-flto=thin" ]
571
572    if (thin_lto_enable_optimizations) {
573      lto_opt_level = 2
574    } else {
575      lto_opt_level = 0
576    }
577
578    if (is_win) {
579      # This is a straight translation of the non-Windows flags below,
580      # except we do not use the ThinLTO cache, which leaks temporary
581      # files on Windows (https://crbug.com/871962).
582      ldflags += [
583        "/opt:lldlto=" + lto_opt_level,
584        "/opt:lldltojobs=8",
585      ]
586    } else {
587      ldflags += [ "-flto=thin" ]
588
589      # Limit the parallelism to avoid too aggressive competition between
590      # linker jobs. This is still suboptimal to a potential dynamic
591      # resource allocation scheme, but should be good enough.
592      if (use_lld) {
593        # Limit the size of the ThinLTO cache to the lesser of 10% of available disk
594        # space, 10GB and 100000 files.
595        cache_policy =
596            "cache_size=10%:cache_size_bytes=10g:cache_size_files=100000"
597        ldflags += [
598          "-Wl,--thinlto-jobs=8",
599          "-Wl,--thinlto-cache-dir=" +
600              rebase_path("$root_out_dir/thinlto-cache", root_build_dir),
601          "-Wl,--thinlto-cache-policy,$cache_policy",
602        ]
603      } else {
604        ldflags += [ "-Wl,-plugin-opt,jobs=8" ]
605      }
606
607      if (use_lld) {
608        ldflags += [ "-Wl,--lto-O" + lto_opt_level ]
609        if (thin_lto_enable_optimizations) {
610          if (is_ohos) {
611            ldflags += [
612              "-Wl,-mllvm",
613              "-Wl,-import-instr-limit=5",
614            ]
615          }
616        }
617      } else {
618        not_needed([ "lto_opt_level" ])
619      }
620    }
621
622    if (!is_ohos) {
623      cflags += [ "-fwhole-program-vtables" ]
624      if (!is_win) {
625        ldflags += [ "-fwhole-program-vtables" ]
626      }
627    }
628
629    # Work-around for http://openradar.appspot.com/20356002
630    if (is_mac) {
631      ldflags += [ "-Wl,-all_load" ]
632    }
633
634    # This flag causes LTO to create an .ARM.attributes section with the correct
635    # architecture. This is necessary because LLD will refuse to link a program
636    # unless the architecture revision in .ARM.attributes is sufficiently new.
637    if (current_cpu == "arm") {
638      ldflags += [ "-march=$arm_arch" ]
639    }
640  }
641
642  if (compiler_timing) {
643    if (is_clang) {
644      if (is_win) {
645        cflags += [ "-Xclang" ]
646      }
647      cflags += [ "-ftime-report" ]
648    } else if (is_win) {
649      cflags += [
650        # "Documented" here:
651        # http://aras-p.info/blog/2017/10/23/Best-unknown-MSVC-flag-d2cgsummary/
652        "/d2cgsummary",
653      ]
654    }
655  }
656
657  # Pass flag to LLD to work around issue in Valgrind related to
658  # location of debug symbols.
659  if (use_lld && ro_segment_workaround_for_valgrind) {
660    ldflags += [ "-Wl,--no-rosegment" ]
661  }
662
663  # This flag enforces that member pointer base types are complete. It helps
664  # prevent us from running into problems in the Microsoft C++ ABI (see
665  # https://crbug.com/847724).
666  if (is_clang && !is_nacl && target_os != "chromeos" && !use_xcode_clang &&
667      (is_win || use_custom_libcxx)) {
668    cflags += [ "-fcomplete-member-pointers" ]
669  }
670
671  # Pass the same C/C++ flags to the objective C/C++ compiler.
672  cflags_objc += cflags_c
673  cflags_objcc += cflags_cc
674
675  # Assign any flags set for the C compiler to asmflags so that they are sent
676  # to the assembler. The Windows assembler takes different types of flags
677  # so only do so for posix platforms.
678  if (is_posix) {
679    asmflags += cflags
680    asmflags += cflags_c
681  }
682}
683
684# This provides the basic options to select the target CPU and ABI.
685# It is factored out of "compiler" so that special cases can use this
686# without using everything that "compiler" brings in.  Options that
687# tweak code generation for a particular CPU do not belong here!
688# See "compiler_codegen", below.
689config("compiler_cpu_abi") {
690  cflags = []
691  ldflags = []
692  defines = []
693
694  if (is_posix && !is_mac) {
695    # CPU architecture. We may or may not be doing a cross compile now, so for
696    # simplicity we always explicitly set the architecture.
697    if (current_cpu == "x64") {
698      cflags += [
699        "-m64",
700        "-march=x86-64",
701      ]
702      ldflags += [ "-m64" ]
703    } else if (current_cpu == "x86") {
704      cflags += [ "-m32" ]
705      ldflags += [ "-m32" ]
706      if (!is_nacl) {
707        cflags += [
708          "-msse2",
709          "-mfpmath=sse",
710          "-mmmx",
711        ]
712      }
713    } else if (current_cpu == "arm") {
714      if (is_clang && !is_ohos && !is_nacl) {
715        cflags += [ "--target=arm-linux-gnueabihf" ]
716        ldflags += [ "--target=arm-linux-gnueabihf" ]
717      }
718      if (!is_nacl) {
719        cflags += [
720          "-march=$arm_arch",
721          "-mfloat-abi=$arm_float_abi",
722        ]
723      }
724      if (arm_tune != "") {
725        cflags += [ "-mtune=$arm_tune" ]
726      }
727    } else if (current_cpu == "arm64") {
728      if (is_clang && !is_ohos && !is_nacl) {
729        cflags += [ "--target=aarch64-linux-gnu" ]
730        ldflags += [ "--target=aarch64-linux-gnu" ]
731      }
732      if (is_clang && is_ohos) {
733        ldflags += [ "-Wl,--hash-style=gnu" ]
734      }
735      cflags += [
736        "-march=$arm_arch",
737        "-mfloat-abi=$arm_float_abi",
738        "-mfpu=$arm_fpu",
739      ]
740      ldflags += [ "-march=$arm_arch" ]
741    }
742  }
743
744  asmflags = cflags
745  if (current_cpu == "arm64") {
746    asmflags += [ "-march=armv8.2-a+dotprod+fp16" ]
747  }
748}
749
750# This provides options to tweak code generation that are necessary
751# for particular Chromium code or for working around particular
752# compiler bugs (or the combination of the two).
753config("compiler_codegen") {
754  configs = []
755  cflags = []
756
757  if (is_nacl) {
758    configs += [ "//build/config/nacl:compiler_codegen" ]
759  } else if (is_posix && !is_mac) {
760    if (current_cpu == "x86") {
761      if (is_clang) {
762        cflags += [ "-momit-leaf-frame-pointer" ]
763      }
764    } else if (current_cpu == "arm") {
765      if (is_ohos && !is_clang) {
766        # Clang doesn't support these flags.
767        cflags += [
768          "-fno-tree-sra",
769          "-fno-caller-saves",
770        ]
771      }
772    }
773  }
774
775  asmflags = cflags
776}
777
778config("compiler_arm_fpu") {
779  if (current_cpu == "arm" && !is_nacl) {
780    cflags = [ "-mfpu=$arm_fpu" ]
781    asmflags = cflags
782  }
783}
784
785config("compiler_arm_thumb") {
786  if (current_cpu == "arm" && arm_use_thumb && is_posix &&
787      !(is_mac || is_nacl)) {
788    cflags = [ "-mthumb" ]
789    if (is_ohos && !is_clang) {
790      # Clang doesn't support this option.
791      cflags += [ "-mthumb-interwork" ]
792    }
793  }
794}
795
796config("compiler_arm") {
797  if (current_cpu == "arm" && is_chromeos) {
798    # arm is normally the default mode for clang, but on chromeos a wrapper
799    # is used to pass -mthumb, and therefore change the default.
800    cflags = [ "-marm" ]
801  }
802}
803
804# runtime_library -------------------------------------------------------------
805#
806# Sets the runtime library and associated options.
807#
808# How do you determine what should go in here vs. "compiler" above? Consider if
809# a target might choose to use a different runtime library (ignore for a moment
810# if this is possible or reasonable on your system). If such a target would want
811# to change or remove your option, put it in the runtime_library config. If a
812# target wants the option regardless, put it in the compiler config.
813
814config("runtime_library") {
815  defines = []
816  configs = []
817
818  # The order of this config is important: it must appear before
819  # ohos:runtime_library.
820  if (is_posix) {
821    configs += [ "//build/config/posix:runtime_library" ]
822  }
823
824  # System-specific flags. If your compiler flags apply to one of the
825  # categories here, add it to the associated file to keep this shared config
826  # smaller.
827  if (is_win) {
828    configs += [ "//build/config/win:runtime_library" ]
829  } else if (is_linux) {
830    configs += [ "//build/config/linux:runtime_library" ]
831  } else if (is_mac) {
832    configs += [ "//build/config/mac:runtime_library" ]
833  } else if (is_ohos) {
834    configs += [ "//build/config/ohos:runtime_library" ]
835  }
836
837  if (is_component_build) {
838    defines += [ "COMPONENT_BUILD" ]
839  }
840}
841
842# default_warnings ------------------------------------------------------------
843#
844# Collects all warning flags that are used by default.  This is used as a
845# subconfig of both chromium_code and no_chromium_code.  This way these
846# flags are guaranteed to appear on the compile command line after -Wall.
847config("default_warnings") {
848  cflags = []
849  cflags_cc = []
850  ldflags = []
851
852  if (is_mac && !is_nacl) {
853    # When compiling Objective-C, warns if a method is used whose
854    # availability is newer than the deployment target.
855    cflags += [ "-Wunguarded-availability" ]
856  }
857
858  # Suppress warnings about ABI changes on ARM (Clang doesn't give this
859  # warning).
860  if (current_cpu == "arm" && !is_clang) {
861    cflags += [ "-Wno-psabi" ]
862  }
863
864  if (!is_clang) {
865    cflags_cc += [
866      # See comment for -Wno-c++11-narrowing.
867      "-Wno-narrowing",
868    ]
869
870    # -Wunused-local-typedefs is broken in gcc,
871    # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63872
872    cflags += [ "-Wno-unused-local-typedefs" ]
873
874    # Don't warn about "maybe" uninitialized. Clang doesn't include this
875    # in -Wall but gcc does, and it gives false positives.
876    cflags += [ "-Wno-maybe-uninitialized" ]
877    cflags += [ "-Wno-deprecated-declarations" ]
878
879    # GCC assumes 'this' is never nullptr and optimizes away code
880    # like "if (this == nullptr) ...": [1].  However, some Chromium
881    # code relies on these types of null pointer checks [2], so
882    # disable this optimization.
883    # [1] https://gcc.gnu.org/gcc-6/porting_to.html#this-cannot-be-null
884    # [2] https://crbug.com/784492#c13
885    cflags += [ "-fno-delete-null-pointer-checks" ]
886
887    # -Wcomment gives too many false positives in the case a
888    # backslash ended comment line is followed by a new line of
889    # comments
890    # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61638
891    cflags += [ "-Wno-comments" ]
892  }
893
894  # Common Clang and GCC warning setup.
895  if (!is_win || is_clang) {
896    cflags += [
897      # Disables.
898      "-Wno-missing-field-initializers",  # "struct foo f = {0};"
899      "-Wno-unused-parameter",  # Unused function parameters.
900    ]
901  }
902
903  if (is_mingw) {
904    cflags += [
905      "-Wno-error=c99-designator",
906      "-Wno-error=anon-enum-enum-conversion",
907      "-Wno-error=implicit-fallthrough",
908      "-Wno-error=sizeof-array-div",
909      "-Wno-error=reorder-init-list",
910      "-Wno-error=range-loop-construct",
911      "-Wno-error=deprecated-copy",
912      "-Wno-error=implicit-int-float-conversion",
913      "-Wno-error=inconsistent-dllimport",
914      "-Wno-error=unknown-warning-option",
915      "-Wno-error=abstract-final-class",
916      "-Wno-error=sign-compare",
917    ]
918  }
919
920  if (is_clang) {
921    cflags += [
922      # This warns on using ints as initializers for floats in
923      # initializer lists (e.g. |int a = f(); CGSize s = { a, a };|),
924      # which happens in several places in chrome code. Not sure if
925      # this is worth fixing.
926      "-Wno-c++11-narrowing",
927      "-Wno-unneeded-internal-declaration",
928    ]
929    if (use_musl) {
930      cflags += [
931        "-Wno-error=c99-designator",
932        "-Wno-error=anon-enum-enum-conversion",
933        "-Wno-error=implicit-fallthrough",
934        "-Wno-error=sizeof-array-div",
935        "-Wno-error=reorder-init-list",
936        "-Wno-error=range-loop-construct",
937        "-Wno-error=deprecated-copy",
938        "-Wno-error=implicit-int-float-conversion",
939        "-Wno-error=inconsistent-dllimport",
940        "-Wno-error=unknown-warning-option",
941        "-Wno-error=abstract-final-class",
942        "-Wno-error=sign-compare",
943        "-Wno-error=int-in-bool-context",
944        "-Wno-error=xor-used-as-pow",
945        "-Wno-error=return-stack-address",
946        "-Wno-error=dangling-gsl",
947      ]
948    }
949
950    # use_xcode_clang only refers to the iOS toolchain, host binaries use
951    # chromium's clang always.
952    if (!is_nacl) {
953      cflags += [ "-Wno-undefined-var-template" ]
954      if (current_toolchain == host_toolchain || !use_xcode_clang ||
955          xcode_version_int >= 930) {
956        cflags += [
957          "-Wno-nonportable-include-path",
958          "-Wno-user-defined-warnings",
959          "-Wno-unused-lambda-capture",
960        ]
961      }
962      if (current_toolchain == host_toolchain || !use_xcode_clang ||
963          xcode_version_int >= 1000) {
964        cflags += [ "-Wno-null-pointer-arithmetic" ]
965      }
966      if (current_toolchain == host_toolchain || !use_xcode_clang) {
967        # Flags NaCl (Clang 3.7) and Xcode 9.2 (Clang clang-900.0.39.2) do not
968        # recognize.
969        cflags += [ "-Wno-enum-compare-switch" ]
970      }
971    }
972  }
973}
974
975# chromium_code ---------------------------------------------------------------
976#
977# Toggles between higher and lower warnings for code that is (or isn't)
978# part of Chromium.
979
980config("chromium_code") {
981  if (is_win) {
982    cflags = [ "/W4" ]  # Warning level 4.
983
984    if (is_clang) {
985      # Opt in to additional [[nodiscard]] on standard library methods.
986      defines = [ "_HAS_NODISCARD" ]
987    }
988  } else {
989    cflags = [ "-Wall" ]
990    if (treat_warnings_as_errors) {
991      cflags += [ "-Werror" ]
992
993      # The compiler driver can sometimes (rarely) emit warnings before calling
994      # the actual linker.  Make sure these warnings are treated as errors as
995      # well.
996      ldflags = [ "-Werror" ]
997    }
998    if (is_clang) {
999      # Enable extra warnings for chromium_code when we control the compiler.
1000      cflags += [ "-Wextra" ]
1001    }
1002
1003    # In Chromium code, we define __STDC_foo_MACROS in order to get the
1004    # C99 macros on Mac and Linux.
1005    defines = [
1006      "__STDC_CONSTANT_MACROS",
1007      "__STDC_FORMAT_MACROS",
1008    ]
1009
1010    if (!is_debug && !using_sanitizer &&
1011        (!is_linux || !is_clang || is_official_build)) {
1012      # _FORTIFY_SOURCE isn't really supported by Clang now, see
1013      # http://llvm.org/bugs/show_bug.cgi?id=16821.
1014      # It seems to work fine with Ubuntu 12 headers though, so use it in
1015      # official builds.
1016      #
1017      # Non-chromium code is not guaranteed to compile cleanly with
1018      # _FORTIFY_SOURCE. Also, fortified build may fail when optimizations are
1019      # disabled, so only do that for Release build.
1020      defines += [ "_FORTIFY_SOURCE=2" ]
1021    }
1022
1023    if (is_mac) {
1024      cflags_objc = [ "-Wobjc-missing-property-synthesis" ]
1025      cflags_objcc = [ "-Wobjc-missing-property-synthesis" ]
1026    }
1027  }
1028
1029  if (is_clang) {
1030    cflags += [
1031      # Warn on missing break statements at the end of switch cases.
1032      # For intentional fallthrough, use FALLTHROUGH; from
1033      # base/compiler_specific.h
1034      "-Wimplicit-fallthrough",
1035
1036      # Thread safety analysis. See base/thread_annotations.h and
1037      # https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
1038      "-Wthread-safety",
1039    ]
1040  }
1041
1042  configs = [ ":default_warnings" ]
1043}
1044
1045config("no_chromium_code") {
1046  cflags = []
1047  cflags_cc = []
1048  defines = []
1049
1050  if (is_win) {
1051    cflags += [
1052      "/W3",  # Warning level 3.
1053      "/wd4800",  # Disable warning when forcing value to bool.
1054      "/wd4267",  # size_t to int.
1055      "/wd4996",  # Deprecated function warning.
1056    ]
1057    defines += [
1058      "_CRT_NONSTDC_NO_WARNINGS",
1059      "_CRT_NONSTDC_NO_DEPRECATE",
1060    ]
1061  } else {
1062    # GCC may emit unsuppressible warnings so don't add -Werror for no chromium
1063    # code. crbug.com/589724
1064    if (treat_warnings_as_errors && is_clang) {
1065      cflags += [ "-Werror" ]
1066      ldflags = [ "-Werror" ]
1067    }
1068    if (is_clang && !is_nacl) {
1069      cflags += [ "-Wall" ]
1070    }
1071  }
1072
1073  if (is_clang) {
1074    cflags += [
1075      # Lots of third-party libraries have unused variables. Instead of
1076      # suppressing them individually, we just blanket suppress them here.
1077      "-Wno-unused-variable",
1078    ]
1079  }
1080
1081  configs = [ ":default_warnings" ]
1082}
1083
1084# noshadowing -----------------------------------------------------------------
1085#
1086# Allows turning -Wshadow on.
1087
1088config("noshadowing") {
1089  # This flag has to be disabled for nacl because the nacl compiler is too
1090  # strict about shadowing.
1091  if (is_clang && !is_nacl) {
1092    cflags = [ "-Wshadow" ]
1093  }
1094}
1095
1096# rtti ------------------------------------------------------------------------
1097#
1098# Allows turning Run-Time Type Identification on or off.
1099
1100config("rtti") {
1101  if (is_win) {
1102    cflags_cc = [ "/GR" ]
1103  } else {
1104    cflags_cc = [ "-frtti" ]
1105  }
1106}
1107
1108config("no_rtti") {
1109  # Some sanitizer configs may require RTTI to be left enabled globally
1110  if (!use_rtti) {
1111    if (is_win) {
1112      cflags_cc = [ "/GR-" ]
1113    } else {
1114      cflags_cc = [ "-fno-rtti" ]
1115      cflags_objcc = cflags_cc
1116    }
1117  }
1118}
1119
1120# export_dynamic ---------------------------------------------------------------
1121#
1122# Ensures all exported symbols are added to the dynamic symbol table.  This is
1123# necessary to expose Chrome's custom operator new() and operator delete() (and
1124# other memory-related symbols) to libraries.  Otherwise, they might
1125# (de)allocate memory on a different heap, which would spell trouble if pointers
1126# to heap-allocated memory are passed over shared library boundaries.
1127config("export_dynamic") {
1128  if (is_desktop_linux || export_libcxxabi_from_executables) {
1129    ldflags = [ "-rdynamic" ]
1130  }
1131}
1132
1133# thin_archive -----------------------------------------------------------------
1134#
1135# Enables thin archives on posix.  Regular archives directly include the object
1136# files used to generate it.  Thin archives merely reference the object files.
1137# This makes building them faster since it requires less disk IO, but is
1138# inappropriate if you wish to redistribute your static library.
1139# This config is added to the global config, so thin archives should already be
1140# enabled.  If you want to make a distributable static library, you need to do 2
1141# things:
1142# 1. Set complete_static_lib so that all dependencies of the library make it
1143#    into the library. See `gn help complete_static_lib` for details.
1144# 2. Remove the thin_archive config, so that the .a file actually contains all
1145#    .o files, instead of just references to .o files in the build directory
1146config("thin_archive") {
1147  # Mac and iOS use the mac-specific "libtool" command, not ar, which doesn't
1148  # have a "thin archive" mode (it does accept -T, but it means truncating
1149  # archive names to 16 characters, which is not what we want).
1150  if (is_posix && !is_nacl && !is_mac) {
1151    arflags = [ "-T" ]
1152  }
1153}
1154
1155# exceptions -------------------------------------------------------------------
1156#
1157# Allows turning Exceptions on or off.
1158
1159config("exceptions") {
1160  if (is_win) {
1161    # Enables exceptions in the STL.
1162    if (!use_custom_libcxx) {
1163      defines = [ "_HAS_EXCEPTIONS=1" ]
1164    }
1165    cflags_cc = [ "/EHsc" ]
1166  } else {
1167    cflags_cc = [ "-fexceptions" ]
1168    cflags_objcc = cflags_cc
1169  }
1170}
1171
1172config("no_exceptions") {
1173  if (is_win) {
1174    # Disables exceptions in the STL.
1175    # libc++ uses the __has_feature macro to control whether to use exceptions,
1176    # so defining this macro is unnecessary. Defining _HAS_EXCEPTIONS to 0 also
1177    # breaks libc++ because it depends on MSVC headers that only provide certain
1178    # declarations if _HAS_EXCEPTIONS is 1. Those MSVC headers do not use
1179    # exceptions, despite being conditional on _HAS_EXCEPTIONS.
1180    if (!use_custom_libcxx) {
1181      defines = [ "_HAS_EXCEPTIONS=0" ]
1182    }
1183  } else {
1184    cflags_cc = [ "-fno-exceptions" ]
1185    cflags_objcc = cflags_cc
1186  }
1187}
1188
1189# Warnings ---------------------------------------------------------------------
1190
1191# This will generate warnings when using Clang if code generates exit-time
1192# destructors, which will slow down closing the program.
1193config("wexit_time_destructors") {
1194  if (is_clang) {
1195    cflags = [ "-Wexit-time-destructors" ]
1196  }
1197}
1198
1199# On Windows compiling on x64, VC will issue a warning when converting
1200# size_t to int because it will truncate the value. Our code should not have
1201# these warnings and one should use a static_cast or a checked_cast for the
1202# conversion depending on the case. However, a lot of code still needs to be
1203# fixed. Apply this config to such targets to disable the warning.
1204#
1205# Note that this can be applied regardless of platform and architecture to
1206# clean up the call sites. This will only apply the flag when necessary.
1207#
1208# This config is just an alias to no_shorten_64_warnings and will
1209# suppress a superset of warning 4267 and any 64-bit -> 32-bit implicit
1210# conversions. Having both for a time means not having to go through and
1211# update all references to no_size_t_to_int_warning throughout the codebase
1212# atomically.
1213#
1214# Any new warning suppressions should use the no_shorten_64_warnings
1215# config below and not this.
1216config("no_size_t_to_int_warning") {
1217  configs = [ ":no_shorten_64_warnings" ]
1218}
1219
1220# As part of re-enabling -Wconversion (see issue 588506) some code
1221# will continue to generate warnings.
1222# The first warning to be enabled will be -Wshorten-64-to-32.
1223#
1224# Code that currently generates warnings for this can include this
1225# config to disable them.
1226config("no_shorten_64_warnings") {
1227  if (current_cpu == "x64" || current_cpu == "arm64") {
1228    if (is_clang) {
1229      cflags = [ "-Wno-shorten-64-to-32" ]
1230    } else {
1231      if (is_win) {
1232        # MSVC does not have an explicit warning equivalent to
1233        # -Wshorten-64-to-32 but 4267 warns for size_t -> int
1234        # on 64-bit builds, so is the closest.
1235        cflags = [ "/wd4267" ]
1236      }
1237    }
1238  }
1239}
1240
1241# Some code presumes that pointers to structures/objects are compatible
1242# regardless of whether what they point to is already known to be valid.
1243# gcc 4.9 and earlier had no way of suppressing this warning without
1244# suppressing the rest of them.  Here we centralize the identification of
1245# the gcc 4.9 toolchains.
1246config("no_incompatible_pointer_warnings") {
1247  cflags = []
1248  if (is_clang) {
1249    cflags += [ "-Wno-incompatible-pointer-types" ]
1250  } else if (is_chromeos && current_cpu == "arm") {
1251    cflags += [ "-w" ]
1252  }
1253}
1254
1255# Optimization -----------------------------------------------------------------
1256#
1257# The BUILDCONFIG file sets the "default_optimization" config on targets by
1258# default. It will be equivalent to either "optimize" (release) or
1259# "no_optimize" (debug) optimization configs.
1260#
1261# You can override the optimization level on a per-target basis by removing the
1262# default config and then adding the named one you want:
1263#
1264#   configs -= [ "//build/config/compiler:default_optimization" ]
1265#   configs += [ "//build/config/compiler:optimize_max" ]
1266
1267# Shared settings for both "optimize" and "optimize_max" configs.
1268# IMPORTANT: On Windows "/O1" and "/O2" must go before the common flags.
1269if (is_win) {
1270  common_optimize_on_cflags = [
1271    "/Ob2",  # Both explicit and auto inlining.
1272    "/Oy-",  # Disable omitting frame pointers, must be after /O2.
1273    "/Zc:inline",  # Remove unreferenced COMDAT (faster links).
1274  ]
1275  if (!is_asan) {
1276    common_optimize_on_cflags += [
1277      # Put data in separate COMDATs. This allows the linker
1278      # to put bit-identical constants at the same address even if
1279      # they're unrelated constants, which saves binary size.
1280      # This optimization can't be used when ASan is enabled because
1281      # it is not compatible with the ASan ODR checker.
1282      "/Gw",
1283    ]
1284  }
1285  common_optimize_on_ldflags = []
1286
1287  # /OPT:ICF is not desirable in Debug builds, since code-folding can result in
1288  # misleading symbols in stack traces. It is also incompatible with
1289  # incremental linking, which we enable for both Debug and component builds.
1290  if (!is_debug && !is_component_build) {
1291    common_optimize_on_ldflags += [ "/OPT:ICF" ]  # Redundant COMDAT folding.
1292  }
1293
1294  if (is_official_build) {
1295    common_optimize_on_ldflags += [ "/OPT:REF" ]  # Remove unreferenced data.
1296
1297    if (!use_lld && !is_clang) {
1298      common_optimize_on_ldflags += [
1299        # Set the number of LTCG code-gen threads to eight. The default is four.
1300        # This gives a 5-10% link speedup.
1301        "/cgthreads:8",
1302      ]
1303      if (use_incremental_wpo) {
1304        # Incremental Link-time code generation.
1305        common_optimize_on_ldflags += [ "/LTCG:INCREMENTAL" ]
1306      } else {
1307        common_optimize_on_ldflags += [ "/LTCG" ]  # Link-time code generation.
1308      }
1309    }
1310  }
1311} else {
1312  common_optimize_on_cflags = []
1313  common_optimize_on_ldflags = []
1314
1315  if (is_ohos) {
1316    common_optimize_on_ldflags += [
1317      # Warn in case of text relocations.
1318      "-Wl,--warn-shared-textrel",
1319    ]
1320  }
1321
1322  if (is_mac) {
1323    if (symbol_level == 2) {
1324      # Mac dead code stripping requires symbols.
1325      common_optimize_on_ldflags += [ "-Wl,-dead_strip" ]
1326    }
1327  } else if (current_os != "aix") {
1328    # Non-Mac Posix flags.
1329    # Aix does not support these.
1330
1331    common_optimize_on_cflags += [
1332      # Don't emit the GCC version ident directives, they just end up in the
1333      # .comment section taking up binary size.
1334      "-fno-ident",
1335
1336      # Put data and code in their own sections, so that unused symbols
1337      # can be removed at link time with --gc-sections.
1338      "-fdata-sections",
1339      "-ffunction-sections",
1340    ]
1341
1342    common_optimize_on_ldflags += [
1343      # Specifically tell the linker to perform optimizations.
1344      # See http://lwn.net/Articles/192624/ .
1345      # -O2 enables string tail merge optimization in gold and lld.
1346      "-Wl,-O2",
1347    ]
1348    if (!is_mingw) {
1349      common_optimize_on_ldflags += [ "-Wl,--gc-sections" ]
1350    }
1351  }
1352}
1353
1354config("default_stack_frames") {
1355  if (is_posix) {
1356    if (enable_frame_pointers) {
1357      cflags = [ "-fno-omit-frame-pointer" ]
1358    } else {
1359      cflags = [ "-fomit-frame-pointer" ]
1360    }
1361  }
1362  # On Windows, the flag to enable framepointers "/Oy-" must always come after
1363  # the optimization flag [e.g. "/O2"]. The optimization flag is set by one of
1364  # the "optimize" configs, see rest of this file. The ordering that cflags are
1365  # applied is well-defined by the GN spec, and there is no way to ensure that
1366  # cflags set by "default_stack_frames" is applied after those set by an
1367  # "optimize" config. Similarly, there is no way to propagate state from this
1368  # config into the "optimize" config. We always apply the "/Oy-" config in the
1369  # definition for common_optimize_on_cflags definition, even though this may
1370  # not be correct.
1371}
1372
1373# Default "optimization on" config.
1374config("optimize") {
1375  if (optimize_for_size && !is_nacl) {
1376    # Favor size over speed.
1377    if (is_clang) {
1378      cflags = [ "-O2" ] + common_optimize_on_cflags
1379    } else {
1380      cflags = [ "-Os" ] + common_optimize_on_cflags
1381    }
1382  } else {
1383    cflags = [ "-O2" ] + common_optimize_on_cflags
1384  }
1385  ldflags = common_optimize_on_ldflags
1386}
1387
1388# Same config as 'optimize' but without the WPO flag.
1389config("optimize_no_wpo") {
1390  if (is_win) {
1391    # Favor size over speed, /O1 must be before the common flags. The GYP
1392    # build also specifies /Os and /GF but these are implied by /O1.
1393    cflags = [ "/O1" ] + common_optimize_on_cflags + [ "/Oi" ]
1394  } else if (optimize_for_size && !is_nacl) {
1395    # Favor size over speed.
1396    if (is_clang) {
1397      cflags = [ "-Oz" ] + common_optimize_on_cflags
1398    } else {
1399      cflags = [ "-Os" ] + common_optimize_on_cflags
1400    }
1401  } else if (optimize_for_fuzzing) {
1402    cflags = [ "-O0" ] + common_optimize_on_cflags
1403  } else {
1404    cflags = [ "-O2" ] + common_optimize_on_cflags
1405  }
1406  ldflags = common_optimize_on_ldflags
1407}
1408
1409# Turn off optimizations.
1410config("no_optimize") {
1411  if (is_win) {
1412    cflags = [
1413      "/Od",  # Disable optimization.
1414      "/Ob0",  # Disable all inlining (on by default).
1415      "/GF",  # Enable string pooling (off by default).
1416    ]
1417  } else if (is_ohos && !ohos_full_debug) {
1418    # On ohos we kind of optimize some things that don't affect debugging
1419    # much even when optimization is disabled to get the binary size down.
1420    if (is_clang) {
1421      cflags = [ "-Oz" ] + common_optimize_on_cflags
1422      ldflags = common_optimize_on_ldflags
1423    } else {
1424      cflags = [ "-Os" ] + common_optimize_on_cflags
1425      ldflags = common_optimize_on_ldflags
1426    }
1427  } else {
1428    # On ohos_full_debug mode, we close all optimization
1429    cflags = [ "-O0" ]
1430    ldflags = []
1431  }
1432}
1433
1434# Turns up the optimization level. On Windows, this implies whole program
1435# optimization and link-time code generation which is very expensive and should
1436# be used sparingly.
1437config("optimize_max") {
1438  if (is_nacl && is_nacl_irt) {
1439    # The NaCl IRT is a special case and always wants its own config.
1440    # Various components do:
1441    #   if (!is_debug) {
1442    #     configs -= [ "//build/config/compiler:default_optimization" ]
1443    #     configs += [ "//build/config/compiler:optimize_max" ]
1444    #   }
1445    # So this config has to have the selection logic just like
1446    # "default_optimization", below.
1447    configs = [ "//build/config/nacl:irt_optimize" ]
1448  } else {
1449    ldflags = common_optimize_on_ldflags
1450    if (is_win) {
1451      # Favor speed over size, /O2 must be before the common flags. The GYP
1452      # build also specifies /Ot, /Oi, and /GF, but these are implied by /O2.
1453      cflags = [ "/O2" ] + common_optimize_on_cflags
1454
1455      if (is_official_build) {
1456        if (!is_clang) {
1457          cflags += [
1458            "/GL",  # Whole program optimization.
1459
1460            # Disable Warning 4702 ("Unreachable code") for the WPO/PGO builds.
1461            # Probably anything that this would catch that wouldn't be caught
1462            # in a normal build isn't going to actually be a bug, so the
1463            # incremental value of C4702 for PGO builds is likely very small.
1464            "/wd4702",
1465          ]
1466        }
1467      }
1468    } else if (optimize_for_fuzzing) {
1469      cflags = [ "-O0" ] + common_optimize_on_cflags
1470    } else {
1471      cflags = [ "-O2" ] + common_optimize_on_cflags
1472    }
1473  }
1474}
1475
1476# This config can be used to override the default settings for per-component
1477# and whole-program optimization, optimizing the particular target for speed
1478# instead of code size. This config is exactly the same as "optimize_max"
1479# except that we use -O3 instead of -O2 on non-win, non-IRT platforms.
1480config("optimize_speed") {
1481  if (is_nacl && is_nacl_irt) {
1482    # The NaCl IRT is a special case and always wants its own config.
1483    # Various components do:
1484    #   if (!is_debug) {
1485    #     configs -= [ "//build/config/compiler:default_optimization" ]
1486    #     configs += [ "//build/config/compiler:optimize_max" ]
1487    #   }
1488    # So this config has to have the selection logic just like
1489    # "default_optimization", below.
1490    configs = [ "//build/config/nacl:irt_optimize" ]
1491  } else {
1492    ldflags = common_optimize_on_ldflags
1493    if (is_win) {
1494      # Favor speed over size, /O2 must be before the common flags. The GYP
1495      # build also specifies /Ot, /Oi, and /GF, but these are implied by /O2.
1496      cflags = [ "/O2" ] + common_optimize_on_cflags
1497
1498      if (is_official_build && !is_clang) {
1499        cflags += [
1500          "/GL",  # Whole program optimization.
1501
1502          # Disable Warning 4702 ("Unreachable code") for the WPO/PGO builds.
1503          # Probably anything that this would catch that wouldn't be caught in a
1504          # normal build isn't going to actually be a bug, so the incremental
1505          # value of C4702 for PGO builds is likely very small.
1506          "/wd4702",
1507        ]
1508      }
1509    } else if (optimize_for_fuzzing) {
1510      cflags = [ "-O0" ] + common_optimize_on_cflags
1511    } else {
1512      cflags = [ "-O3" ] + common_optimize_on_cflags
1513    }
1514  }
1515}
1516
1517config("optimize_fuzzing") {
1518  cflags = [ "-O0" ] + common_optimize_on_cflags
1519  ldflags = common_optimize_on_ldflags
1520  visibility = [ ":default_optimization" ]
1521}
1522
1523# The default optimization applied to all targets. This will be equivalent to
1524# either "optimize" or "no_optimize", depending on the build flags.
1525config("default_optimization") {
1526  if (is_nacl && is_nacl_irt) {
1527    # The NaCl IRT is a special case and always wants its own config.
1528    # It gets optimized the same way regardless of the type of build.
1529    configs = [ "//build/config/nacl:irt_optimize" ]
1530  } else if (is_debug) {
1531    configs = [ ":no_optimize" ]
1532  } else if (optimize_for_fuzzing) {
1533    assert(!is_win, "Fuzzing optimize level not supported on Windows")
1534
1535    # Coverage build is quite slow. Using "optimize_for_fuzzing" makes it even
1536    # slower as it uses "-O1" instead of "-O3". Prevent that from happening.
1537    assert(!use_clang_coverage,
1538           "optimize_for_fuzzing=true should not be used with " +
1539               "use_clang_coverage=true.")
1540    configs = [ ":optimize_fuzzing" ]
1541  } else {
1542    configs = [ ":optimize" ]
1543  }
1544}
1545
1546_clang_sample_profile = ""
1547if (is_clang && current_toolchain == default_toolchain) {
1548  if (clang_sample_profile_path != "") {
1549    _clang_sample_profile = clang_sample_profile_path
1550  } else if (clang_use_default_sample_profile) {
1551    assert(build_with_chromium,
1552           "Our default profiles currently only apply to Chromium")
1553    assert(is_ohos || is_desktop_linux,
1554           "The current platform has no default profile")
1555    _clang_sample_profile = ""
1556  }
1557}
1558
1559# Clang offers a way to assert that AFDO profiles are accurate, which causes it
1560# to optimize functions not represented in a profile more aggressively for size.
1561# This config can be toggled in cases where shaving off binary size hurts
1562# performance too much.
1563config("afdo_optimize_size") {
1564  if (_clang_sample_profile != "" && sample_profile_is_accurate) {
1565    cflags = [ "-fprofile-sample-accurate" ]
1566  }
1567}
1568
1569# GCC and clang support a form of profile-guided optimization called AFDO.
1570# There are some targeted places that AFDO regresses (and an icky interaction
1571# between //base/allocator:tcmalloc and AFDO on GCC), so we provide a separate
1572# config to allow AFDO to be disabled per-target.
1573config("afdo") {
1574  if (is_clang) {
1575    if (_clang_sample_profile != "") {
1576      rebased_clang_sample_profile =
1577          rebase_path(_clang_sample_profile, root_build_dir)
1578      cflags = [ "-fprofile-sample-use=${rebased_clang_sample_profile}" ]
1579      inputs = [ _clang_sample_profile ]
1580    }
1581  } else if (auto_profile_path != "" &&
1582             current_toolchain == default_toolchain) {
1583    cflags = [ "-fauto-profile=${auto_profile_path}" ]
1584    inputs = [ auto_profile_path ]
1585  }
1586}
1587
1588# Symbols ----------------------------------------------------------------------
1589
1590# The BUILDCONFIG file sets the "default_symbols" config on targets by
1591# default. It will be equivalent to one the three specific symbol levels.
1592#
1593# You can override the symbol level on a per-target basis by removing the
1594# default config and then adding the named one you want:
1595#
1596#   configs -= [ "//build/config/compiler:default_symbols" ]
1597#   configs += [ "//build/config/compiler:symbols" ]
1598
1599# A helper config that all configs passing /DEBUG to the linker should
1600# include as sub-config.
1601config("win_pdbaltpath") {
1602  visibility = [
1603    ":minimal_symbols",
1604    ":symbols",
1605  ]
1606
1607  # /DEBUG causes the linker to generate a pdb file, and to write the absolute
1608  # path to it in the executable file it generates.  This flag turns that
1609  # absolute path into just the basename of the pdb file, which helps with
1610  # build reproducibility. Debuggers look for pdb files next to executables,
1611  # so there's no downside to always using this.
1612  ldflags = [ "/pdbaltpath:%_PDB%" ]
1613}
1614
1615# Full symbols.
1616config("symbols") {
1617  if (is_win) {
1618    if (is_clang) {
1619      # Note that with VC++ this requires is_win_fastlink, enforced elsewhere.
1620      cflags = [ "/Z7" ]  # Debug information in the .obj files.
1621    } else {
1622      cflags = [ "/Zi" ]  # Produce PDB file, no edit and continue.
1623    }
1624
1625    if (is_win_fastlink && !use_lld) {
1626      # Tell VS 2015+ to create a PDB that references debug
1627      # information in .obj and .lib files instead of copying
1628      # it all. This flag is incompatible with /PROFILE
1629      ldflags = [ "/DEBUG:FASTLINK" ]
1630    } else if (is_clang && use_lld && use_ghash) {
1631      cflags += [
1632        "-mllvm",
1633        "-emit-codeview-ghash-section",
1634      ]
1635      ldflags = [ "/DEBUG:GHASH" ]
1636    } else {
1637      ldflags = [ "/DEBUG" ]
1638    }
1639
1640    # All configs using /DEBUG should include this:
1641    configs = [ ":win_pdbaltpath" ]
1642
1643    if (is_clang) {
1644      # /DEBUG:FASTLINK requires every object file to have standalone debug
1645      # information.
1646      if (is_win_fastlink && !use_lld) {
1647        cflags += [ "-fstandalone-debug" ]
1648      } else {
1649        cflags += [ "-fno-standalone-debug" ]
1650      }
1651    }
1652  } else {
1653    if (is_mac) {
1654      cflags = [ "-gdwarf-2" ]
1655      if (is_mac && enable_dsyms) {
1656        # If generating dSYMs, specify -fno-standalone-debug. This was
1657        # originally specified for https://crbug.com/479841 because dsymutil
1658        # could not handle a 4GB dSYM file. But dsymutil from Xcodes prior to
1659        # version 7 also produces debug data that is incompatible with Breakpad
1660        # dump_syms, so this is still required (https://crbug.com/622406).
1661        cflags += [ "-fno-standalone-debug" ]
1662      }
1663    } else {
1664      cflags = []
1665      if (!use_debug_fission && current_cpu == "arm") {
1666        # dump_syms has issues with dwarf4 on arm, https://crbug.com/744956
1667        #
1668        # debug fission needs DWARF DIEs to be emitted at version 4.
1669        # Chrome OS emits Debug Frame in DWARF1 to make breakpad happy. [1]
1670        # Unless ohos needs debug fission, DWARF3 is the simplest solution.
1671        #
1672        # [1] crrev.com/a81d5ade0b043208e06ad71a38bcf9c348a1a52f
1673        cflags += [ "-gdwarf-3" ]
1674      }
1675      if (!ohos_full_debug) {
1676        cflags += [ "-g2" ]
1677      } else {
1678        # Set -g3 symbol level when ohos_full_debug is true
1679        cflags += [ "-g3" ]
1680      }
1681    }
1682    if (use_debug_fission && !is_nacl && !is_ohos) {
1683      # NOTE: Some Chrome OS builds globally set |use_debug_fission| to true,
1684      # but they also build some targets against ohos toolchains which aren't
1685      # compatible with it.
1686      cflags += [ "-gsplit-dwarf" ]
1687    }
1688    asmflags = cflags
1689    ldflags = []
1690
1691    if (!is_mac && !is_nacl && current_cpu != "x86" && (use_gold || use_lld)) {
1692      if (is_clang) {
1693        # This flag enables the GNU-format pubnames and pubtypes sections,
1694        # which lld needs in order to generate a correct GDB index.
1695        cflags += [ "-ggnu-pubnames" ]
1696      }
1697      ldflags += [ "-Wl,--gdb-index" ]
1698    }
1699  }
1700}
1701
1702# Minimal symbols.
1703# This config guarantees to hold symbol for stack trace which are shown to user
1704# when crash happens in unittests running on buildbot.
1705config("minimal_symbols") {
1706  if (is_win) {
1707    # Linker symbols for backtraces only.
1708    cflags = []
1709    ldflags = [ "/DEBUG" ]
1710
1711    # All configs using /DEBUG should include this:
1712    configs = [ ":win_pdbaltpath" ]
1713
1714    # For win/asan, get stack traces with full line numbers.
1715    # AddressSanitizerTests.TestAddressSanitizer needs this, and since
1716    # win/asan isn't a default cq bot the build time hit is ok.
1717    if (is_clang && using_sanitizer) {
1718      # -gline-tables-only is the same as -g1, but clang-cl only exposes the
1719      # former.
1720      cflags += [ "-gline-tables-only" ]
1721    }
1722  } else {
1723    cflags = []
1724    if (current_cpu == "arm") {
1725      # dump_syms has issues with dwarf4 on arm, https://crbug.com/744956
1726      cflags += [ "-gdwarf-3" ]
1727    }
1728    cflags += [ "-g1" ]
1729    ldflags = []
1730    if (is_ohos && is_clang) {
1731      # ohos defaults to symbol_level=1 builds in production builds
1732      # (https://crbug.com/648948), but clang, unlike gcc, doesn't emit
1733      # DW_AT_linkage_name in -g1 builds. -fdebug-info-for-profiling enables
1734      # that (and a bunch of other things we don't need), so that we get
1735      # qualified names in stacks.
1736      cflags += [ "-fdebug-info-for-profiling" ]
1737    }
1738
1739    # Note: -gsplit-dwarf implicitly turns on -g2 with clang, so don't pass it.
1740    asmflags = cflags
1741  }
1742}
1743
1744# No symbols.
1745config("no_symbols") {
1746  if (!is_win) {
1747    cflags = [ "-g0" ]
1748    asmflags = cflags
1749  }
1750}
1751
1752# Default symbols.
1753config("default_symbols") {
1754  if (symbol_level == 0) {
1755    configs = [ ":no_symbols" ]
1756  } else if (symbol_level == 1) {
1757    configs = [ ":minimal_symbols" ]
1758  } else if (symbol_level == 2) {
1759    configs = [ ":symbols" ]
1760  } else {
1761    assert(false)
1762  }
1763
1764  # This config is removed by base unittests app.
1765  if (is_ohos && is_clang && strip_debug_info) {
1766    configs += [ ":strip_debug" ]
1767  }
1768}
1769
1770config("strip_debug") {
1771  if (!defined(ldflags)) {
1772    ldflags = []
1773  }
1774  ldflags += [ "-Wl,--strip-debug" ]
1775}
1776
1777if (is_mac) {
1778  # On Mac and iOS, this enables support for ARC (automatic ref-counting).
1779  # See http://clang.llvm.org/docs/AutomaticReferenceCounting.html.
1780  config("enable_arc") {
1781    common_flags = [ "-fobjc-arc" ]
1782    cflags_objc = common_flags
1783    cflags_objcc = common_flags
1784  }
1785}
1786
1787config("no_common") {
1788  if (is_clang) {
1789    cflags = [ "-fno-common" ]
1790    asmflags = cflags
1791  }
1792}
1793