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