• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2013 The Chromium Authors
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/buildflag_header.gni")
6import("//build/config/android/config.gni")
7import("//build/config/c++/c++.gni")
8import("//build/config/chrome_build.gni")
9import("//build/config/chromeos/args.gni")
10import("//build/config/chromeos/ui_mode.gni")
11import("//build/config/clang/clang.gni")
12import("//build/config/compiler/compiler.gni")
13import("//build/config/coverage/coverage.gni")
14import("//build/config/dcheck_always_on.gni")
15import("//build/config/gclient_args.gni")
16import("//build/config/host_byteorder.gni")
17import("//build/config/rust.gni")
18import("//build/config/sanitizers/sanitizers.gni")
19import("//build/config/ui.gni")
20import("//build/config/unwind.gni")
21import("//build/toolchain/cc_wrapper.gni")
22import("//build/toolchain/goma.gni")
23import("//build/toolchain/rbe.gni")
24import("//build/toolchain/toolchain.gni")
25import("//build_overrides/build.gni")
26
27if (current_cpu == "arm" || current_cpu == "arm64") {
28  import("//build/config/arm.gni")
29}
30if (current_cpu == "mipsel" || current_cpu == "mips64el" ||
31    current_cpu == "mips" || current_cpu == "mips64") {
32  import("//build/config/mips.gni")
33}
34if (is_mac) {
35  import("//build/config/apple/symbols.gni")
36}
37if (is_ios) {
38  import("//build/config/ios/ios_sdk.gni")
39}
40if (is_nacl) {
41  # To keep NaCl variables out of builds that don't include NaCl, all
42  # variables defined in nacl/config.gni referenced here should be protected by
43  # is_nacl conditions.
44  import("//build/config/nacl/config.gni")
45}
46
47lld_path = ""
48if (!is_clang) {
49  declare_args() {
50    # This allows overriding the location of lld.
51    lld_path = rebase_path("$clang_base_path/bin", root_build_dir)
52  }
53} else {
54  # clang looks for lld next to it, no need for -B.
55  lld_path = ""
56}
57
58declare_args() {
59  # Normally, Android builds are lightly optimized, even for debug builds, to
60  # keep binary size down. Setting this flag to true disables such optimization
61  android_full_debug = false
62
63  # Compile in such a way as to make it possible for the profiler to unwind full
64  # stack frames. Setting this flag has a large effect on the performance of the
65  # generated code than just setting profiling, but gives the profiler more
66  # information to analyze.
67  # Requires profiling to be set to true.
68  enable_full_stack_frames_for_profiling = false
69
70  # When we are going to use gold we need to find it.
71  # This is initialized below, after use_gold might have been overridden.
72  gold_path = ""
73
74  # Enable fatal linker warnings. Building Chromium with certain versions
75  # of binutils can cause linker warning.
76  fatal_linker_warnings = true
77
78  # Build with C++ RTTI enabled. Chromium builds without RTTI by default,
79  # but some sanitizers are known to require it, like CFI diagnostics
80  # and UBsan variants.
81  use_rtti = use_cfi_diag || is_ubsan_vptr || is_ubsan_security
82
83  # AFDO (Automatic Feedback Directed Optimizer) is a form of profile-guided
84  # optimization that GCC supports. It used by ChromeOS in their official
85  # builds. To use it, set auto_profile_path to the path to a file containing
86  # the needed gcov profiling data.
87  auto_profile_path = ""
88
89  # Path to an AFDO profile to use while building with clang, if any. Empty
90  # implies none.
91  clang_sample_profile_path = ""
92
93  # Some configurations have default sample profiles. If this is true and
94  # clang_sample_profile_path is empty, we'll fall back to the default.
95  #
96  # We currently only have default profiles for Chromium in-tree, so we disable
97  # this by default for all downstream projects, since these profiles are likely
98  # nonsensical for said projects.
99  clang_use_default_sample_profile =
100      chrome_pgo_phase == 0 && build_with_chromium && is_official_build &&
101      (is_android || chromeos_is_browser_only)
102
103  # This configuration is used to select a default profile in Chrome OS based on
104  # the microarchitectures we are using. This is only used if
105  # clang_use_default_sample_profile is true and clang_sample_profile_path is
106  # empty.
107  chromeos_afdo_platform = "atom"
108
109  # Emit debug information for profiling wile building with clang.
110  # Only enable this for ChromeOS official builds for AFDO.
111  clang_emit_debug_info_for_profiling = is_chromeos_device && is_official_build
112
113  # Turn this on to have the compiler output extra timing information.
114  compiler_timing = false
115
116  # Turn this on to use ghash feature of lld for faster debug link on Windows.
117  # http://blog.llvm.org/2018/01/improving-link-time-on-windows-with.html
118  use_ghash = true
119
120  # Whether to enable ThinLTO optimizations. Turning ThinLTO optimizations on
121  # can substantially increase link time and binary size, but they generally
122  # also make binaries a fair bit faster.
123  #
124  # TODO(gbiv): We disable optimizations by default on most platforms because
125  # the space overhead is too great. We should use some mixture of profiles and
126  # optimization settings to better tune the size increase.
127  thin_lto_enable_optimizations =
128      (is_chromeos || is_android || is_win || is_linux || is_mac ||
129       (is_ios && use_lld)) && is_official_build
130
131  # Initialize all local variables with a pattern. This flag will fill
132  # uninitialized floating-point types (and 32-bit pointers) with 0xFF and the
133  # rest with 0xAA. This makes behavior of uninitialized memory bugs consistent,
134  # recognizable in the debugger, and crashes on memory accesses through
135  # uninitialized pointers.
136  #
137  # TODO(crbug.com/1131993): This regresses binary size by ~1MB on Android and
138  # needs to be evaluated before enabling it there as well.
139  init_stack_vars = !(is_android && is_official_build)
140
141  # Zero init has favorable performance/size tradeoffs for Chrome OS
142  # but was not evaluated for other platforms.
143  init_stack_vars_zero = is_chromeos
144
145  # This argument is to control whether enabling text section splitting in the
146  # final binary. When enabled, the separated text sections with prefix
147  # '.text.hot', '.text.unlikely', '.text.startup' and '.text.exit' will not be
148  # merged to '.text' section. This allows us to identify the hot code section
149  # ('.text.hot') in the binary which may be mlocked or mapped to huge page to
150  # reduce TLB misses which gives performance improvement on cpu usage.
151  # The gold linker by default has text section splitting enabled.
152  use_text_section_splitting = false
153
154  # Enable DWARF v5.
155  use_dwarf5 = false
156
157  # Override this to put full paths to PDBs in Windows PE files. This helps
158  # windbg and Windows Performance Analyzer with finding the PDBs in some local-
159  # build scenarios. This is never needed for bots or official builds. Because
160  # this puts the output directory in the DLLs/EXEs it breaks build determinism.
161  # Bugs have been reported to the windbg/WPA teams and this workaround will be
162  # removed when they are fixed.
163  use_full_pdb_paths = false
164
165  # Enable -H, which prints the include tree during compilation.
166  # For use by tools/clang/scripts/analyze_includes.py
167  show_includes = false
168
169  # Enable Profi algorithm. Profi can infer block and edge counts.
170  # https://clang.llvm.org/docs/UsersManual.html#using-sampling-profilers
171  # TODO(crbug.com/1375958i:) Possibly enable this for Android too.
172  use_profi = is_chromeos
173
174  # If true, linker crashes will be rerun with `--reproduce` which causes
175  # a reproducer file to be saved.
176  save_reproducers_on_lld_crash = false
177
178  # Allow projects that wish to stay on C++17 to override Chromium's default.
179  # TODO(crbug.com/1402249): evaluate removing this end of 2023
180  use_cxx17 = false
181
182  # Enable ShadowCallStack for compiled binaries. SCS stores a pointer to a
183  # shadow call stack in register x18. Hence, x18 must not be used by the OS
184  # or libraries. We assume that to be the case for high end Android
185  # configurations. For more details see
186  # https://clang.llvm.org/docs/ShadowCallStack.html
187  enable_shadow_call_stack = false
188}
189
190declare_args() {
191  # Set to true to use icf, Identical Code Folding.
192  #
193  # icf=all is broken in older golds, see
194  # https://sourceware.org/bugzilla/show_bug.cgi?id=17704
195  # chromeos binutils has been patched with the fix, so always use icf there.
196  # The bug only affects x86 and x64, so we can still use ICF when targeting
197  # other architectures.
198  #
199  # lld doesn't have the bug.
200  use_icf = (is_posix || is_fuchsia) && !is_debug && !using_sanitizer &&
201            !use_clang_coverage && current_os != "zos" &&
202            !(is_android && use_order_profiling) &&
203            (use_lld || (use_gold && (is_chromeos || !(current_cpu == "x86" ||
204                                                       current_cpu == "x64"))))
205}
206
207if (is_android) {
208  # Set the path to use orderfile for linking Chrome
209  # Note that this is for using only one orderfile for linking
210  # the Chrome binary/library.
211  declare_args() {
212    chrome_orderfile_path = ""
213
214    if (defined(default_chrome_orderfile)) {
215      # Allow downstream tools to set orderfile path with
216      # another variable.
217      chrome_orderfile_path = default_chrome_orderfile
218    }
219  }
220}
221
222declare_args() {
223  # Turn off the --call-graph-profile-sort flag for lld by default. Enable
224  # selectively for targets where it's beneficial.
225  enable_call_graph_profile_sort =
226      chrome_pgo_phase == 2 ||
227      (is_chromeos &&
228       (clang_use_default_sample_profile || clang_sample_profile_path != ""))
229}
230
231assert(!(llvm_force_head_revision && use_goma),
232       "can't use goma with trunk clang")
233assert(!(llvm_force_head_revision && use_remoteexec),
234       "can't use rbe with trunk clang")
235
236# default_include_dirs ---------------------------------------------------------
237#
238# This is a separate config so that third_party code (which would not use the
239# source root and might have conflicting versions of some headers) can remove
240# this and specify their own include paths.
241config("default_include_dirs") {
242  include_dirs = [
243    "//",
244    root_gen_dir,
245  ]
246}
247
248# Compiler instrumentation can introduce dependencies in DSOs to symbols in
249# the executable they are loaded into, so they are unresolved at link-time.
250config("no_unresolved_symbols") {
251  if (!using_sanitizer &&
252      (is_linux || is_chromeos || is_android || is_fuchsia)) {
253    ldflags = [
254      "-Wl,-z,defs",
255      "-Wl,--as-needed",
256    ]
257  }
258}
259
260# compiler ---------------------------------------------------------------------
261#
262# Base compiler configuration.
263#
264# See also "runtime_library" below for related stuff and a discussion about
265# where stuff should go. Put warning related stuff in the "warnings" config.
266
267config("compiler") {
268  asmflags = []
269  cflags = []
270  cflags_c = []
271  cflags_cc = []
272  cflags_objc = []
273  cflags_objcc = []
274  rustflags = []
275  ldflags = []
276  defines = []
277  configs = []
278  rustflags = []
279
280  # System-specific flags. If your compiler flags apply to one of the
281  # categories here, add it to the associated file to keep this shared config
282  # smaller.
283  if (is_win) {
284    configs += [ "//build/config/win:compiler" ]
285  } else if (is_android) {
286    configs += [ "//build/config/android:compiler" ]
287  } else if (is_linux || is_chromeos) {
288    configs += [ "//build/config/linux:compiler" ]
289  } else if (is_nacl) {
290    configs += [ "//build/config/nacl:compiler" ]
291  } else if (is_mac) {
292    configs += [ "//build/config/mac:compiler" ]
293  } else if (is_ios) {
294    configs += [ "//build/config/ios:compiler" ]
295  } else if (is_fuchsia) {
296    configs += [ "//build/config/fuchsia:compiler" ]
297  } else if (current_os == "aix") {
298    configs += [ "//build/config/aix:compiler" ]
299  } else if (current_os == "zos") {
300    configs += [ "//build/config/zos:compiler" ]
301  }
302
303  configs += [
304    # See the definitions below.
305    ":clang_revision",
306    ":rustc_revision",
307    ":compiler_cpu_abi",
308    ":compiler_codegen",
309    ":compiler_deterministic",
310  ]
311
312  # Here we enable -fno-delete-null-pointer-checks, which makes various nullptr
313  # operations (e.g. dereferencing) into defined behavior. This avoids deletion
314  # of some security-critical code: see https://crbug.com/1139129.
315  # Nacl does not support the flag. And, we still want UBSAN to catch undefined
316  # behavior related to nullptrs, so do not add this flag if UBSAN is enabled.
317  # GCC seems to have some bugs compiling constexpr code when this is defined,
318  # so only enable it if using_clang. See: https://gcc.gnu.org/PR97913
319  # TODO(mpdenton): remove is_clang once GCC bug is fixed.
320  if (!is_nacl && !is_ubsan && is_clang) {
321    cflags += [ "-fno-delete-null-pointer-checks" ]
322  }
323
324  # Don't emit the GCC version ident directives, they just end up in the
325  # .comment section or debug info taking up binary size, and makes comparing
326  # .o files built with different compiler versions harder.
327  if (!is_win || is_clang) {
328    cflags += [ "-fno-ident" ]
329  }
330
331  # In general, Windows is totally different, but all the other builds share
332  # some common compiler and linker configuration.
333  if (!is_win) {
334    # Common POSIX compiler flags setup.
335    # --------------------------------
336    cflags += [ "-fno-strict-aliasing" ]  # See http://crbug.com/32204
337
338    # Stack protection. ShadowCallStack and Stack protector address the same
339    # problems. Therefore, we only enable one or the other. Clang advertises SCS as
340    # a stronger alternative to StackProtector, so we give SCS precedence over SP.
341    if (enable_shadow_call_stack) {
342      # On Aarch64, SCS requires the x18 register to be unused because it will hold
343      # a pointer to the shadow stack. For Android we know that Clang doesn't use
344      # x18 by default. On other OSs adding "-ffixed-x18" might be required.
345      assert(is_android)
346
347      scs_parameters = [
348        "-fsanitize=shadow-call-stack",
349        "-fno-stack-protector",
350      ]
351      cflags += scs_parameters
352      ldflags += scs_parameters
353    } else {
354      if (is_apple) {
355        # The strong variant of the stack protector significantly increases
356        # binary size, so only enable it in debug mode.
357        if (is_debug) {
358          cflags += [ "-fstack-protector-strong" ]
359        } else {
360          cflags += [ "-fstack-protector" ]
361        }
362      } else if ((is_posix && !is_chromeos && !is_nacl) || is_fuchsia) {
363        # TODO(phajdan.jr): Use -fstack-protector-strong when our gcc supports it.
364        # See also https://crbug.com/533294
365        if (current_os != "zos") {
366          cflags += [ "--param=ssp-buffer-size=4" ]
367        }
368
369        # The x86 toolchain currently has problems with stack-protector.
370        if (is_android && current_cpu == "x86") {
371          cflags += [ "-fno-stack-protector" ]
372        } else if (current_os != "aix") {
373          # Not available on aix.
374          cflags += [ "-fstack-protector" ]
375        }
376      }
377    }
378
379    if (use_lld) {
380      ldflags += [ "-fuse-ld=lld" ]
381      if (lld_path != "") {
382        ldflags += [ "-B$lld_path" ]
383      }
384    }
385
386    # Linker warnings.
387    if (fatal_linker_warnings && !is_apple && current_os != "aix" &&
388        current_os != "zos") {
389      ldflags += [ "-Wl,--fatal-warnings" ]
390    }
391    if (fatal_linker_warnings && is_apple) {
392      ldflags += [ "-Wl,-fatal_warnings" ]
393    }
394  }
395
396  if (is_clang && is_debug) {
397    # Allow comparing the address of references and 'this' against 0
398    # in debug builds. Technically, these can never be null in
399    # well-defined C/C++ and Clang can optimize such checks away in
400    # release builds, but they may be used in asserts in debug builds.
401    cflags_cc += [
402      "-Wno-undefined-bool-conversion",
403      "-Wno-tautological-undefined-compare",
404    ]
405  }
406
407  # Non-Apple Posix and Fuchsia compiler flags setup.
408  # -----------------------------------
409  if ((is_posix && !is_apple) || is_fuchsia) {
410    if (enable_profiling) {
411      if (!is_debug) {
412        cflags += [ "-g" ]
413
414        if (enable_full_stack_frames_for_profiling) {
415          cflags += [
416            "-fno-inline",
417            "-fno-optimize-sibling-calls",
418          ]
419        }
420      }
421    }
422
423    # Explicitly pass --build-id to ld. Compilers used to always pass this
424    # implicitly but don't any more (in particular clang when built without
425    # ENABLE_LINKER_BUILD_ID=ON).
426    if (is_official_build) {
427      # The sha1 build id has lower risk of collision but is more expensive to
428      # compute, so only use it in the official build to avoid slowing down
429      # links.
430      ldflags += [ "-Wl,--build-id=sha1" ]
431    } else if (current_os != "aix" && current_os != "zos") {
432      ldflags += [ "-Wl,--build-id" ]
433    }
434
435    if (!is_android) {
436      defines += [
437        # _FILE_OFFSET_BITS=64 should not be set on Android in order to maintain
438        # the behavior of the Android NDK from earlier versions.
439        # See https://android-developers.googleblog.com/2017/09/introducing-android-native-development.html
440        "_FILE_OFFSET_BITS=64",
441        "_LARGEFILE_SOURCE",
442        "_LARGEFILE64_SOURCE",
443      ]
444    }
445
446    if (!is_nacl) {
447      if (exclude_unwind_tables) {
448        cflags += [
449          "-fno-unwind-tables",
450          "-fno-asynchronous-unwind-tables",
451        ]
452        rustflags += [ "-Cforce-unwind-tables=no" ]
453        defines += [ "NO_UNWIND_TABLES" ]
454      } else {
455        cflags += [ "-funwind-tables" ]
456        rustflags += [ "-Cforce-unwind-tables=yes" ]
457      }
458    }
459  }
460
461  # Apple compiler flags setup.
462  # ---------------------------------
463  if (is_apple) {
464    # On Intel, clang emits both Apple's "compact unwind" information and
465    # DWARF eh_frame unwind information by default, for compatibility reasons.
466    # This flag limits emission of eh_frame information to functions
467    # whose unwind information can't be expressed in the compact unwind format
468    # (which in practice means almost everything gets only compact unwind
469    # entries). This reduces object file size a bit and makes linking a bit
470    # faster.
471    # On arm64, this is already the default behavior.
472    if (current_cpu == "x64") {
473      asmflags += [ "-femit-dwarf-unwind=no-compact-unwind" ]
474      cflags += [ "-femit-dwarf-unwind=no-compact-unwind" ]
475    }
476  }
477
478  # Linux/Android/Fuchsia common flags setup.
479  # ---------------------------------
480  if (is_linux || is_chromeos || is_android || is_fuchsia) {
481    asmflags += [ "-fPIC" ]
482    cflags += [ "-fPIC" ]
483    ldflags += [ "-fPIC" ]
484    rustflags += [ "-Crelocation-model=pic" ]
485
486    if (!is_clang) {
487      # Use pipes for communicating between sub-processes. Faster.
488      # (This flag doesn't do anything with Clang.)
489      cflags += [ "-pipe" ]
490    }
491
492    ldflags += [
493      "-Wl,-z,noexecstack",
494      "-Wl,-z,relro",
495    ]
496
497    if (!is_component_build) {
498      ldflags += [ "-Wl,-z,now" ]
499    }
500  }
501
502  # Linux-specific compiler flags setup.
503  # ------------------------------------
504  if (use_gold) {
505    ldflags += [ "-fuse-ld=gold" ]
506    if (!is_android) {
507      # On Android, this isn't needed.  gcc in the NDK knows to look next to
508      # it with -fuse-ld=gold, and clang gets a --gcc-toolchain flag passed
509      # above.
510      if (gold_path != "") {
511        ldflags += [ "-B$gold_path" ]
512      }
513
514      ldflags += [
515        # Experimentation found that using four linking threads
516        # saved ~20% of link time.
517        # https://groups.google.com/a/chromium.org/group/chromium-dev/browse_thread/thread/281527606915bb36
518        # Only apply this to the target linker, since the host
519        # linker might not be gold, but isn't used much anyway.
520        "-Wl,--threads",
521        "-Wl,--thread-count=4",
522      ]
523    }
524
525    # TODO(thestig): Make this flag work with GN.
526    #if (!is_official_build && !is_chromeos && !(is_asan || is_lsan || is_tsan || is_msan)) {
527    #  ldflags += [
528    #    "-Wl,--detect-odr-violations",
529    #  ]
530    #}
531  }
532
533  if (use_icf && (!is_apple || use_lld)) {
534    ldflags += [ "-Wl,--icf=all" ]
535  }
536
537  if (is_linux || is_chromeos) {
538    cflags += [ "-pthread" ]
539    # Do not use the -pthread ldflag here since it becomes a no-op
540    # when using -nodefaultlibs, which would cause an unused argument
541    # error.  "-lpthread" is added in //build/config:default_libs.
542  }
543
544  # Clang-specific compiler flags setup.
545  # ------------------------------------
546  if (is_clang) {
547    cflags += [ "-fcolor-diagnostics" ]
548
549    # Enable -fmerge-all-constants. This used to be the default in clang
550    # for over a decade. It makes clang non-conforming, but is fairly safe
551    # in practice and saves some binary size. We might want to consider
552    # disabling this (https://bugs.llvm.org/show_bug.cgi?id=18538#c13),
553    # but for now it looks like our build might rely on it
554    # (https://crbug.com/829795).
555    cflags += [ "-fmerge-all-constants" ]
556  }
557
558  if (use_lld) {
559    # TODO(thakis): Make the driver pass --color-diagnostics to the linker
560    # if -fcolor-diagnostics is passed to it, and pass -fcolor-diagnostics
561    # in ldflags instead.
562    if (is_win) {
563      # On Windows, we call the linker directly, instead of calling it through
564      # the driver.
565      ldflags += [ "--color-diagnostics" ]
566    } else {
567      ldflags += [ "-Wl,--color-diagnostics" ]
568    }
569  }
570
571  # Enable text section splitting only on linux when using lld for now. Other
572  # platforms can be added later if needed.
573  if ((is_linux || is_chromeos) && use_lld && use_text_section_splitting) {
574    ldflags += [ "-Wl,-z,keep-text-section-prefix" ]
575  }
576
577  if (is_clang && !is_nacl && current_os != "zos") {
578    cflags += [ "-fcrash-diagnostics-dir=" + clang_diagnostic_dir ]
579    if (save_reproducers_on_lld_crash && use_lld) {
580      ldflags += [
581        "-fcrash-diagnostics=all",
582        "-fcrash-diagnostics-dir=" + clang_diagnostic_dir,
583      ]
584    }
585
586    # TODO(hans): Remove this once Clang generates better optimized debug info
587    # by default. https://crbug.com/765793
588    cflags += [
589      "-mllvm",
590      "-instcombine-lower-dbg-declare=0",
591    ]
592    if (!is_debug && use_thin_lto && is_a_target_toolchain) {
593      if (is_win) {
594        ldflags += [ "-mllvm:-instcombine-lower-dbg-declare=0" ]
595      } else {
596        ldflags += [ "-Wl,-mllvm,-instcombine-lower-dbg-declare=0" ]
597      }
598    }
599
600    # TODO(crbug.com/1235145): Investigate why/if this should be needed.
601    if (is_win) {
602      cflags += [ "/clang:-ffp-contract=off" ]
603    } else {
604      cflags += [ "-ffp-contract=off" ]
605    }
606  }
607
608  # C11/C++11 compiler flags setup.
609  # ---------------------------
610  if (is_linux || is_chromeos || is_android || (is_nacl && is_clang) ||
611      current_os == "aix") {
612    if (is_clang) {
613      standard_prefix = "c"
614
615      # Since we build with -std=c* and not -std=gnu*, _GNU_SOURCE will not be
616      # defined by the compiler.  However, lots of code relies on the
617      # non-standard features that _GNU_SOURCE enables, so define it manually.
618      defines += [ "_GNU_SOURCE" ]
619
620      if (is_nacl) {
621        # Undefine __STRICT_ANSI__ to get non-standard features which would
622        # otherwise not be enabled by NaCl's sysroots.
623        cflags += [ "-U__STRICT_ANSI__" ]
624      }
625    } else {
626      # Gcc does not support ##__VA_ARGS__ when in standards-conforming mode,
627      # but we use this feature in several places in Chromium.
628      # TODO(thomasanderson): Replace usages of ##__VA_ARGS__ with the
629      # standard-compliant __VA_OPT__ added by C++20, and switch the gcc build
630      # to -std=c*.
631      standard_prefix = "gnu"
632    }
633
634    cflags_c += [ "-std=${standard_prefix}11" ]
635    if (is_nacl && !is_nacl_saigo) {
636      # This is for the pnacl_newlib toolchain. It's only used to build
637      # a few independent ppapi test files that don't pull in any other
638      # dependencies.
639      cflags_cc += [ "-std=${standard_prefix}++14" ]
640      if (is_clang) {
641        cflags_cc += [ "-fno-trigraphs" ]
642      }
643    } else if (is_clang) {
644      if (use_cxx17) {
645        cflags_cc += [ "-std=${standard_prefix}++17" ]
646      } else {
647        cflags_cc += [ "-std=${standard_prefix}++20" ]
648      }
649    } else {
650      # The gcc bots are currently using GCC 9, which is not new enough to
651      # support "c++20"/"gnu++20".
652      cflags_cc += [ "-std=${standard_prefix}++2a" ]
653    }
654  } else if (is_win) {
655    cflags_c += [ "/std:c11" ]
656    if (use_cxx17 || (!is_clang && defined(msvc_use_cxx17) && msvc_use_cxx17)) {
657      cflags_cc += [ "/std:c++17" ]
658    } else {
659      cflags_cc += [ "/std:c++20" ]
660    }
661  } else if (!is_nacl) {
662    # TODO(mcgrathr) - the NaCl GCC toolchain doesn't support either
663    # gnu11/gnu++11 or c11/c++11; we technically don't need this toolchain any
664    # more, but there are still a few buildbots using it, so until those are
665    # turned off we need the !is_nacl clause and the (is_nacl && is_clang)
666    # clause, above.
667    cflags_c += [ "-std=c11" ]
668
669    if (use_cxx17) {
670      cflags_cc += [ "-std=c++17" ]
671    } else {
672      cflags_cc += [ "-std=c++20" ]
673    }
674  }
675
676  if (is_clang && current_os != "zos") {
677    # C++17 removes trigraph support, but clang still warns that it ignores
678    # them when seeing them.  Don't.
679    cflags_cc += [ "-Wno-trigraphs" ]
680  }
681
682  if (use_relative_vtables_abi) {
683    cflags_cc += [ "-fexperimental-relative-c++-abi-vtables" ]
684    ldflags += [ "-fexperimental-relative-c++-abi-vtables" ]
685  }
686
687  # Add flags for link-time optimization. These flags enable
688  # optimizations/transformations that require whole-program visibility at link
689  # time, so they need to be applied to all translation units, and we may end up
690  # with miscompiles if only part of the program is compiled with LTO flags. For
691  # that reason, we cannot allow targets to enable or disable these flags, for
692  # example by disabling the optimize configuration.
693  # TODO(pcc): Make this conditional on is_official_build rather than on gn
694  # flags for specific features.
695  if (!is_debug && use_thin_lto && is_a_target_toolchain) {
696    assert(use_lld, "LTO is only supported with lld")
697
698    cflags += [
699      "-flto=thin",
700      "-fsplit-lto-unit",
701    ]
702
703    # Limit the size of the ThinLTO cache to the lesser of 10% of
704    # available disk space, 40GB and 100000 files.
705    cache_policy = "cache_size=10%:cache_size_bytes=40g:cache_size_files=100000"
706
707    # An import limit of 30 has better performance (per speedometer) and lower
708    # binary size than the default setting of 100.
709    # TODO(gbiv): We ideally shouldn't need to specify this; ThinLTO
710    # should be able to better manage binary size increases on its own.
711    import_instr_limit = 30
712
713    if (is_win) {
714      ldflags += [
715        "/opt:lldltojobs=all",
716        "-mllvm:-import-instr-limit=$import_instr_limit",
717        "/lldltocache:" +
718            rebase_path("$root_out_dir/thinlto-cache", root_build_dir),
719        "/lldltocachepolicy:$cache_policy",
720        "-mllvm:-disable-auto-upgrade-debug-info",
721      ]
722    } else {
723      ldflags += [ "-flto=thin" ]
724
725      # Enabling ThinLTO on Chrome OS too, in an effort to reduce the memory
726      # usage in crbug.com/1038040. Note this will increase build time in
727      # Chrome OS.
728
729      # In ThinLTO builds, we run at most one link process at a time,
730      # and let it use all cores.
731      # TODO(thakis): Check if '=0' (that is, number of cores, instead
732      # of "all" which means number of hardware threads) is faster.
733      ldflags += [ "-Wl,--thinlto-jobs=all" ]
734      if (is_apple) {
735        ldflags += [
736          "-Wl,-cache_path_lto," +
737              rebase_path("$root_out_dir/thinlto-cache", root_build_dir),
738          "-Wcrl,object_path_lto",
739        ]
740      } else {
741        ldflags +=
742            [ "-Wl,--thinlto-cache-dir=" +
743              rebase_path("$root_out_dir/thinlto-cache", root_build_dir) ]
744      }
745
746      ldflags += [ "-Wl,--thinlto-cache-policy=$cache_policy" ]
747
748      if (is_chromeos) {
749        # ARM was originally set lower than x86 to keep the size
750        # bloat of ThinLTO to <10%, but that's potentially no longer true.
751        # FIXME(inglorion): maybe tune these?
752        # TODO(b/271459198): Revert limit on amd64 to 30 when fixed.
753        import_instr_limit = 20
754      } else if (is_android) {
755        # TODO(crbug.com/1308318): Investigate if we can get the > 6% perf win
756        # of import_instr_limit 30 with a binary size hit smaller than ~2 MiB.
757        import_instr_limit = 5
758      }
759
760      ldflags += [ "-Wl,-mllvm,-import-instr-limit=$import_instr_limit" ]
761
762      if (!is_chromeos) {
763        # TODO(https://crbug.com/972449): turn on for ChromeOS when that
764        # toolchain has this flag.
765        # We only use one version of LLVM within a build so there's no need to
766        # upgrade debug info, which can be expensive since it runs the verifier.
767        ldflags += [ "-Wl,-mllvm,-disable-auto-upgrade-debug-info" ]
768      }
769    }
770
771    # TODO(https://crbug.com/1211155): investigate why this isn't effective on
772    # arm32.
773    if (!is_android || current_cpu == "arm64") {
774      cflags += [ "-fwhole-program-vtables" ]
775
776      # whole-program-vtables implies -fsplit-lto-unit, and Rust needs to match
777      # behaviour. Rust needs to know the linker will be doing LTO in this case
778      # or it rejects the Zsplit-lto-unit flag.
779      rustflags += [
780        "-Zsplit-lto-unit",
781        "-Clinker-plugin-lto=yes",
782      ]
783
784      if (!is_win) {
785        ldflags += [ "-fwhole-program-vtables" ]
786      }
787    }
788
789    # This flag causes LTO to create an .ARM.attributes section with the correct
790    # architecture. This is necessary because LLD will refuse to link a program
791    # unless the architecture revision in .ARM.attributes is sufficiently new.
792    # TODO(pcc): The contents of .ARM.attributes should be based on the
793    # -march flag passed at compile time (see llvm.org/pr36291).
794    if (current_cpu == "arm") {
795      ldflags += [ "-march=$arm_arch" ]
796    }
797  }
798
799  if (compiler_timing) {
800    if (is_clang && !is_nacl) {
801      cflags += [ "-ftime-trace" ]
802    } else if (is_win) {
803      cflags += [
804        # "Documented" here:
805        # http://aras-p.info/blog/2017/10/23/Best-unknown-MSVC-flag-d2cgsummary/
806        "/d2cgsummary",
807      ]
808    }
809  }
810
811  # Pass flag to LLD so Android builds can allow debuggerd to properly symbolize
812  # stack crashes (http://crbug.com/919499).
813  if (use_lld && is_android) {
814    ldflags += [ "-Wl,--no-rosegment" ]
815  }
816
817  # TODO(crbug.com/1374347): Cleanup undefined symbol errors caught by
818  # --no-undefined-version.
819  if (use_lld && !is_win && !is_mac && !is_ios) {
820    ldflags += [ "-Wl,--undefined-version" ]
821  }
822
823  if (use_lld && is_apple) {
824    ldflags += [ "-Wl,--strict-auto-link" ]
825  }
826
827  # LLD does call-graph-sorted binary layout by default when profile data is
828  # present. On Android this increases binary size due to more thinks for long
829  # jumps. Turn it off by default and enable selectively for targets where it's
830  # beneficial.
831  if (use_lld && !enable_call_graph_profile_sort) {
832    if (is_win) {
833      ldflags += [ "/call-graph-profile-sort:no" ]
834    } else {
835      ldflags += [ "-Wl,--no-call-graph-profile-sort" ]
836    }
837  }
838
839  if (is_clang && !is_nacl && show_includes) {
840    if (is_win) {
841      # TODO(crbug.com/1223741): Goma mixes the -H and /showIncludes output.
842      assert(!use_goma, "show_includes on Windows is not reliable with goma")
843      cflags += [
844        "/clang:-H",
845        "/clang:-fshow-skipped-includes",
846      ]
847    } else {
848      cflags += [
849        "-H",
850        "-fshow-skipped-includes",
851      ]
852    }
853  }
854
855  # This flag enforces that member pointer base types are complete. It helps
856  # prevent us from running into problems in the Microsoft C++ ABI (see
857  # https://crbug.com/847724).
858  if (is_clang && !is_nacl && target_os != "chromeos" &&
859      (is_win || use_custom_libcxx)) {
860    cflags += [ "-fcomplete-member-pointers" ]
861  }
862
863  # Use DWARF simple template names, with the following exceptions:
864  #
865  # * Windows is not supported as it doesn't use DWARF.
866  # * Apple platforms (e.g. MacOS, iPhone, iPad) aren't supported because xcode
867  #   lldb doesn't have the needed changes yet.
868  # TODO(crbug.com/1379070): Remove if the upstream default ever changes.
869  if (is_clang && !is_nacl && !is_win && !is_apple) {
870    cflags_cc += [ "-gsimple-template-names" ]
871  }
872
873  # MLGO specific flags. These flags enable an ML-based inliner trained on
874  # Chrome on Android (arm32) with ThinLTO enabled, optimizing for size.
875  # The "release" ML model is embedded into clang as part of its build.
876  # Currently, the ML inliner is only enabled when targeting Android due to:
877  # a) Android is where size matters the most.
878  # b) MLGO presently has the limitation of only being able to embed one model
879  #    at a time; It is unclear if the embedded model is beneficial for
880  #    non-Android targets.
881  # MLGO is only officially supported on linux.
882  if (use_ml_inliner && is_a_target_toolchain) {
883    assert(
884        is_android && host_os == "linux",
885        "MLGO is currently only supported for targeting Android on a linux host")
886    if (use_thin_lto) {
887      ldflags += [ "-Wl,-mllvm,-enable-ml-inliner=release" ]
888    }
889  }
890
891  if (clang_embed_bitcode) {
892    assert(!use_thin_lto,
893           "clang_embed_bitcode is only supported in non-ThinLTO builds")
894    cflags += [
895      "-Xclang",
896      "-fembed-bitcode=all",
897    ]
898  }
899
900  if (lld_emit_indexes_and_imports) {
901    assert(use_thin_lto,
902           "lld_emit_indexes_and_imports is only supported with ThinLTO builds")
903    ldflags += [
904      "-Wl,--save-temps=import",
905      "-Wl,--thinlto-emit-index-files",
906    ]
907  }
908
909  # Pass the same C/C++ flags to the objective C/C++ compiler.
910  cflags_objc += cflags_c
911  cflags_objcc += cflags_cc
912
913  # Assign any flags set for the C compiler to asmflags so that they are sent
914  # to the assembler. The Windows assembler takes different types of flags
915  # so only do so for posix platforms.
916  if (is_posix || is_fuchsia) {
917    asmflags += cflags
918    asmflags += cflags_c
919  }
920
921  if (is_chromeos_device && !is_nacl) {
922    # On ChromeOS devices, we want to ensure we're using Chrome's allocator
923    # symbols for all C++ new/delete operator overloads. PartitionAlloc
924    # and other local allocators should always take precedence over system or
925    # preloaded allocators. These are the mangled symbol names.
926    # See b/280115910 for details.
927    ldflags += [
928      "-Wl,--export-dynamic-symbol=_ZdaPv,-u,_ZdaPv",
929      "-Wl,--export-dynamic-symbol=_ZdaPvRKSt9nothrow_t,-u,_ZdaPvRKSt9nothrow_t",
930      "-Wl,--export-dynamic-symbol=_ZdlPv,-u,_ZdlPv",
931      "-Wl,--export-dynamic-symbol=_ZdlPvm,-u,_ZdlPvm",
932      "-Wl,--export-dynamic-symbol=_ZdlPvRKSt9nothrow_t,-u,_ZdlPvRKSt9nothrow_t",
933      "-Wl,--export-dynamic-symbol=_Znam,-u,_Znam",
934      "-Wl,--export-dynamic-symbol=_ZnamRKSt9nothrow_t,-u,_ZnamRKSt9nothrow_t",
935      "-Wl,--export-dynamic-symbol=_Znwm,-u,_Znwm",
936      "-Wl,--export-dynamic-symbol=_ZnwmRKSt9nothrow_t,-u,_ZnwmRKSt9nothrow_t",
937      "-Wl,--export-dynamic-symbol=_ZdaPvmSt11align_val_t,-u,_ZdaPvmSt11align_val_t",
938      "-Wl,--export-dynamic-symbol=_ZdaPvSt11align_val_t,-u,_ZdaPvSt11align_val_t",
939      "-Wl,--export-dynamic-symbol=_ZdaPvSt11align_val_tRKSt9nothrow_t,-u,_ZdaPvSt11align_val_tRKSt9nothrow_t",
940      "-Wl,--export-dynamic-symbol=_ZdlPvmSt11align_val_t,-u,_ZdlPvmSt11align_val_t",
941      "-Wl,--export-dynamic-symbol=_ZdlPvSt11align_val_t,-u,_ZdlPvSt11align_val_t",
942      "-Wl,--export-dynamic-symbol=_ZdlPvSt11align_val_tRKSt9nothrow_t,-u,_ZdlPvSt11align_val_tRKSt9nothrow_t",
943      "-Wl,--export-dynamic-symbol=_ZnamSt11align_val_t,-u,_ZnamSt11align_val_t",
944      "-Wl,--export-dynamic-symbol=_ZnamSt11align_val_tRKSt9nothrow_t,-u,_ZnamSt11align_val_tRKSt9nothrow_t",
945      "-Wl,--export-dynamic-symbol=_ZnwmSt11align_val_t,-u,_ZnwmSt11align_val_t",
946      "-Wl,--export-dynamic-symbol=_ZnwmSt11align_val_tRKSt9nothrow_t,-u,_ZnwmSt11align_val_tRKSt9nothrow_t",
947    ]
948  }
949
950  # Rust compiler flags setup.
951  # ---------------------------
952  rustflags += [
953    # Overflow checks are optional in Rust, but even if switched
954    # off they do not cause undefined behavior (the overflowing
955    # behavior is defined). Because containers are bounds-checked
956    # in safe Rust, they also can't provoke buffer overflows.
957    # As such these checks may be less important in Rust than C++.
958    # But in (simplistic) testing they have negligible performance
959    # overhead, and this helps to provide consistent behavior
960    # between different configurations, so we'll keep them on until
961    # we discover a reason to turn them off.
962    "-Coverflow-checks=on",
963
964    # By default Rust passes `-nodefaultlibs` to the linker, however this
965    # conflicts with our `--unwind=none` flag for Android dylibs, as the latter
966    # is then unused and produces a warning/error. So this removes the
967    # `-nodefaultlibs` from the linker invocation from Rust, which would be used
968    # to compile dylibs on Android, such as for constructing unit test APKs.
969    "-Cdefault-linker-libraries",
970
971    # To make Rust .d files compatible with ninja
972    "-Zdep-info-omit-d-target",
973
974    # If a macro panics during compilation, show which macro and where it is
975    # defined.
976    "-Zmacro-backtrace",
977
978    # For deterministic builds, keep the local machine's current working
979    # directory from appearing in build outputs.
980    "-Zremap-cwd-prefix=.",
981  ]
982
983  if (!is_win || force_rustc_color_output) {
984    # Colorize error output. The analogous flag is passed for clang. This must
985    # be platform-gated since rustc will unconditionally output ANSI escape
986    # sequences, ignoring the platform, when stderr is not a terminal.
987    rustflags += [ "--color=always" ]
988  }
989  if (rust_abi_target != "") {
990    rustflags += [ "--target=$rust_abi_target" ]
991  }
992  if (!use_thin_lto) {
993    # Don't include bitcode if it won't be used.
994    rustflags += [ "-Cembed-bitcode=no" ]
995  }
996  if (is_official_build) {
997    rustflags += [ "-Ccodegen-units=1" ]
998  }
999  if (!rust_prebuilt_stdlib) {
1000    # When building against the Chromium Rust stdlib (which we compile) always
1001    # abort instead of unwinding when panic occurs. In official builds, panics
1002    # abort immediately (this is configured in the stdlib) to keep binary size
1003    # down. So we unconditionally match behaviour in unofficial too.
1004    rustflags += [
1005      "-Cpanic=abort",
1006      "-Zpanic_abort_tests",
1007    ]
1008  }
1009
1010  # Normally, this would be defined in the `runtime_library` config but NaCl
1011  # saigo libc++ does not use the custom hermetic libc++. Unfortunately, there
1012  # isn't really a better config to add this define for the define to
1013  # consistently apply in both Chromium and non-Chromium code *and* non-NaCl
1014  # and NaCl code.
1015  #
1016  # TODO(https://crbug.com/702997): Move this back to the `runtime_library`
1017  # config when NaCl is removed.
1018  if (use_safe_libcxx) {
1019    defines += [ "_LIBCPP_ENABLE_ASSERTIONS=1" ]
1020  }
1021}
1022
1023# The BUILDCONFIG file sets this config on targets by default, which means when
1024# building with ThinLTO, no optimization is performed in the link step.
1025config("thinlto_optimize_default") {
1026  if (!is_debug && use_thin_lto && is_a_target_toolchain) {
1027    lto_opt_level = 0
1028
1029    if (is_win) {
1030      ldflags = [ "/opt:lldlto=" + lto_opt_level ]
1031    } else {
1032      ldflags = [ "-Wl,--lto-O" + lto_opt_level ]
1033    }
1034
1035    # We always point Rust to a linker that performs LTO, so we don't want Rust
1036    # to preemptively do so during compilation too or they conflict. But we do
1037    # want Rust to generate LTO metadata in order for the linker to do its job.
1038    rustflags = [ "-Clinker-plugin-lto=yes" ]
1039  }
1040}
1041
1042# Use this to enable optimization in the ThinLTO link step for select targets
1043# when thin_lto_enable_optimizations is set by doing:
1044#
1045#   configs -= [ "//build/config/compiler:thinlto_optimize_default" ]
1046#   configs += [ "//build/config/compiler:thinlto_optimize_max" ]
1047#
1048# Since it makes linking significantly slower and more resource intensive, only
1049# use it on important targets such as the main browser executable or dll.
1050config("thinlto_optimize_max") {
1051  if (!is_debug && use_thin_lto && is_a_target_toolchain) {
1052    if (thin_lto_enable_optimizations) {
1053      lto_opt_level = 2
1054    } else {
1055      lto_opt_level = 0
1056    }
1057
1058    if (is_win) {
1059      ldflags = [ "/opt:lldlto=" + lto_opt_level ]
1060    } else {
1061      ldflags = [ "-Wl,--lto-O" + lto_opt_level ]
1062    }
1063
1064    # We always point Rust to a linker that performs LTO, so we don't want Rust
1065    # to preemptively do so during compilation too or they conflict. But we do
1066    # want Rust to generate LTO metadata in order for the linker to do its job.
1067    rustflags = [ "-Clinker-plugin-lto=yes" ]
1068  }
1069}
1070
1071# This provides the basic options to select the target CPU and ABI.
1072# It is factored out of "compiler" so that special cases can use this
1073# without using everything that "compiler" brings in.  Options that
1074# tweak code generation for a particular CPU do not belong here!
1075# See "compiler_codegen", below.
1076config("compiler_cpu_abi") {
1077  cflags = []
1078  ldflags = []
1079  defines = []
1080
1081  configs = []
1082  if (is_chromeos) {
1083    configs += [ "//build/config/chromeos:compiler_cpu_abi" ]
1084  }
1085
1086  # TODO(https://crbug.com/1383873): Remove this once figured out.
1087  if (is_apple && current_cpu == "arm64") {
1088    cflags += [ "-fno-global-isel" ]
1089    ldflags += [ "-fno-global-isel" ]
1090  }
1091
1092  if ((is_posix && !is_apple) || is_fuchsia) {
1093    # CPU architecture. We may or may not be doing a cross compile now, so for
1094    # simplicity we always explicitly set the architecture.
1095    if (current_cpu == "x64") {
1096      cflags += [
1097        "-m64",
1098        "-msse3",
1099      ]
1100      ldflags += [ "-m64" ]
1101    } else if (current_cpu == "x86") {
1102      cflags += [ "-m32" ]
1103      ldflags += [ "-m32" ]
1104      if (!is_nacl) {
1105        cflags += [
1106          "-mfpmath=sse",
1107          "-msse3",
1108        ]
1109      }
1110    } else if (current_cpu == "arm") {
1111      if (is_clang && !is_android && !is_nacl &&
1112          !(is_chromeos_lacros && is_chromeos_device)) {
1113        cflags += [ "--target=arm-linux-gnueabihf" ]
1114        ldflags += [ "--target=arm-linux-gnueabihf" ]
1115      }
1116      if (!is_nacl) {
1117        cflags += [
1118          "-march=$arm_arch",
1119          "-mfloat-abi=$arm_float_abi",
1120        ]
1121      }
1122      if (arm_tune != "") {
1123        cflags += [ "-mtune=$arm_tune" ]
1124      }
1125    } else if (current_cpu == "arm64") {
1126      if (is_clang && !is_android && !is_nacl && !is_fuchsia &&
1127          !(is_chromeos_lacros && is_chromeos_device)) {
1128        cflags += [ "--target=aarch64-linux-gnu" ]
1129        ldflags += [ "--target=aarch64-linux-gnu" ]
1130      }
1131    } else if (current_cpu == "mipsel" && !is_nacl) {
1132      ldflags += [ "-Wl,--hash-style=sysv" ]
1133      if (custom_toolchain == "") {
1134        if (is_clang) {
1135          if (is_android) {
1136            cflags += [ "--target=mipsel-linux-android" ]
1137            ldflags += [ "--target=mipsel-linux-android" ]
1138          } else {
1139            cflags += [ "--target=mipsel-linux-gnu" ]
1140            ldflags += [ "--target=mipsel-linux-gnu" ]
1141          }
1142        } else {
1143          cflags += [ "-EL" ]
1144          ldflags += [ "-EL" ]
1145        }
1146      }
1147
1148      if (mips_arch_variant == "r6") {
1149        cflags += [ "-mno-odd-spreg" ]
1150        ldflags += [ "-mips32r6" ]
1151        if (is_clang) {
1152          cflags += [
1153            "-march=mipsel",
1154            "-mcpu=mips32r6",
1155          ]
1156        } else {
1157          cflags += [
1158            "-mips32r6",
1159            "-Wa,-mips32r6",
1160          ]
1161          if (is_android) {
1162            ldflags += [ "-Wl,-melf32ltsmip" ]
1163          }
1164        }
1165        if (mips_use_msa == true) {
1166          cflags += [
1167            "-mmsa",
1168            "-mfp64",
1169          ]
1170        }
1171      } else if (mips_arch_variant == "r2") {
1172        ldflags += [ "-mips32r2" ]
1173        if (is_clang) {
1174          cflags += [
1175            "-march=mipsel",
1176            "-mcpu=mips32r2",
1177          ]
1178        } else {
1179          cflags += [
1180            "-mips32r2",
1181            "-Wa,-mips32r2",
1182          ]
1183          if (mips_float_abi == "hard" && mips_fpu_mode != "") {
1184            cflags += [ "-m$mips_fpu_mode" ]
1185          }
1186        }
1187      } else if (mips_arch_variant == "r1") {
1188        ldflags += [ "-mips32" ]
1189        if (is_clang) {
1190          cflags += [
1191            "-march=mipsel",
1192            "-mcpu=mips32",
1193          ]
1194        } else {
1195          cflags += [
1196            "-mips32",
1197            "-Wa,-mips32",
1198          ]
1199        }
1200      } else if (mips_arch_variant == "loongson3") {
1201        defines += [ "_MIPS_ARCH_LOONGSON" ]
1202        cflags += [
1203          "-march=loongson3a",
1204          "-mno-branch-likely",
1205          "-Wa,-march=loongson3a",
1206        ]
1207      }
1208
1209      if (mips_dsp_rev == 1) {
1210        cflags += [ "-mdsp" ]
1211      } else if (mips_dsp_rev == 2) {
1212        cflags += [ "-mdspr2" ]
1213      }
1214
1215      cflags += [ "-m${mips_float_abi}-float" ]
1216    } else if (current_cpu == "mips" && !is_nacl) {
1217      ldflags += [ "-Wl,--hash-style=sysv" ]
1218      if (custom_toolchain == "") {
1219        if (is_clang) {
1220          cflags += [ "--target=mips-linux-gnu" ]
1221          ldflags += [ "--target=mips-linux-gnu" ]
1222        } else {
1223          cflags += [ "-EB" ]
1224          ldflags += [ "-EB" ]
1225        }
1226      }
1227
1228      if (mips_arch_variant == "r6") {
1229        cflags += [
1230          "-mips32r6",
1231          "-Wa,-mips32r6",
1232        ]
1233        if (mips_use_msa == true) {
1234          cflags += [
1235            "-mmsa",
1236            "-mfp64",
1237          ]
1238        }
1239      } else if (mips_arch_variant == "r2") {
1240        cflags += [
1241          "-mips32r2",
1242          "-Wa,-mips32r2",
1243        ]
1244        if (mips_float_abi == "hard" && mips_fpu_mode != "") {
1245          cflags += [ "-m$mips_fpu_mode" ]
1246        }
1247      } else if (mips_arch_variant == "r1") {
1248        cflags += [
1249          "-mips32",
1250          "-Wa,-mips32",
1251        ]
1252      }
1253
1254      if (mips_dsp_rev == 1) {
1255        cflags += [ "-mdsp" ]
1256      } else if (mips_dsp_rev == 2) {
1257        cflags += [ "-mdspr2" ]
1258      }
1259
1260      cflags += [ "-m${mips_float_abi}-float" ]
1261    } else if (current_cpu == "mips64el") {
1262      cflags += [ "-D__SANE_USERSPACE_TYPES__" ]
1263      ldflags += [ "-Wl,--hash-style=sysv" ]
1264      if (custom_toolchain == "") {
1265        if (is_clang) {
1266          if (is_android) {
1267            cflags += [ "--target=mips64el-linux-android" ]
1268            ldflags += [ "--target=mips64el-linux-android" ]
1269          } else {
1270            cflags += [ "--target=mips64el-linux-gnuabi64" ]
1271            ldflags += [ "--target=mips64el-linux-gnuabi64" ]
1272          }
1273        } else {
1274          cflags += [
1275            "-EL",
1276            "-mabi=64",
1277          ]
1278          ldflags += [
1279            "-EL",
1280            "-mabi=64",
1281          ]
1282        }
1283      }
1284
1285      if (mips_arch_variant == "r6") {
1286        if (is_clang) {
1287          cflags += [
1288            "-march=mips64el",
1289            "-mcpu=mips64r6",
1290          ]
1291        } else {
1292          cflags += [
1293            "-mips64r6",
1294            "-Wa,-mips64r6",
1295          ]
1296          ldflags += [ "-mips64r6" ]
1297        }
1298        if (mips_use_msa == true) {
1299          cflags += [
1300            "-mmsa",
1301            "-mfp64",
1302          ]
1303        }
1304      } else if (mips_arch_variant == "r2") {
1305        ldflags += [ "-mips64r2" ]
1306        if (is_clang) {
1307          cflags += [
1308            "-march=mips64el",
1309            "-mcpu=mips64r2",
1310          ]
1311        } else {
1312          cflags += [
1313            "-mips64r2",
1314            "-Wa,-mips64r2",
1315          ]
1316        }
1317      } else if (mips_arch_variant == "loongson3") {
1318        defines += [ "_MIPS_ARCH_LOONGSON" ]
1319        cflags += [
1320          "-march=loongson3a",
1321          "-mno-branch-likely",
1322          "-Wa,-march=loongson3a",
1323        ]
1324      }
1325    } else if (current_cpu == "mips64") {
1326      ldflags += [ "-Wl,--hash-style=sysv" ]
1327      if (custom_toolchain == "") {
1328        if (is_clang) {
1329          cflags += [ "--target=mips64-linux-gnuabi64" ]
1330          ldflags += [ "--target=mips64-linux-gnuabi64" ]
1331        } else {
1332          cflags += [
1333            "-EB",
1334            "-mabi=64",
1335          ]
1336          ldflags += [
1337            "-EB",
1338            "-mabi=64",
1339          ]
1340        }
1341      }
1342
1343      if (mips_arch_variant == "r6") {
1344        cflags += [
1345          "-mips64r6",
1346          "-Wa,-mips64r6",
1347        ]
1348        ldflags += [ "-mips64r6" ]
1349
1350        if (mips_use_msa == true) {
1351          cflags += [
1352            "-mmsa",
1353            "-mfp64",
1354          ]
1355        }
1356      } else if (mips_arch_variant == "r2") {
1357        cflags += [
1358          "-mips64r2",
1359          "-Wa,-mips64r2",
1360        ]
1361        ldflags += [ "-mips64r2" ]
1362      }
1363    } else if (current_cpu == "ppc64") {
1364      if (current_os == "aix") {
1365        cflags += [ "-maix64" ]
1366        ldflags += [ "-maix64" ]
1367      } else {
1368        cflags += [ "-m64" ]
1369        ldflags += [ "-m64" ]
1370      }
1371    } else if (current_cpu == "riscv64") {
1372      if (is_clang && !is_android) {
1373        cflags += [ "--target=riscv64-linux-gnu" ]
1374        ldflags += [ "--target=riscv64-linux-gnu" ]
1375      }
1376      cflags += [ "-mabi=lp64d" ]
1377    } else if (current_cpu == "loong64") {
1378      if (is_clang) {
1379        cflags += [ "--target=loongarch64-linux-gnu" ]
1380        ldflags += [ "--target=loongarch64-linux-gnu" ]
1381      }
1382      cflags += [
1383        "-mabi=lp64d",
1384        "-mcmodel=medium",
1385      ]
1386    } else if (current_cpu == "s390x") {
1387      cflags += [ "-m64" ]
1388      ldflags += [ "-m64" ]
1389    }
1390  }
1391
1392  asmflags = cflags
1393}
1394
1395# This provides options to tweak code generation that are necessary
1396# for particular Chromium code or for working around particular
1397# compiler bugs (or the combination of the two).
1398config("compiler_codegen") {
1399  configs = []
1400  cflags = []
1401  ldflags = []
1402
1403  if (is_nacl) {
1404    configs += [ "//build/config/nacl:compiler_codegen" ]
1405  }
1406
1407  if (current_cpu == "arm64" && !is_win && is_clang) {
1408    # Disable outlining everywhere on arm64 except Win. For more information see
1409    # crbug.com/931297 for Android and crbug.com/1410297 for iOS.
1410    # TODO(crbug.com/1411363): Enable this on Windows if possible.
1411    cflags += [ "-mno-outline" ]
1412
1413    # This can be removed once https://bugs.llvm.org/show_bug.cgi?id=40348
1414    # has been resolved, and -mno-outline is obeyed by the linker during
1415    # ThinLTO.
1416    ldflags += [ "-Wl,-mllvm,-enable-machine-outliner=never" ]
1417  }
1418
1419  asmflags = cflags
1420}
1421
1422# This provides options that make the build deterministic, so that the same
1423# revision produces the same output, independent of the name of the build
1424# directory and of the computer the build is done on.
1425# The relative path from build dir to source dir makes it into the build
1426# outputs, so it's recommended that you use a build dir two levels deep
1427# (e.g. "out/Release") so that you get the same "../.." path as all the bots
1428# in your build outputs.
1429config("compiler_deterministic") {
1430  cflags = []
1431  ldflags = []
1432  swiftflags = []
1433
1434  # Eliminate build metadata (__DATE__, __TIME__ and __TIMESTAMP__) for
1435  # deterministic build.  See https://crbug.com/314403
1436  if (!is_official_build) {
1437    if (is_win && !is_clang) {
1438      cflags += [
1439        "/wd4117",  # Trying to define or undefine a predefined macro.
1440        "/D__DATE__=",
1441        "/D__TIME__=",
1442        "/D__TIMESTAMP__=",
1443      ]
1444    } else {
1445      cflags += [
1446        "-Wno-builtin-macro-redefined",
1447        "-D__DATE__=",
1448        "-D__TIME__=",
1449        "-D__TIMESTAMP__=",
1450      ]
1451    }
1452  }
1453
1454  # Makes builds independent of absolute file path.
1455  if (is_clang && strip_absolute_paths_from_debug_symbols) {
1456    # If debug option is given, clang includes $cwd in debug info by default.
1457    # For such build, this flag generates reproducible obj files even we use
1458    # different build directory like "out/feature_a" and "out/feature_b" if
1459    # we build same files with same compile flag.
1460    # Other paths are already given in relative, no need to normalize them.
1461    if (is_nacl) {
1462      # TODO(https://crbug.com/1231236): Use -ffile-compilation-dir= here.
1463      cflags += [
1464        "-Xclang",
1465        "-fdebug-compilation-dir",
1466        "-Xclang",
1467        ".",
1468      ]
1469    } else {
1470      # -ffile-compilation-dir is an alias for both -fdebug-compilation-dir=
1471      # and -fcoverage-compilation-dir=.
1472      cflags += [ "-ffile-compilation-dir=." ]
1473      swiftflags += [ "-file-compilation-dir=." ]
1474    }
1475    if (!is_win) {
1476      # We don't use clang -cc1as on Windows (yet? https://crbug.com/762167)
1477      asmflags = [ "-Wa,-fdebug-compilation-dir,." ]
1478    }
1479
1480    if (is_win && use_lld) {
1481      if (symbol_level == 2 || (is_clang && using_sanitizer)) {
1482        # Absolutize source file paths for PDB. Pass the real build directory
1483        # if the pdb contains source-level debug information and if linker
1484        # reproducibility is not critical.
1485        ldflags += [ "/PDBSourcePath:" + rebase_path(root_build_dir) ]
1486      } else {
1487        # Use a fake fixed base directory for paths in the pdb to make the pdb
1488        # output fully deterministic and independent of the build directory.
1489        ldflags += [ "/PDBSourcePath:o:\fake\prefix" ]
1490      }
1491    }
1492  }
1493
1494  # Tells the compiler not to use absolute paths when passing the default
1495  # paths to the tools it invokes. We don't want this because we don't
1496  # really need it and it can mess up the goma cache entries.
1497  if (is_clang && (!is_nacl || is_nacl_saigo)) {
1498    cflags += [ "-no-canonical-prefixes" ]
1499
1500    # Same for links: Let the compiler driver invoke the linker
1501    # with a relative path and pass relative paths to built-in
1502    # libraries. Not needed on Windows because we call the linker
1503    # directly there, not through the compiler driver.
1504    # We don't link on goma, so this change is just for cleaner
1505    # internal linker invocations, for people who work on the build.
1506    if (!is_win) {
1507      ldflags += [ "-no-canonical-prefixes" ]
1508    }
1509  }
1510}
1511
1512config("clang_revision") {
1513  if (is_clang && clang_base_path == default_clang_base_path) {
1514    update_args = [
1515      "--print-revision",
1516      "--verify-version=$clang_version",
1517    ]
1518    if (llvm_force_head_revision) {
1519      update_args += [ "--llvm-force-head-revision" ]
1520    }
1521    clang_revision = exec_script("//tools/clang/scripts/update.py",
1522                                 update_args,
1523                                 "trim string")
1524
1525    # This is here so that all files get recompiled after a clang roll and
1526    # when turning clang on or off. (defines are passed via the command line,
1527    # and build system rebuild things when their commandline changes). Nothing
1528    # should ever read this define.
1529    defines = [ "CR_CLANG_REVISION=\"$clang_revision\"" ]
1530  }
1531}
1532
1533config("rustc_revision") {
1534  if (rustc_revision != "") {
1535    # Similar to the above config, this is here so that all files get recompiled
1536    # after a rustc roll. Nothing should ever read this cfg. This will not be
1537    # set if a custom toolchain is used.
1538    rustflags = [
1539      "--cfg",
1540      "cr_rustc_revision=\"$rustc_revision\"",
1541    ]
1542  }
1543}
1544
1545config("compiler_arm_fpu") {
1546  if (current_cpu == "arm" && !is_ios && !is_nacl) {
1547    cflags = [ "-mfpu=$arm_fpu" ]
1548    if (!arm_use_thumb) {
1549      cflags += [ "-marm" ]
1550    }
1551    asmflags = cflags
1552  }
1553}
1554
1555config("compiler_arm_thumb") {
1556  if (current_cpu == "arm" && arm_use_thumb && is_posix &&
1557      !(is_apple || is_nacl)) {
1558    cflags = [ "-mthumb" ]
1559  }
1560}
1561
1562config("compiler_arm") {
1563  if (current_cpu == "arm" && is_chromeos) {
1564    # arm is normally the default mode for clang, but on chromeos a wrapper
1565    # is used to pass -mthumb, and therefor change the default.
1566    cflags = [ "-marm" ]
1567  }
1568}
1569
1570# runtime_library -------------------------------------------------------------
1571#
1572# Sets the runtime library and associated options.
1573#
1574# How do you determine what should go in here vs. "compiler" above? Consider if
1575# a target might choose to use a different runtime library (ignore for a moment
1576# if this is possible or reasonable on your system). If such a target would want
1577# to change or remove your option, put it in the runtime_library config. If a
1578# target wants the option regardless, put it in the compiler config.
1579
1580config("runtime_library") {
1581  configs = []
1582
1583  # The order of this config is important: it must appear before
1584  # android:runtime_library.  This is to ensure libc++ appears before
1585  # libandroid_support in the -isystem include order.  Otherwise, there will be
1586  # build errors related to symbols declared in math.h.
1587  if (use_custom_libcxx) {
1588    configs += [ "//build/config/c++:runtime_library" ]
1589  }
1590
1591  # Rust and C++ both provide intrinsics for LLVM to call for math operations. We
1592  # want to use the C++ intrinsics, not the ones in the Rust compiler_builtins
1593  # library. The Rust symbols are marked as weak, so that they can be replaced by
1594  # the C++ symbols. This config ensures the C++ symbols exist and are strong in
1595  # order to cause that replacement to occur by explicitly linking in clang's
1596  # compiler-rt library.
1597  if (is_clang && toolchain_has_rust) {
1598    configs += [ "//build/config/clang:compiler_builtins" ]
1599  }
1600
1601  # TODO(crbug.com/830987): Come up with a better name for is POSIX + Fuchsia
1602  # configuration.
1603  if (is_posix || is_fuchsia) {
1604    configs += [ "//build/config/posix:runtime_library" ]
1605
1606    if (use_custom_libunwind) {
1607      # Instead of using an unwind lib from the toolchain,
1608      # buildtools/third_party/libunwind will be built and used directly.
1609      ldflags = [ "--unwindlib=none" ]
1610    }
1611  }
1612
1613  # System-specific flags. If your compiler flags apply to one of the
1614  # categories here, add it to the associated file to keep this shared config
1615  # smaller.
1616  if (is_win) {
1617    configs += [ "//build/config/win:runtime_library" ]
1618  } else if (is_linux || is_chromeos) {
1619    configs += [ "//build/config/linux:runtime_library" ]
1620    if (is_chromeos) {
1621      configs += [ "//build/config/chromeos:runtime_library" ]
1622    }
1623  } else if (is_ios) {
1624    configs += [ "//build/config/ios:runtime_library" ]
1625  } else if (is_mac) {
1626    configs += [ "//build/config/mac:runtime_library" ]
1627  } else if (is_android) {
1628    configs += [ "//build/config/android:runtime_library" ]
1629  }
1630
1631  if (is_component_build) {
1632    defines = [ "COMPONENT_BUILD" ]
1633  }
1634}
1635
1636# default_warnings ------------------------------------------------------------
1637#
1638# Collects all warning flags that are used by default.  This is used as a
1639# subconfig of both chromium_code and no_chromium_code.  This way these
1640# flags are guaranteed to appear on the compile command line after -Wall.
1641config("default_warnings") {
1642  cflags = []
1643  cflags_c = []
1644  cflags_cc = []
1645  ldflags = []
1646
1647  if (is_win) {
1648    if (treat_warnings_as_errors) {
1649      cflags += [ "/WX" ]
1650    }
1651    if (fatal_linker_warnings) {
1652      arflags = [ "/WX" ]
1653      ldflags = [ "/WX" ]
1654    }
1655    defines = [
1656      # Without this, Windows headers warn that functions like wcsnicmp
1657      # should be spelled _wcsnicmp. But all other platforms keep spelling
1658      # it wcsnicmp, making this warning unhelpful. We don't want it.
1659      "_CRT_NONSTDC_NO_WARNINGS",
1660
1661      # TODO(thakis): winsock wants us to use getaddrinfo instead of
1662      # gethostbyname. Fires mostly in non-Chromium code. We probably
1663      # want to remove this define eventually.
1664      "_WINSOCK_DEPRECATED_NO_WARNINGS",
1665    ]
1666    if (!is_clang) {
1667      # TODO(thakis): Remove this once
1668      # https://swiftshader-review.googlesource.com/c/SwiftShader/+/57968 has
1669      # rolled into angle.
1670      cflags += [ "/wd4244" ]
1671    }
1672  } else {
1673    if (is_apple && !is_nacl) {
1674      # When compiling Objective-C, warns if a method is used whose
1675      # availability is newer than the deployment target.
1676      cflags += [ "-Wunguarded-availability" ]
1677    }
1678
1679    if (is_ios) {
1680      # When compiling Objective-C, warns if a selector named via @selector has
1681      # not been defined in any visible interface.
1682      cflags += [ "-Wundeclared-selector" ]
1683    }
1684
1685    # Suppress warnings about ABI changes on ARM (Clang doesn't give this
1686    # warning).
1687    if (current_cpu == "arm" && !is_clang) {
1688      cflags += [ "-Wno-psabi" ]
1689    }
1690
1691    if (!is_clang) {
1692      cflags_cc += [
1693        # See comment for -Wno-c++11-narrowing.
1694        "-Wno-narrowing",
1695      ]
1696
1697      # -Wno-class-memaccess warns about hash table and vector in blink.
1698      # But the violation is intentional.
1699      if (!is_nacl) {
1700        cflags_cc += [ "-Wno-class-memaccess" ]
1701      }
1702
1703      # -Wunused-local-typedefs is broken in gcc,
1704      # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63872
1705      cflags += [ "-Wno-unused-local-typedefs" ]
1706
1707      # Don't warn about "maybe" uninitialized. Clang doesn't include this
1708      # in -Wall but gcc does, and it gives false positives.
1709      cflags += [ "-Wno-maybe-uninitialized" ]
1710      cflags += [ "-Wno-deprecated-declarations" ]
1711
1712      # -Wcomment gives too many false positives in the case a
1713      # backslash ended comment line is followed by a new line of
1714      # comments
1715      # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61638
1716      cflags += [ "-Wno-comments" ]
1717
1718      # -Wpacked-not-aligned complains all generated mojom-shared-internal.h
1719      # files.
1720      cflags += [ "-Wno-packed-not-aligned" ]
1721    }
1722  }
1723
1724  # Common Clang and GCC warning setup.
1725  if (!is_win || is_clang) {
1726    cflags += [
1727      # Disables.
1728      "-Wno-missing-field-initializers",  # "struct foo f = {0};"
1729      "-Wno-unused-parameter",  # Unused function parameters.
1730    ]
1731
1732    if (!is_nacl || is_nacl_saigo) {
1733      cflags += [
1734        # An ABI compat warning we don't care about, https://crbug.com/1102157
1735        # TODO(thakis): Push this to the (few) targets that need it,
1736        # instead of having a global flag.
1737        "-Wno-psabi",
1738      ]
1739    }
1740  }
1741
1742  if (is_clang) {
1743    cflags += [
1744      "-Wloop-analysis",
1745
1746      # TODO(thakis): This used to be implied by -Wno-unused-function,
1747      # which we no longer use. Check if it makes sense to remove
1748      # this as well. http://crbug.com/316352
1749      "-Wno-unneeded-internal-declaration",
1750    ]
1751
1752    if (!is_nacl || is_nacl_saigo) {
1753      if (is_win) {
1754        # TODO(thakis): https://crbug.com/617318
1755        # Currently goma can not handle case sensitiveness for windows well.
1756        cflags += [ "-Wno-nonportable-include-path" ]
1757      }
1758
1759      cflags += [
1760        "-Wenum-compare-conditional",
1761
1762        # Ignore warnings about MSVC optimization pragmas.
1763        # TODO(thakis): Only for no_chromium_code? http://crbug.com/912662
1764        "-Wno-ignored-pragma-optimize",
1765      ]
1766
1767      if (!is_nacl) {
1768        cflags += [
1769          # TODO(crbug.com/1343975) Evaluate and possibly enable.
1770          "-Wno-deprecated-builtins",
1771
1772          # TODO(crbug.com/1352183) Evaluate and possibly enable.
1773          "-Wno-bitfield-constant-conversion",
1774
1775          # TODO(crbug.com/1412713) Evaluate and possibly enable.
1776          "-Wno-deprecated-this-capture",
1777        ]
1778      }
1779    }
1780
1781    # Some builders, such as Cronet, use a different version of Clang than
1782    # Chromium. This can cause minor errors when compiling Chromium changes. We
1783    # want to avoid these errors.
1784    if (use_lenient_compiler_flags) {
1785      cflags += [
1786        "-Wno-error=unknown-warning-option",
1787        "-Wno-error=unused-command-line-argument",
1788      ]
1789    }
1790  }
1791
1792  # Rust warnings
1793
1794  # Require `unsafe` blocks even in `unsafe` fns. This is intended to become
1795  # an error by default eventually; see
1796  # https://github.com/rust-lang/rust/issues/71668
1797  rustflags = [ "-Dunsafe_op_in_unsafe_fn" ]
1798}
1799
1800# prevent_unsafe_narrowing ----------------------------------------------------
1801#
1802# Warnings that prevent narrowing or comparisons of integer types that are
1803# likely to cause out-of-bound read/writes or Undefined Behaviour. In
1804# particular, size_t is used for memory sizes, allocation, indexing, and
1805# offsets. Using other integer types along with size_t produces risk of
1806# memory-safety bugs and thus security exploits.
1807#
1808# In order to prevent these bugs, allocation sizes were historically limited to
1809# sizes that can be represented within 31 bits of information, allowing `int` to
1810# be safely misused instead of `size_t` (https://crbug.com/169327). In order to
1811# support increasing the allocation limit we require strictly adherence to
1812# using the correct types, avoiding lossy conversions, and preventing overflow.
1813# To do so, enable this config and fix errors by converting types to be
1814# `size_t`, which is both large enough and unsigned, when dealing with memory
1815# sizes, allocations, indices, or offsets.In cases where type conversion is not
1816# possible or is superfluous, use base::strict_cast<> or base::checked_cast<>
1817# to convert to size_t as needed.
1818# See also: https://docs.google.com/document/d/1CTbQ-5cQjnjU8aCOtLiA7G6P0i5C6HpSDNlSNq6nl5E
1819#
1820# To enable in a GN target, use:
1821#   configs += [ "//build/config/compiler:prevent_unsafe_narrowing" ]
1822
1823config("prevent_unsafe_narrowing") {
1824  if (is_clang) {
1825    cflags = [
1826      "-Wshorten-64-to-32",
1827      "-Wimplicit-int-conversion",
1828      "-Wsign-compare",
1829      "-Wsign-conversion",
1830    ]
1831    if (!is_nacl) {
1832      cflags += [
1833        # Avoid bugs of the form `if (size_t i = size; i >= 0; --i)` while
1834        # fixing types to be sign-correct.
1835        "-Wtautological-unsigned-zero-compare",
1836      ]
1837    }
1838  }
1839}
1840
1841# chromium_code ---------------------------------------------------------------
1842#
1843# Toggles between higher and lower warnings for code that is (or isn't)
1844# part of Chromium.
1845
1846config("chromium_code") {
1847  if (is_win) {
1848    if (is_clang) {
1849      cflags = [ "/W4" ]  # Warning level 4.
1850
1851      # Opt in to additional [[nodiscard]] on standard library methods.
1852      defines = [ "_HAS_NODISCARD" ]
1853    }
1854  } else {
1855    cflags = [ "-Wall" ]
1856    if (treat_warnings_as_errors) {
1857      cflags += [ "-Werror" ]
1858
1859      # The compiler driver can sometimes (rarely) emit warnings before calling
1860      # the actual linker.  Make sure these warnings are treated as errors as
1861      # well.
1862      ldflags = [ "-Werror" ]
1863    }
1864    if (is_clang) {
1865      # Enable extra warnings for chromium_code when we control the compiler.
1866      cflags += [ "-Wextra" ]
1867    }
1868
1869    if (treat_warnings_as_errors) {
1870      # Turn rustc warnings into the "deny" lint level, which produce compiler
1871      # errors. The equivalent of -Werror for clang/gcc.
1872      #
1873      # Note we apply the actual lint flags in config("compiler"). All warnings
1874      # are suppressed in third-party crates.
1875      rustflags = [ "-Dwarnings" ]
1876    }
1877
1878    # In Chromium code, we define __STDC_foo_MACROS in order to get the
1879    # C99 macros on Mac and Linux.
1880    defines = [
1881      "__STDC_CONSTANT_MACROS",
1882      "__STDC_FORMAT_MACROS",
1883    ]
1884
1885    if (!is_debug && !using_sanitizer && current_cpu != "s390x" &&
1886        current_cpu != "s390" && current_cpu != "ppc64" &&
1887        current_cpu != "mips" && current_cpu != "mips64" &&
1888        current_cpu != "riscv64" && current_cpu != "loong64") {
1889      # Non-chromium code is not guaranteed to compile cleanly with
1890      # _FORTIFY_SOURCE. Also, fortified build may fail when optimizations are
1891      # disabled, so only do that for Release build.
1892      defines += [ "_FORTIFY_SOURCE=2" ]
1893    }
1894
1895    if (is_apple) {
1896      cflags_objc = [ "-Wimplicit-retain-self" ]
1897      cflags_objcc = [ "-Wimplicit-retain-self" ]
1898    }
1899
1900    if (is_mac) {
1901      cflags_objc += [ "-Wobjc-missing-property-synthesis" ]
1902      cflags_objcc += [ "-Wobjc-missing-property-synthesis" ]
1903    }
1904  }
1905
1906  if (is_clang) {
1907    cflags += [
1908      # Warn on missing break statements at the end of switch cases.
1909      # For intentional fallthrough, use [[fallthrough]].
1910      "-Wimplicit-fallthrough",
1911
1912      # Warn on unnecessary extra semicolons outside of function definitions.
1913      "-Wextra-semi",
1914    ]
1915
1916    # TODO(thakis): Enable this more often, https://crbug.com/346399
1917    # use_fuzzing_engine_with_lpm: https://crbug.com/1063180
1918    if ((!is_nacl || is_nacl_saigo) && !use_fuzzing_engine_with_lpm) {
1919      cflags += [ "-Wunreachable-code-aggressive" ]
1920    }
1921
1922    # Thread safety analysis is broken under nacl: https://crbug.com/982423.
1923    if (!is_nacl || is_nacl_saigo) {
1924      cflags += [
1925        # Thread safety analysis. See base/thread_annotations.h and
1926        # https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
1927        "-Wthread-safety",
1928      ]
1929    }
1930  }
1931
1932  configs = [
1933    ":default_warnings",
1934    ":noshadowing",
1935  ]
1936}
1937
1938config("no_chromium_code") {
1939  cflags = []
1940  cflags_cc = []
1941  defines = []
1942
1943  if (is_win) {
1944    if (is_clang) {
1945      cflags += [ "/W3" ]  # Warning level 3.
1946    }
1947    cflags += [
1948      "/wd4800",  # Disable warning when forcing value to bool.
1949      "/wd4267",  # TODO(jschuh): size_t to int.
1950    ]
1951  } else {
1952    # GCC may emit unsuppressible warnings so don't add -Werror for no chromium
1953    # code. crbug.com/589724
1954    if (treat_warnings_as_errors && is_clang) {
1955      cflags += [ "-Werror" ]
1956      ldflags = [ "-Werror" ]
1957    }
1958    if (is_clang && !is_nacl) {
1959      # TODO(thakis): Remove !is_nacl once
1960      # https://codereview.webrtc.org/1552863002/ made its way into chromium.
1961      cflags += [ "-Wall" ]
1962    }
1963  }
1964
1965  if (is_clang) {
1966    cflags += [
1967      # Lots of third-party libraries have unused variables. Instead of
1968      # suppressing them individually, we just blanket suppress them here.
1969      "-Wno-unused-variable",
1970
1971      # Similarly, we're not going to fix all the C++11 narrowing issues in
1972      # third-party libraries.
1973      "-Wno-c++11-narrowing",
1974    ]
1975    if (!is_nacl) {
1976      cflags += [
1977        # Disabled for similar reasons as -Wunused-variable.
1978        "-Wno-unused-but-set-variable",
1979
1980        # TODO(https://crbug.com/1202159): Clean up and enable.
1981        "-Wno-misleading-indentation",
1982      ]
1983    }
1984  }
1985
1986  # Suppress all warnings in third party, as Cargo does:
1987  # https://doc.rust-lang.org/rustc/lints/levels.html#capping-lints
1988  rustflags = [ "--cap-lints=allow" ]
1989
1990  configs = [ ":default_warnings" ]
1991}
1992
1993# noshadowing -----------------------------------------------------------------
1994#
1995# Allows turning -Wshadow on.
1996
1997config("noshadowing") {
1998  # This flag has to be disabled for nacl because the nacl compiler is too
1999  # strict about shadowing.
2000  if (is_clang && (!is_nacl || is_nacl_saigo)) {
2001    cflags = [ "-Wshadow" ]
2002  }
2003}
2004
2005# rtti ------------------------------------------------------------------------
2006#
2007# Allows turning Run-Time Type Identification on or off.
2008
2009config("rtti") {
2010  if (is_win) {
2011    cflags_cc = [ "/GR" ]
2012  } else {
2013    cflags_cc = [ "-frtti" ]
2014  }
2015}
2016
2017config("no_rtti") {
2018  # Some sanitizer configs may require RTTI to be left enabled globally
2019  if (!use_rtti) {
2020    if (is_win) {
2021      cflags_cc = [ "/GR-" ]
2022    } else {
2023      cflags_cc = [ "-fno-rtti" ]
2024      cflags_objcc = cflags_cc
2025    }
2026  }
2027}
2028
2029# export_dynamic ---------------------------------------------------------------
2030#
2031# Ensures all exported symbols are added to the dynamic symbol table.  This is
2032# necessary to expose Chrome's custom operator new() and operator delete() (and
2033# other memory-related symbols) to libraries.  Otherwise, they might
2034# (de)allocate memory on a different heap, which would spell trouble if pointers
2035# to heap-allocated memory are passed over shared library boundaries.
2036config("export_dynamic") {
2037  # TODO(crbug.com/1052397): Revisit after target_os flip is completed.
2038  if (is_linux || is_chromeos_lacros || export_libcxxabi_from_executables) {
2039    ldflags = [ "-rdynamic" ]
2040  }
2041}
2042
2043# thin_archive -----------------------------------------------------------------
2044#
2045# Enables thin archives on posix, and on windows when the lld linker is used.
2046# Regular archives directly include the object files used to generate it.
2047# Thin archives merely reference the object files.
2048# This makes building them faster since it requires less disk IO, but is
2049# inappropriate if you wish to redistribute your static library.
2050# This config is added to the global config, so thin archives should already be
2051# enabled.  If you want to make a distributable static library, you need to do 2
2052# things:
2053# 1. Set complete_static_lib so that all dependencies of the library make it
2054#    into the library. See `gn help complete_static_lib` for details.
2055# 2. Remove the thin_archive config, so that the .a file actually contains all
2056#    .o files, instead of just references to .o files in the build directoy
2057config("thin_archive") {
2058  # The macOS and iOS default linker ld64 does not support reading thin
2059  # archives.
2060  # TODO(crbug.com/1221615): Enable on is_apple if use_lld once that no longer
2061  # confuses lldb.
2062  if ((is_posix && !is_nacl && !is_apple) || is_fuchsia) {
2063    arflags = [ "-T" ]
2064  } else if (is_win && use_lld) {
2065    arflags = [ "/llvmlibthin" ]
2066  }
2067}
2068
2069# exceptions -------------------------------------------------------------------
2070#
2071# Allows turning Exceptions on or off.
2072# Note: exceptions are disallowed in Google code.
2073
2074config("exceptions") {
2075  if (is_win) {
2076    # Enables exceptions in the STL.
2077    if (!use_custom_libcxx) {
2078      defines = [ "_HAS_EXCEPTIONS=1" ]
2079    }
2080    cflags_cc = [ "/EHsc" ]
2081  } else {
2082    cflags_cc = [ "-fexceptions" ]
2083    cflags_objcc = cflags_cc
2084  }
2085}
2086
2087config("no_exceptions") {
2088  if (is_win) {
2089    # Disables exceptions in the STL.
2090    # libc++ uses the __has_feature macro to control whether to use exceptions,
2091    # so defining this macro is unnecessary. Defining _HAS_EXCEPTIONS to 0 also
2092    # breaks libc++ because it depends on MSVC headers that only provide certain
2093    # declarations if _HAS_EXCEPTIONS is 1. Those MSVC headers do not use
2094    # exceptions, despite being conditional on _HAS_EXCEPTIONS.
2095    if (!use_custom_libcxx) {
2096      defines = [ "_HAS_EXCEPTIONS=0" ]
2097    }
2098  } else {
2099    cflags_cc = [ "-fno-exceptions" ]
2100    cflags_objcc = cflags_cc
2101  }
2102}
2103
2104# Warnings ---------------------------------------------------------------------
2105
2106# Generate a warning for code that might emit a static initializer.
2107# See: //docs/static_initializers.md
2108# See: https://groups.google.com/a/chromium.org/d/topic/chromium-dev/B9Q5KTD7iCo/discussion
2109config("wglobal_constructors") {
2110  if (is_clang) {
2111    cflags = [ "-Wglobal-constructors" ]
2112  }
2113}
2114
2115# This will generate warnings when using Clang if code generates exit-time
2116# destructors, which will slow down closing the program.
2117# TODO(thakis): Make this a blocklist instead, http://crbug.com/101600
2118config("wexit_time_destructors") {
2119  if (is_clang) {
2120    cflags = [ "-Wexit-time-destructors" ]
2121  }
2122}
2123
2124# Some code presumes that pointers to structures/objects are compatible
2125# regardless of whether what they point to is already known to be valid.
2126# gcc 4.9 and earlier had no way of suppressing this warning without
2127# suppressing the rest of them.  Here we centralize the identification of
2128# the gcc 4.9 toolchains.
2129config("no_incompatible_pointer_warnings") {
2130  cflags = []
2131  if (is_clang) {
2132    cflags += [ "-Wno-incompatible-pointer-types" ]
2133  } else if (current_cpu == "mipsel" || current_cpu == "mips64el") {
2134    cflags += [ "-w" ]
2135  } else if (is_chromeos_ash && current_cpu == "arm") {
2136    cflags += [ "-w" ]
2137  }
2138}
2139
2140# Optimization -----------------------------------------------------------------
2141#
2142# The BUILDCONFIG file sets the "default_optimization" config on targets by
2143# default. It will be equivalent to either "optimize" (release) or
2144# "no_optimize" (debug) optimization configs.
2145#
2146# You can override the optimization level on a per-target basis by removing the
2147# default config and then adding the named one you want:
2148#
2149#   configs -= [ "//build/config/compiler:default_optimization" ]
2150#   configs += [ "//build/config/compiler:optimize_max" ]
2151
2152# Shared settings for both "optimize" and "optimize_max" configs.
2153# IMPORTANT: On Windows "/O1" and "/O2" must go before the common flags.
2154if (is_win) {
2155  common_optimize_on_cflags = [
2156    "/Ob2",  # Both explicit and auto inlining.
2157    "/Oy-",  # Disable omitting frame pointers, must be after /O2.
2158    "/Zc:inline",  # Remove unreferenced COMDAT (faster links).
2159  ]
2160  if (!is_asan) {
2161    common_optimize_on_cflags += [
2162      # Put data in separate COMDATs. This allows the linker
2163      # to put bit-identical constants at the same address even if
2164      # they're unrelated constants, which saves binary size.
2165      # This optimization can't be used when ASan is enabled because
2166      # it is not compatible with the ASan ODR checker.
2167      "/Gw",
2168    ]
2169  }
2170  common_optimize_on_ldflags = []
2171
2172  # /OPT:ICF is not desirable in Debug builds, since code-folding can result in
2173  # misleading symbols in stack traces.
2174  if (!is_debug && !is_component_build) {
2175    common_optimize_on_ldflags += [ "/OPT:ICF" ]  # Redundant COMDAT folding.
2176  }
2177
2178  if (is_official_build) {
2179    common_optimize_on_ldflags += [ "/OPT:REF" ]  # Remove unreferenced data.
2180    # TODO(thakis): Add LTO/PGO clang flags eventually, https://crbug.com/598772
2181  }
2182} else {
2183  common_optimize_on_cflags = []
2184  common_optimize_on_ldflags = []
2185
2186  if (is_android) {
2187    # TODO(jdduke) Re-enable on mips after resolving linking
2188    # issues with libc++ (crbug.com/456380).
2189    if (current_cpu != "mipsel" && current_cpu != "mips64el") {
2190      common_optimize_on_ldflags += [
2191        # Warn in case of text relocations.
2192        "-Wl,--warn-shared-textrel",
2193      ]
2194    }
2195  }
2196
2197  if (is_apple) {
2198    common_optimize_on_ldflags += [ "-Wl,-dead_strip" ]
2199
2200    if (is_official_build) {
2201      common_optimize_on_ldflags += [
2202        "-Wl,-no_data_in_code_info",
2203        "-Wl,-no_function_starts",
2204      ]
2205    }
2206  } else if (current_os != "aix" && current_os != "zos") {
2207    # Non-Mac Posix flags.
2208    # Aix does not support these.
2209
2210    common_optimize_on_cflags += [
2211      # Put data and code in their own sections, so that unused symbols
2212      # can be removed at link time with --gc-sections.
2213      "-fdata-sections",
2214      "-ffunction-sections",
2215    ]
2216    if ((!is_nacl || is_nacl_saigo) && is_clang) {
2217      # We don't care about unique section names, this makes object files a bit
2218      # smaller.
2219      common_optimize_on_cflags += [ "-fno-unique-section-names" ]
2220    }
2221
2222    common_optimize_on_ldflags += [
2223      # Specifically tell the linker to perform optimizations.
2224      # See http://lwn.net/Articles/192624/ .
2225      # -O2 enables string tail merge optimization in gold and lld.
2226      "-Wl,-O2",
2227      "-Wl,--gc-sections",
2228    ]
2229  }
2230}
2231
2232config("default_stack_frames") {
2233  if (!is_win) {
2234    if (enable_frame_pointers) {
2235      cflags = [ "-fno-omit-frame-pointer" ]
2236
2237      # Omit frame pointers for leaf functions on x86, otherwise building libyuv
2238      # gives clang's register allocator issues, see llvm.org/PR15798 /
2239      # crbug.com/233709
2240      if (is_clang && current_cpu == "x86" && !is_apple) {
2241        cflags += [ "-momit-leaf-frame-pointer" ]
2242      }
2243    } else {
2244      cflags = [ "-fomit-frame-pointer" ]
2245    }
2246  }
2247  # On Windows, the flag to enable framepointers "/Oy-" must always come after
2248  # the optimization flag [e.g. "/O2"]. The optimization flag is set by one of
2249  # the "optimize" configs, see rest of this file. The ordering that cflags are
2250  # applied is well-defined by the GN spec, and there is no way to ensure that
2251  # cflags set by "default_stack_frames" is applied after those set by an
2252  # "optimize" config. Similarly, there is no way to propagate state from this
2253  # config into the "optimize" config. We always apply the "/Oy-" config in the
2254  # definition for common_optimize_on_cflags definition, even though this may
2255  # not be correct.
2256}
2257
2258# Default "optimization on" config.
2259config("optimize") {
2260  if (is_win) {
2261    if (chrome_pgo_phase != 2) {
2262      # Favor size over speed, /O1 must be before the common flags.
2263      # /O1 implies /Os and /GF.
2264      cflags = [ "/O1" ] + common_optimize_on_cflags + [ "/Oi" ]
2265      rustflags = [ "-Copt-level=s" ]
2266    } else {
2267      # PGO requires all translation units to be compiled with /O2. The actual
2268      # optimization level will be decided based on the profiling data.
2269      cflags = [ "/O2" ] + common_optimize_on_cflags + [ "/Oi" ]
2270
2271      # https://doc.rust-lang.org/rustc/profile-guided-optimization.html#usage
2272      # suggests not using an explicit `-Copt-level` at all, and the default is
2273      # to optimize for performance like `/O2` for clang.
2274      rustflags = []
2275    }
2276  } else if (optimize_for_size) {
2277    # Favor size over speed.
2278    if (is_clang) {
2279      cflags = [ "-Oz" ] + common_optimize_on_cflags
2280
2281      if (use_ml_inliner && is_a_target_toolchain) {
2282        cflags += [
2283          "-mllvm",
2284          "-enable-ml-inliner=release",
2285        ]
2286      }
2287    } else {
2288      cflags = [ "-Os" ] + common_optimize_on_cflags
2289    }
2290
2291    # Like with `-Oz` on Clang, `-Copt-level=z` will also turn off loop
2292    # vectorization.
2293    rustflags = [ "-Copt-level=z" ]
2294  } else if (is_chromeos) {
2295    # TODO(gbiv): This is partially favoring size over speed. CrOS exclusively
2296    # uses clang, and -Os in clang is more of a size-conscious -O2 than "size at
2297    # any cost" (AKA -Oz). It'd be nice to:
2298    # - Make `optimize_for_size` apply to all platforms where we're optimizing
2299    #   for size by default (so, also Windows)
2300    # - Investigate -Oz here, maybe just for ARM?
2301    cflags = [ "-Os" ] + common_optimize_on_cflags
2302
2303    # Similar to clang, we optimize with `-Copt-level=s` to keep loop
2304    # vectorization while otherwise optimizing for size.
2305    rustflags = [ "-Copt-level=s" ]
2306  } else {
2307    cflags = [ "-O2" ] + common_optimize_on_cflags
2308
2309    # The `-O3` for clang turns on extra optimizations compared to the standard
2310    # `-O2`. But for rust, `-Copt-level=3` is the default and is thus reliable
2311    # to use.
2312    rustflags = [ "-Copt-level=3" ]
2313  }
2314  ldflags = common_optimize_on_ldflags
2315}
2316
2317# Turn off optimizations.
2318config("no_optimize") {
2319  if (is_win) {
2320    cflags = [
2321      "/Od",  # Disable optimization.
2322      "/Ob0",  # Disable all inlining (on by default).
2323      "/GF",  # Enable string pooling (off by default).
2324    ]
2325
2326    if (target_cpu == "arm64") {
2327      # Disable omitting frame pointers for no_optimize build because stack
2328      # traces on Windows ARM64 rely on it.
2329      cflags += [ "/Oy-" ]
2330    }
2331  } else if (is_android && !android_full_debug) {
2332    # On Android we kind of optimize some things that don't affect debugging
2333    # much even when optimization is disabled to get the binary size down.
2334    if (is_clang) {
2335      cflags = [ "-Oz" ] + common_optimize_on_cflags
2336    } else {
2337      cflags = [ "-Os" ] + common_optimize_on_cflags
2338    }
2339
2340    if (!is_component_build) {
2341      # Required for library partitions. Without this all symbols just end up
2342      # in the base partition.
2343      ldflags = [ "-Wl,--gc-sections" ]
2344    }
2345  } else if (is_fuchsia) {
2346    # On Fuchsia, we optimize for size here to reduce the size of debug build
2347    # packages so they can be run in a KVM. See crbug.com/910243 for details.
2348    cflags = [ "-Og" ]
2349  } else {
2350    cflags = [ "-O0" ]
2351    ldflags = []
2352  }
2353}
2354
2355# Turns up the optimization level. On Windows, this implies whole program
2356# optimization and link-time code generation which is very expensive and should
2357# be used sparingly.
2358config("optimize_max") {
2359  if (is_nacl && is_nacl_irt) {
2360    # The NaCl IRT is a special case and always wants its own config.
2361    # Various components do:
2362    #   if (!is_debug) {
2363    #     configs -= [ "//build/config/compiler:default_optimization" ]
2364    #     configs += [ "//build/config/compiler:optimize_max" ]
2365    #   }
2366    # So this config has to have the selection logic just like
2367    # "default_optimization", below.
2368    configs = [ "//build/config/nacl:irt_optimize" ]
2369  } else {
2370    ldflags = common_optimize_on_ldflags
2371    if (is_win) {
2372      # Favor speed over size, /O2 must be before the common flags.
2373      # /O2 implies /Ot, /Oi, and /GF.
2374      cflags = [ "/O2" ] + common_optimize_on_cflags
2375    } else if (optimize_for_fuzzing) {
2376      cflags = [ "-O1" ] + common_optimize_on_cflags
2377    } else {
2378      cflags = [ "-O2" ] + common_optimize_on_cflags
2379    }
2380    rustflags = [ "-Copt-level=3" ]
2381  }
2382}
2383
2384# This config can be used to override the default settings for per-component
2385# and whole-program optimization, optimizing the particular target for speed
2386# instead of code size. This config is exactly the same as "optimize_max"
2387# except that we use -O3 instead of -O2 on non-win, non-IRT platforms.
2388#
2389# TODO(crbug.com/621335) - rework how all of these configs are related
2390# so that we don't need this disclaimer.
2391config("optimize_speed") {
2392  if (is_nacl && is_nacl_irt) {
2393    # The NaCl IRT is a special case and always wants its own config.
2394    # Various components do:
2395    #   if (!is_debug) {
2396    #     configs -= [ "//build/config/compiler:default_optimization" ]
2397    #     configs += [ "//build/config/compiler:optimize_max" ]
2398    #   }
2399    # So this config has to have the selection logic just like
2400    # "default_optimization", below.
2401    configs = [ "//build/config/nacl:irt_optimize" ]
2402  } else {
2403    ldflags = common_optimize_on_ldflags
2404    if (is_win) {
2405      # Favor speed over size, /O2 must be before the common flags.
2406      # /O2 implies /Ot, /Oi, and /GF.
2407      cflags = [ "/O2" ] + common_optimize_on_cflags
2408    } else if (optimize_for_fuzzing) {
2409      cflags = [ "-O1" ] + common_optimize_on_cflags
2410    } else {
2411      cflags = [ "-O3" ] + common_optimize_on_cflags
2412    }
2413    rustflags = [ "-Copt-level=3" ]
2414  }
2415}
2416
2417config("optimize_fuzzing") {
2418  cflags = [ "-O1" ] + common_optimize_on_cflags
2419  rustflags = [ "-Copt-level=1" ]
2420  ldflags = common_optimize_on_ldflags
2421  visibility = [ ":default_optimization" ]
2422}
2423
2424# The default optimization applied to all targets. This will be equivalent to
2425# either "optimize" or "no_optimize", depending on the build flags.
2426config("default_optimization") {
2427  if (is_nacl && is_nacl_irt) {
2428    # The NaCl IRT is a special case and always wants its own config.
2429    # It gets optimized the same way regardless of the type of build.
2430    configs = [ "//build/config/nacl:irt_optimize" ]
2431  } else if (is_debug) {
2432    configs = [ ":no_optimize" ]
2433  } else if (optimize_for_fuzzing) {
2434    assert(!is_win, "Fuzzing optimize level not supported on Windows")
2435
2436    # Coverage build is quite slow. Using "optimize_for_fuzzing" makes it even
2437    # slower as it uses "-O1" instead of "-O3". Prevent that from happening.
2438    assert(!use_clang_coverage,
2439           "optimize_for_fuzzing=true should not be used with " +
2440               "use_clang_coverage=true.")
2441    configs = [ ":optimize_fuzzing" ]
2442  } else {
2443    configs = [ ":optimize" ]
2444  }
2445}
2446
2447_clang_sample_profile = ""
2448if (is_clang && is_a_target_toolchain) {
2449  if (clang_sample_profile_path != "") {
2450    _clang_sample_profile = clang_sample_profile_path
2451  } else if (clang_use_default_sample_profile) {
2452    assert(build_with_chromium,
2453           "Our default profiles currently only apply to Chromium")
2454    assert(is_android || is_chromeos || is_castos,
2455           "The current platform has no default profile")
2456    if (is_android || is_castos) {
2457      _clang_sample_profile = "//chrome/android/profiles/afdo.prof"
2458    } else {
2459      assert(
2460          chromeos_afdo_platform == "atom" ||
2461              chromeos_afdo_platform == "bigcore" ||
2462              chromeos_afdo_platform == "arm" ||
2463              chromeos_afdo_platform == "arm-exp",
2464          "Only 'atom', 'bigcore', 'arm' and 'arm-exp' are valid ChromeOS profiles.")
2465      _clang_sample_profile =
2466          "//chromeos/profiles/${chromeos_afdo_platform}.afdo.prof"
2467    }
2468  }
2469}
2470
2471# Clang offers a way to assert that AFDO profiles are accurate, which causes it
2472# to optimize functions not represented in a profile more aggressively for size.
2473# This config can be toggled in cases where shaving off binary size hurts
2474# performance too much.
2475config("afdo_optimize_size") {
2476  if (_clang_sample_profile != "" && sample_profile_is_accurate) {
2477    cflags = [ "-fprofile-sample-accurate" ]
2478  }
2479}
2480
2481# GCC and clang support a form of profile-guided optimization called AFDO.
2482# There are some targeted places that AFDO regresses, so we provide a separate
2483# config to allow AFDO to be disabled per-target.
2484config("afdo") {
2485  if (is_clang) {
2486    cflags = []
2487    if (clang_emit_debug_info_for_profiling) {
2488      # Add the following flags to generate debug info for profiling.
2489      cflags += [ "-gline-tables-only" ]
2490      if (!is_nacl) {
2491        cflags += [ "-fdebug-info-for-profiling" ]
2492      }
2493    }
2494    if (_clang_sample_profile != "") {
2495      assert(chrome_pgo_phase == 0, "AFDO can't be used in PGO builds")
2496      rebased_clang_sample_profile =
2497          rebase_path(_clang_sample_profile, root_build_dir)
2498      cflags += [ "-fprofile-sample-use=${rebased_clang_sample_profile}" ]
2499      if (use_profi) {
2500        cflags += [ "-fsample-profile-use-profi" ]
2501      }
2502
2503      # crbug.com/1459429: ARM builds see failures due to -Wbackend-plugin.
2504      # These seem to be false positives - the complaints are about functions
2505      # marked with `__nodebug__` not having associated debuginfo. In the case
2506      # where this was observed, the `__nodebug__` function was also marked
2507      # `__always_inline__` and had no branches, so AFDO info is likely useless
2508      # there.
2509      cflags += [ "-Wno-backend-plugin" ]
2510      inputs = [ _clang_sample_profile ]
2511    }
2512  } else if (auto_profile_path != "" && is_a_target_toolchain) {
2513    cflags = [ "-fauto-profile=${auto_profile_path}" ]
2514    inputs = [ auto_profile_path ]
2515  }
2516}
2517
2518# Symbols ----------------------------------------------------------------------
2519
2520# The BUILDCONFIG file sets the "default_symbols" config on targets by
2521# default. It will be equivalent to one the three specific symbol levels.
2522#
2523# You can override the symbol level on a per-target basis by removing the
2524# default config and then adding the named one you want:
2525#
2526#   configs -= [ "//build/config/compiler:default_symbols" ]
2527#   configs += [ "//build/config/compiler:symbols" ]
2528
2529# A helper config that all configs passing /DEBUG to the linker should
2530# include as sub-config.
2531config("win_pdbaltpath") {
2532  visibility = [
2533    ":minimal_symbols",
2534    ":symbols",
2535  ]
2536
2537  # /DEBUG causes the linker to generate a pdb file, and to write the absolute
2538  # path to it in the executable file it generates.  This flag turns that
2539  # absolute path into just the basename of the pdb file, which helps with
2540  # build reproducibility. Debuggers look for pdb files next to executables,
2541  # so there's minimal downside to always using this. However, post-mortem
2542  # debugging of Chromium crash dumps and ETW tracing can be complicated by this
2543  # switch so an option to omit it is important.
2544  if (!use_full_pdb_paths) {
2545    ldflags = [ "/pdbaltpath:%_PDB%" ]
2546  }
2547}
2548
2549# Full symbols.
2550config("symbols") {
2551  rustflags = []
2552  if (is_win) {
2553    if (is_clang) {
2554      cflags = [
2555        # Debug information in the .obj files.
2556        "/Z7",
2557
2558        # Disable putting the compiler command line into the debug info to
2559        # prevent some types of non-determinism.
2560        "-gno-codeview-command-line",
2561      ]
2562    } else {
2563      cflags = [ "/Zi" ]  # Produce PDB file, no edit and continue.
2564    }
2565
2566    if (is_clang && use_lld && use_ghash) {
2567      cflags += [ "-gcodeview-ghash" ]
2568      ldflags = [ "/DEBUG:GHASH" ]
2569    } else {
2570      ldflags = [ "/DEBUG" ]
2571    }
2572
2573    # All configs using /DEBUG should include this:
2574    configs = [ ":win_pdbaltpath" ]
2575  } else {
2576    cflags = []
2577    if (is_mac && enable_dsyms) {
2578      # If generating dSYMs, specify -fno-standalone-debug. This was
2579      # originally specified for https://crbug.com/479841 because dsymutil
2580      # could not handle a 4GB dSYM file. But dsymutil from Xcodes prior to
2581      # version 7 also produces debug data that is incompatible with Breakpad
2582      # dump_syms, so this is still required (https://crbug.com/622406).
2583      cflags += [ "-fno-standalone-debug" ]
2584    }
2585
2586    # On aix -gdwarf causes linker failures due to thread_local variables.
2587    if (!is_nacl && current_os != "aix") {
2588      if (use_dwarf5) {
2589        cflags += [ "-gdwarf-5" ]
2590        rustflags += [ "-Zdwarf-version=5" ]
2591      } else {
2592        # Recent clang versions default to DWARF5 on Linux, and Android is about
2593        # to switch. TODO: Adopt that in controlled way. For now, keep DWARF4.
2594        # Apple platforms still default to 4 in clang, so they don't need the
2595        # cflags.
2596        if (!is_apple) {
2597          cflags += [ "-gdwarf-4" ]
2598        }
2599
2600        # On Apple, rustc defaults to DWARF2 so it needs to be told how to
2601        # match clang.
2602        rustflags += [ "-Zdwarf-version=4" ]
2603      }
2604    }
2605
2606    # The gcc-based nacl compilers don't support -fdebug-compilation-dir (see
2607    # elsewhere in this file), so they can't have build-dir-independent output.
2608    # Moreover pnacl does not support newer flags such as -fdebug-prefix-map
2609    # Disable symbols for nacl object files to get deterministic,
2610    # build-directory-independent output.
2611    # Keeping -g2 for saigo as it's the only toolchain whose artifacts that are
2612    # part of chromium release (other nacl toolchains are used only for tests).
2613    if ((!is_nacl || is_nacl_saigo) && current_os != "zos") {
2614      cflags += [ "-g2" ]
2615    }
2616
2617    if (!is_nacl && is_clang && !is_tsan && !is_asan) {
2618      # gcc generates dwarf-aranges by default on -g1 and -g2. On clang it has
2619      # to be manually enabled.
2620      #
2621      # It is skipped in tsan and asan because enabling it causes some
2622      # formatting changes in the output which would require fixing bunches
2623      # of expectation regexps.
2624      cflags += [ "-gdwarf-aranges" ]
2625    }
2626
2627    if (is_apple) {
2628      swiftflags = [ "-g" ]
2629    }
2630
2631    if (use_debug_fission) {
2632      cflags += [ "-gsplit-dwarf" ]
2633    }
2634    asmflags = cflags
2635    ldflags = []
2636
2637    # Split debug info with all thinlto builds except nacl and apple.
2638    # thinlto requires -gsplit-dwarf in ldflags.
2639    if (use_debug_fission && use_thin_lto && !is_nacl && !is_apple) {
2640      ldflags += [ "-gsplit-dwarf" ]
2641    }
2642
2643    # TODO(thakis): Figure out if there's a way to make this go for 32-bit,
2644    # currently we get "warning:
2645    # obj/native_client/src/trusted/service_runtime/sel_asm/nacl_switch_32.o:
2646    # DWARF info may be corrupt; offsets in a range list entry are in different
2647    # sections" there.  Maybe just a bug in nacl_switch_32.S.
2648    _enable_gdb_index =
2649        symbol_level == 2 && !is_apple && !is_nacl && current_cpu != "x86" &&
2650        current_os != "zos" && (use_gold || use_lld) &&
2651        # Disable on non-fission 32-bit Android because it pushes
2652        # libcomponents_unittests over the 4gb size limit.
2653        !(is_android && !use_debug_fission && current_cpu != "x64" &&
2654          current_cpu != "arm64")
2655    if (_enable_gdb_index) {
2656      if (is_clang) {
2657        # This flag enables the GNU-format pubnames and pubtypes sections,
2658        # which lld needs in order to generate a correct GDB index.
2659        # TODO(pcc): Try to make lld understand non-GNU-format pubnames
2660        # sections (llvm.org/PR34820).
2661        cflags += [ "-ggnu-pubnames" ]
2662      }
2663      ldflags += [ "-Wl,--gdb-index" ]
2664    }
2665  }
2666
2667  configs = []
2668
2669  # Compress debug on 32-bit ARM to stay under 4GB for ChromeOS
2670  # https://b/243982712.
2671  if (symbol_level == 2 && is_chromeos_device && !use_debug_fission &&
2672      !is_nacl && current_cpu == "arm") {
2673    configs += [ "//build/config:compress_debug_sections" ]
2674  }
2675
2676  if (is_clang && (!is_nacl || is_nacl_saigo) && current_os != "zos") {
2677    if (is_apple) {
2678      # TODO(https://crbug.com/1050118): Investigate missing debug info on mac.
2679      # Make sure we don't use constructor homing on mac.
2680      cflags += [
2681        "-Xclang",
2682        "-debug-info-kind=limited",
2683      ]
2684    } else {
2685      # Use constructor homing for debug info. This option reduces debug info
2686      # by emitting class type info only when constructors are emitted.
2687      cflags += [
2688        "-Xclang",
2689        "-fuse-ctor-homing",
2690      ]
2691    }
2692  }
2693  rustflags += [ "-g" ]
2694}
2695
2696# Minimal symbols.
2697# This config guarantees to hold symbol for stack trace which are shown to user
2698# when crash happens in unittests running on buildbot.
2699config("minimal_symbols") {
2700  rustflags = []
2701  if (is_win) {
2702    # Functions, files, and line tables only.
2703    cflags = []
2704
2705    if (is_clang) {
2706      cflags += [
2707        # Disable putting the compiler command line into the debug info to
2708        # prevent some types of non-determinism.
2709        "-gno-codeview-command-line",
2710      ]
2711    }
2712    if (is_clang && use_lld && use_ghash) {
2713      cflags += [ "-gcodeview-ghash" ]
2714      ldflags = [ "/DEBUG:GHASH" ]
2715    } else {
2716      ldflags = [ "/DEBUG" ]
2717    }
2718
2719    # All configs using /DEBUG should include this:
2720    configs = [ ":win_pdbaltpath" ]
2721
2722    # Enable line tables for clang. MSVC doesn't have an equivalent option.
2723    if (is_clang) {
2724      # -gline-tables-only is the same as -g1, but clang-cl only exposes the
2725      # former.
2726      cflags += [ "-gline-tables-only" ]
2727    }
2728  } else {
2729    cflags = []
2730    if (is_mac && !use_dwarf5) {
2731      # clang defaults to DWARF2 on macOS unless mac_deployment_target is
2732      # at least 10.11.
2733      # TODO(thakis): Remove this once mac_deployment_target is 10.11.
2734      cflags += [ "-gdwarf-4" ]
2735      rustflags += [ "-Zdwarf-version=4" ]
2736    } else if (!use_dwarf5 && !is_nacl && current_os != "aix") {
2737      # On aix -gdwarf causes linker failures due to thread_local variables.
2738      # Recent clang versions default to DWARF5 on Linux, and Android is about
2739      # to switch. TODO: Adopt that in controlled way.
2740      cflags += [ "-gdwarf-4" ]
2741      rustflags += [ "-Zdwarf-version=4" ]
2742    }
2743
2744    if (use_dwarf5 && !is_nacl) {
2745      cflags += [ "-gdwarf-5" ]
2746      rustflags += [ "-Zdwarf-version=5" ]
2747    }
2748
2749    # The gcc-based nacl compilers don't support -fdebug-compilation-dir (see
2750    # elsewhere in this file), so they can't have build-dir-independent output.
2751    # Moreover pnacl does not support newer flags such as -fdebug-prefix-map
2752    # Disable symbols for nacl object files to get deterministic,
2753    # build-directory-independent output.
2754    # Keeping -g1 for saigo as it's the only toolchain whose artifacts that are
2755    # part of chromium release (other nacl toolchains are used only for tests).
2756    if (!is_nacl || is_nacl_saigo) {
2757      cflags += [ "-g1" ]
2758    }
2759
2760    if (!is_nacl && is_clang && !is_tsan && !is_asan) {
2761      # See comment for -gdwarf-aranges in config("symbols").
2762      cflags += [ "-gdwarf-aranges" ]
2763    }
2764
2765    ldflags = []
2766    if (is_android && is_clang) {
2767      # Android defaults to symbol_level=1 builds, but clang, unlike gcc,
2768      # doesn't emit DW_AT_linkage_name in -g1 builds.
2769      # -fdebug-info-for-profiling enables that (and a bunch of other things we
2770      # don't need), so that we get qualified names in stacks.
2771      # TODO(thakis): Consider making clang emit DW_AT_linkage_name in -g1 mode;
2772      #               failing that consider doing this on non-Android too.
2773      cflags += [ "-fdebug-info-for-profiling" ]
2774    }
2775
2776    asmflags = cflags
2777  }
2778  rustflags += [ "-Cdebuginfo=1" ]
2779}
2780
2781# This configuration contains function names only. That is, the compiler is
2782# told to not generate debug information and the linker then just puts function
2783# names in the final debug information.
2784config("no_symbols") {
2785  if (is_win) {
2786    ldflags = [ "/DEBUG" ]
2787
2788    # All configs using /DEBUG should include this:
2789    configs = [ ":win_pdbaltpath" ]
2790  } else {
2791    cflags = [ "-g0" ]
2792    asmflags = cflags
2793  }
2794}
2795
2796# Default symbols.
2797config("default_symbols") {
2798  if (symbol_level == 0) {
2799    configs = [ ":no_symbols" ]
2800  } else if (symbol_level == 1) {
2801    configs = [ ":minimal_symbols" ]
2802  } else if (symbol_level == 2) {
2803    configs = [ ":symbols" ]
2804  } else {
2805    assert(false)
2806  }
2807
2808  # This config is removed by base unittests apk.
2809  if (is_android && is_clang && strip_debug_info) {
2810    configs += [ ":strip_debug" ]
2811  }
2812}
2813
2814config("strip_debug") {
2815  if (!defined(ldflags)) {
2816    ldflags = []
2817  }
2818  ldflags += [ "-Wl,--strip-debug" ]
2819}
2820
2821if (is_apple) {
2822  # On macOS and iOS, this enables support for ARC (automatic reference
2823  # counting). See http://clang.llvm.org/docs/AutomaticReferenceCounting.html.
2824  #
2825  # -fobjc-arc enables ARC overall.
2826  #
2827  # ARC does not add exception handlers to pure Objective-C code, but does add
2828  # them to Objective-C++ code with the rationale that C++ pervasively adds them
2829  # in for exception safety. However, exceptions are banned in Chromium code for
2830  # C++ and exceptions in Objective-C code are intended to be fatal, so
2831  # -fno-objc-arc-exceptions is specified to disable these unwanted exception
2832  # handlers.
2833  config("enable_arc") {
2834    common_flags = [
2835      "-fobjc-arc",
2836      "-fno-objc-arc-exceptions",
2837    ]
2838    cflags_objc = common_flags
2839    cflags_objcc = common_flags
2840  }
2841}
2842
2843if (is_android) {
2844  # Use orderfile for linking Chrome on Android.
2845  # This config enables using an orderfile for linking in LLD.
2846  config("chrome_orderfile_config") {
2847    # Don't try to use an orderfile with call graph sorting, except on Android,
2848    # where we care about memory used by code, so we still want to mandate
2849    # ordering.
2850    if (chrome_orderfile_path != "") {
2851      assert(use_lld)
2852      _rebased_orderfile = rebase_path(chrome_orderfile_path, root_build_dir)
2853      ldflags = [
2854        "-Wl,--symbol-ordering-file",
2855        "-Wl,$_rebased_orderfile",
2856        "-Wl,--no-warn-symbol-ordering",
2857      ]
2858      inputs = [ chrome_orderfile_path ]
2859    }
2860  }
2861}
2862
2863# Initialize all variables on the stack if needed.
2864config("default_init_stack_vars") {
2865  cflags = []
2866  if (init_stack_vars && is_clang && !is_nacl && !using_sanitizer) {
2867    if (init_stack_vars_zero) {
2868      cflags += [ "-ftrivial-auto-var-init=zero" ]
2869    } else {
2870      cflags += [ "-ftrivial-auto-var-init=pattern" ]
2871    }
2872  }
2873}
2874
2875buildflag_header("compiler_buildflags") {
2876  header = "compiler_buildflags.h"
2877
2878  flags = [
2879    "CLANG_PGO=$chrome_pgo_phase",
2880    "SYMBOL_LEVEL=$symbol_level",
2881  ]
2882}
2883
2884config("cet_shadow_stack") {
2885  if (enable_cet_shadow_stack && is_win) {
2886    assert(target_cpu == "x64")
2887    ldflags = [ "/CETCOMPAT" ]
2888  }
2889}
2890