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