tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BUILD.gn (113990B)


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