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