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