1# Copyright 2013 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import("//build/config/c++/c++.gni") 6import("//build/config/chrome_build.gni") 7import("//build/config/clang/clang.gni") 8import("//build/config/compiler/compiler.gni") 9import("//build/config/rust.gni") 10import("//build/config/sanitizers/sanitizers.gni") 11import("//build/config/win/control_flow_guard.gni") 12import("//build/config/win/visual_studio_version.gni") 13import("//build/timestamp.gni") 14import("//build/toolchain/goma.gni") 15import("//build/toolchain/rbe.gni") 16import("//build/toolchain/toolchain.gni") 17 18assert(is_win) 19 20declare_args() { 21 # Turn this on to have the linker output extra timing information. 22 win_linker_timing = false 23 24 # possible values for target_winuwp_version: 25 # "10" - Windows UWP 10 26 # "8.1" - Windows RT 8.1 27 # "8.0" - Windows RT 8.0 28 target_winuwp_version = "10" 29 30 # possible values: 31 # "app" - Windows Store Applications 32 # "phone" - Windows Phone Applications 33 # "system" - Windows Drivers and Tools 34 # "server" - Windows Server Applications 35 # "desktop" - Windows Desktop Applications 36 target_winuwp_family = "app" 37 38 # Set this to use clang-style diagnostics format instead of MSVC-style, which 39 # is useful in e.g. Emacs compilation mode. 40 # E.g.: 41 # Without this, clang emits a diagnostic message like this: 42 # foo/bar.cc(12,34): error: something went wrong 43 # and with this switch, clang emits it like this: 44 # foo/bar.cc:12:34: error: something went wrong 45 use_clang_diagnostics_format = false 46} 47 48# This is included by reference in the //build/config/compiler config that 49# is applied to all targets. It is here to separate out the logic that is 50# Windows-only. 51config("compiler") { 52 if (current_cpu == "x86") { 53 asmflags = [ 54 # When /safeseh is specified, the linker will only produce an image if it 55 # can also produce a table of the image's safe exception handlers. This 56 # table specifies for the operating system which exception handlers are 57 # valid for the image. Note that /SAFESEH isn't accepted on the command 58 # line, only /safeseh. This is only accepted by ml.exe, not ml64.exe. 59 "/safeseh", 60 ] 61 } 62 63 cflags = [ 64 "/Gy", # Enable function-level linking. 65 "/FS", # Preserve previous PDB behavior. 66 "/bigobj", # Some of our files are bigger than the regular limits. 67 "/utf-8", # Assume UTF-8 by default to avoid code page dependencies. 68 ] 69 70 if (is_clang) { 71 cflags += [ 72 "/Zc:twoPhase", 73 74 # Consistently use backslash as the path separator when expanding the 75 # __FILE__ macro when targeting Windows regardless of the build 76 # environment. 77 "-ffile-reproducible", 78 ] 79 } 80 81 # Force C/C++ mode for the given GN detected file type. This is necessary 82 # for precompiled headers where the same source file is compiled in both 83 # modes. 84 cflags_c = [ "/TC" ] 85 cflags_cc = [ "/TP" ] 86 87 cflags += [ 88 # Work around crbug.com/526851, bug in VS 2015 RTM compiler. 89 "/Zc:sizedDealloc-", 90 ] 91 92 if (is_clang) { 93 # Required to make the 19041 SDK compatible with clang-cl. 94 # See https://crbug.com/1089996 issue #2 for details. 95 cflags += [ "/D__WRL_ENABLE_FUNCTION_STATICS__" ] 96 97 # Tell clang which version of MSVC to emulate. 98 cflags += [ "-fmsc-version=1934" ] 99 100 if (is_component_build) { 101 cflags += [ 102 # Do not export inline member functions. This makes component builds 103 # faster. This is similar to -fvisibility-inlines-hidden. 104 "/Zc:dllexportInlines-", 105 ] 106 } 107 108 if (current_cpu == "x86") { 109 if (host_cpu == "x86" || host_cpu == "x64") { 110 cflags += [ "-m32" ] 111 } else { 112 cflags += [ "--target=i386-windows" ] 113 } 114 } else if (current_cpu == "x64") { 115 if (host_cpu == "x86" || host_cpu == "x64") { 116 cflags += [ "-m64" ] 117 } else { 118 cflags += [ "--target=x86_64-windows" ] 119 } 120 } else if (current_cpu == "arm64") { 121 cflags += [ "--target=aarch64-pc-windows" ] 122 } else { 123 assert(false, "unknown current_cpu " + current_cpu) 124 } 125 126 # Chrome currently requires SSE3. Clang supports targeting any Intel 127 # microarchitecture. MSVC only supports a subset of architectures, and the 128 # next step after SSE2 will be AVX. 129 if (current_cpu == "x86" || current_cpu == "x64") { 130 cflags += [ "-msse3" ] 131 } 132 133 # Enable ANSI escape codes if something emulating them is around (cmd.exe 134 # doesn't understand ANSI escape codes by default). Make sure to not enable 135 # this if goma/remoteexec is in use, because this will lower cache hits. 136 if (!use_goma && !use_remoteexec && 137 exec_script("//build/win/use_ansi_codes.py", [], "trim string") == 138 "True") { 139 cflags += [ "-fansi-escape-codes" ] 140 } 141 142 if (use_clang_diagnostics_format) { 143 cflags += [ "/clang:-fdiagnostics-format=clang" ] 144 } 145 } 146 147 # Disabled with cc_wrapper because of https://github.com/mozilla/sccache/issues/264 148 if (use_lld && !use_thin_lto && (is_clang || !use_goma) && cc_wrapper == "") { 149 # /Brepro lets the compiler not write the mtime field in the .obj output. 150 # link.exe /incremental relies on this field to work correctly, but lld 151 # never looks at this timestamp, so it's safe to pass this flag with 152 # lld and get more deterministic compiler output in return. 153 # In LTO builds, the compiler doesn't write .obj files containing mtimes, 154 # so /Brepro is ignored there. 155 cflags += [ "/Brepro" ] 156 } 157 158 ldflags = [] 159 160 if (use_lld) { 161 # lld defaults to writing the current time in the pe/coff header. 162 # For build reproducibility, pass an explicit timestamp. See 163 # build/compute_build_timestamp.py for how the timestamp is chosen. 164 # (link.exe also writes the current time, but it doesn't have a flag to 165 # override that behavior.) 166 ldflags += [ "/TIMESTAMP:" + build_timestamp ] 167 168 # Don't look for libpaths in %LIB%, similar to /X in cflags above. 169 ldflags += [ "/lldignoreenv" ] 170 } 171 172 # Some binaries create PDBs larger than 4 GiB. Increasing the PDB page size 173 # to 8 KiB allows 8 GiB PDBs. The larger page size also allows larger block maps 174 # which is a PDB limit that was hit in https://crbug.com/1406510. The page size 175 # can easily be increased in the future to allow even larger PDBs or larger 176 # block maps. 177 # This flag requires lld-link.exe or link.exe from VS 2022 or later to create 178 # the PDBs, and tools from circa 22H2 or later to consume the PDBs. 179 # Debug component builds can generate PDBs that exceed 8 GiB, so use an 180 # even larger page size, allowing up to 16 GiB PDBs. 181 if (is_debug && !is_component_build) { 182 ldflags += [ "/pdbpagesize:16384" ] 183 } else { 184 ldflags += [ "/pdbpagesize:8192" ] 185 } 186 187 if (!is_debug && !is_component_build) { 188 # Enable standard linker optimizations like GC (/OPT:REF) and ICF in static 189 # release builds. 190 # Release builds always want these optimizations, so enable them explicitly. 191 ldflags += [ 192 "/OPT:REF", 193 "/OPT:ICF", 194 "/INCREMENTAL:NO", 195 "/FIXED:NO", 196 ] 197 198 if (use_lld) { 199 # String tail merging leads to smaller binaries, but they don't compress 200 # as well, leading to increased mini_installer size (crbug.com/838449). 201 ldflags += [ "/OPT:NOLLDTAILMERGE" ] 202 } 203 204 # TODO(siggi): Is this of any use anymore? 205 # /PROFILE ensures that the PDB file contains FIXUP information (growing the 206 # PDB file by about 5%) but does not otherwise alter the output binary. It 207 # is enabled opportunistically for builds where it is not prohibited (not 208 # supported when incrementally linking, or using /debug:fastlink). 209 ldflags += [ "/PROFILE" ] 210 } 211 212 # arflags apply only to static_libraries. The normal linker configs are only 213 # set for executable and shared library targets so arflags must be set 214 # elsewhere. Since this is relatively contained, we just apply them in this 215 # more general config and they will only have an effect on static libraries. 216 arflags = [ 217 # "No public symbols found; archive member will be inaccessible." This 218 # means that one or more object files in the library can never be 219 # pulled in to targets that link to this library. It's just a warning that 220 # the source file is a no-op. 221 "/ignore:4221", 222 ] 223} 224 225# This is included by reference in the //build/config/compiler:runtime_library 226# config that is applied to all targets. It is here to separate out the logic 227# that is Windows-only. Please see that target for advice on what should go in 228# :runtime_library vs. :compiler. 229config("runtime_library") { 230 cflags = [] 231 cflags_cc = [] 232 233 # Defines that set up the CRT. 234 defines = [ 235 "__STD_C", 236 "_CRT_RAND_S", 237 "_CRT_SECURE_NO_DEPRECATE", 238 "_SCL_SECURE_NO_DEPRECATE", 239 ] 240 241 # Defines that set up the Windows SDK. 242 defines += [ 243 "_ATL_NO_OPENGL", 244 "_WINDOWS", 245 "CERT_CHAIN_PARA_HAS_EXTRA_FIELDS", 246 "PSAPI_VERSION=2", 247 "WIN32", 248 "_SECURE_ATL", 249 ] 250 251 if (current_os == "winuwp") { 252 # When targeting Windows Runtime, certain compiler/linker flags are 253 # necessary. 254 defines += [ 255 "WINUWP", 256 "__WRL_NO_DEFAULT_LIB__", 257 ] 258 if (target_winuwp_family == "app") { 259 defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_PC_APP" ] 260 } else if (target_winuwp_family == "phone") { 261 defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" ] 262 } else if (target_winuwp_family == "system") { 263 defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_SYSTEM" ] 264 } else if (target_winuwp_family == "server") { 265 defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_SERVER" ] 266 } else { 267 defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP" ] 268 } 269 cflags_cc += [ "/EHsc" ] 270 271 # This warning is given because the linker cannot tell the difference 272 # between consuming WinRT APIs versus authoring WinRT within static 273 # libraries as such this warning is always given by the linker. Since 274 # consuming WinRT APIs within a library is legitimate but authoring 275 # WinRT APis is not allowed, this warning is disabled to ignore the 276 # legitimate consumption of WinRT APIs within static library builds. 277 arflags = [ "/IGNORE:4264" ] 278 279 if (target_winuwp_version == "10") { 280 defines += [ "WIN10=_WIN32_WINNT_WIN10" ] 281 } else if (target_winuwp_version == "8.1") { 282 defines += [ "WIN8_1=_WIN32_WINNT_WINBLUE" ] 283 } else if (target_winuwp_version == "8.0") { 284 defines += [ "WIN8=_WIN32_WINNT_WIN8" ] 285 } 286 } else { 287 # When not targeting Windows Runtime, make sure the WINAPI family is set 288 # to desktop. 289 defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP" ] 290 } 291} 292 293# Chromium only supports Windowes 10+. 294# Some third-party libraries assume that these defines set what version of 295# Windows is available at runtime. Targets using these libraries need to 296# manually override this config for their compiles. 297config("winver") { 298 defines = [ 299 "NTDDI_VERSION=NTDDI_WIN10_NI", 300 301 # We can't say `=_WIN32_WINNT_WIN10` here because some files do 302 # `#if WINVER < 0x0600` without including windows.h before, 303 # and then _WIN32_WINNT_WIN10 isn't yet known to be 0x0A00. 304 "_WIN32_WINNT=0x0A00", 305 "WINVER=0x0A00", 306 ] 307} 308 309# Linker flags for Windows SDK setup, this is applied only to EXEs and DLLs. 310config("sdk_link") { 311 if (current_cpu == "x86") { 312 ldflags = [ 313 "/SAFESEH", # Not compatible with x64 so use only for x86. 314 "/largeaddressaware", 315 ] 316 } 317} 318 319# This default linker setup is provided separately from the SDK setup so 320# targets who want different library configurations can remove this and specify 321# their own. 322config("common_linker_setup") { 323 ldflags = [ 324 "/FIXED:NO", 325 "/ignore:4199", 326 "/ignore:4221", 327 "/NXCOMPAT", 328 "/DYNAMICBASE", 329 ] 330 331 if (win_linker_timing) { 332 ldflags += [ 333 "/time", 334 "/verbose:incr", 335 ] 336 } 337} 338 339config("default_cfg_compiler") { 340 # Emit table of address-taken functions for Control-Flow Guard (CFG). 341 # This is needed to allow functions to be called by code that is built 342 # with CFG enabled, such as system libraries. 343 # The CFG guards are only emitted if |win_enable_cfg_guards| is enabled. 344 if (win_enable_cfg_guards) { 345 if (is_clang) { 346 cflags = [ "/guard:cf" ] 347 } 348 rustflags = [ "-Ccontrol-flow-guard" ] 349 } else { 350 if (is_clang) { 351 cflags = [ "/guard:cf,nochecks" ] 352 } 353 rustflags = [ "-Ccontrol-flow-guard=nochecks" ] 354 } 355} 356 357# To disable CFG guards for a target, remove the "default_cfg_compiler" 358# config, and add "disable_guards_cfg_compiler" config. 359config("disable_guards_cfg_compiler") { 360 # Emit table of address-taken functions for Control-Flow Guard (CFG). 361 # This is needed to allow functions to be called by code that is built 362 # with CFG enabled, such as system libraries. 363 if (is_clang) { 364 cflags = [ "/guard:cf,nochecks" ] 365 } 366 rustflags = [ "-Ccontrol-flow-guard=nochecks" ] 367} 368 369config("cfi_linker") { 370 # Control Flow Guard (CFG) 371 # https://msdn.microsoft.com/en-us/library/windows/desktop/mt637065.aspx 372 # /DYNAMICBASE (ASLR) is turned off in debug builds, therefore CFG cannot be 373 # turned on either. 374 # ASan and CFG leads to slow process startup. Chromium's test runner uses 375 # lots of child processes, so this means things are really slow. Disable CFG 376 # for now. https://crbug.com/846966 377 if (!is_debug && !is_asan) { 378 # Turn on CFG bitmap generation and CFG load config. 379 ldflags = [ "/guard:cf" ] 380 } 381} 382 383# This is a superset of all the delayloads needed for chrome.exe, chrome.dll, 384# and chrome_elf.dll. The linker will automatically ignore anything which is not 385# linked to the binary at all (it is harmless to have an unmatched /delayload). 386# 387# We delayload most libraries as the dlls are simply not required at startup (or 388# at all, depending on the process type). In unsandboxed process they will load 389# when first needed. 390# 391# Some dlls open handles when they are loaded, and we may not want them to be 392# loaded in renderers or other sandboxed processes. Conversely, some dlls must 393# be loaded before sandbox lockdown. 394# 395# Some dlls themselves load others - in particular, to avoid unconditionally 396# loading user32.dll - we require that the following dlls are all delayloaded: 397# user32, gdi32, comctl32, comdlg32, cryptui, d3d9, dwmapi, imm32, msi, ole32, 398# oleacc, rstrtmgr, shell32, shlwapi, and uxtheme. 399# 400# Advapi32.dll is unconditionally loaded at process startup on Windows 10, but 401# on Windows 11 it is not, which makes it worthwhile to delay load it. 402# Additionally, advapi32.dll exports several functions that are forwarded to 403# other DLLs such as cryptbase.dll. If calls to those functions are present but 404# there are some processes where the functions are never called then delay 405# loading of advapi32.dll avoids pulling in those DLLs (such as cryptbase.dll) 406# unnecessarily, even if advapi32.dll itself is loaded. 407# 408# This config applies to chrome.exe, chrome.dll, chrome_elf.dll (& others). 409# 410# This config should also be used for any test binary whose goal is to run 411# tests with the full browser. 412config("delayloads") { 413 ldflags = [ 414 "/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll", 415 "/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll", 416 "/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll", 417 "/DELAYLOAD:advapi32.dll", 418 "/DELAYLOAD:comctl32.dll", 419 "/DELAYLOAD:comdlg32.dll", 420 "/DELAYLOAD:credui.dll", 421 "/DELAYLOAD:cryptui.dll", 422 "/DELAYLOAD:d3d11.dll", 423 "/DELAYLOAD:d3d9.dll", 424 "/DELAYLOAD:dwmapi.dll", 425 "/DELAYLOAD:dxgi.dll", 426 "/DELAYLOAD:dxva2.dll", 427 "/DELAYLOAD:esent.dll", 428 "/DELAYLOAD:gdi32.dll", 429 "/DELAYLOAD:hid.dll", 430 "/DELAYLOAD:imagehlp.dll", 431 "/DELAYLOAD:imm32.dll", 432 "/DELAYLOAD:msi.dll", 433 "/DELAYLOAD:netapi32.dll", 434 "/DELAYLOAD:ncrypt.dll", 435 "/DELAYLOAD:ole32.dll", 436 "/DELAYLOAD:oleacc.dll", 437 "/DELAYLOAD:pdh.dll", 438 "/DELAYLOAD:propsys.dll", 439 "/DELAYLOAD:psapi.dll", 440 "/DELAYLOAD:rpcrt4.dll", 441 "/DELAYLOAD:rstrtmgr.dll", 442 "/DELAYLOAD:setupapi.dll", 443 "/DELAYLOAD:shell32.dll", 444 "/DELAYLOAD:shlwapi.dll", 445 "/DELAYLOAD:uiautomationcore.dll", 446 "/DELAYLOAD:urlmon.dll", 447 "/DELAYLOAD:user32.dll", 448 "/DELAYLOAD:usp10.dll", 449 "/DELAYLOAD:uxtheme.dll", 450 "/DELAYLOAD:wer.dll", 451 "/DELAYLOAD:wevtapi.dll", 452 "/DELAYLOAD:wininet.dll", 453 "/DELAYLOAD:winusb.dll", 454 "/DELAYLOAD:wsock32.dll", 455 "/DELAYLOAD:wtsapi32.dll", 456 ] 457} 458 459# This config (along with `:delayloads`) applies to chrome.exe & chrome_elf.dll. 460# Entries should not appear in both configs. 461config("delayloads_not_for_child_dll") { 462 ldflags = [ 463 "/DELAYLOAD:crypt32.dll", 464 "/DELAYLOAD:dbghelp.dll", 465 "/DELAYLOAD:dhcpcsvc.dll", 466 "/DELAYLOAD:dwrite.dll", 467 "/DELAYLOAD:iphlpapi.dll", 468 "/DELAYLOAD:oleaut32.dll", 469 "/DELAYLOAD:secur32.dll", 470 "/DELAYLOAD:userenv.dll", 471 "/DELAYLOAD:winhttp.dll", 472 "/DELAYLOAD:winmm.dll", 473 "/DELAYLOAD:winspool.drv", 474 "/DELAYLOAD:wintrust.dll", 475 "/DELAYLOAD:ws2_32.dll", 476 ] 477} 478 479# CRT -------------------------------------------------------------------------- 480 481# Configures how the runtime library (CRT) is going to be used. 482# See https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx for a reference of 483# what each value does. 484config("default_crt") { 485 if (is_component_build) { 486 # Component mode: dynamic CRT. Since the library is shared, it requires 487 # exceptions or will give errors about things not matching, so keep 488 # exceptions on. 489 configs = [ ":dynamic_crt" ] 490 } else { 491 if (current_os == "winuwp") { 492 # https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/ 493 # contains a details explanation of what is happening with the Windows 494 # CRT in Visual Studio releases related to Windows store applications. 495 configs = [ ":dynamic_crt" ] 496 } else { 497 # Desktop Windows: static CRT. 498 configs = [ ":static_crt" ] 499 } 500 } 501} 502 503# Use this to force use of the release CRT when building perf-critical build 504# tools that need to be fully optimized even in debug builds, for those times 505# when the debug CRT is part of the bottleneck. This also avoids *implicitly* 506# defining _DEBUG. 507config("release_crt") { 508 if (is_component_build) { 509 cflags = [ "/MD" ] 510 511 if (rust_prebuilt_stdlib) { 512 rustflags = [ "-Ctarget-feature=-crt-static" ] 513 } else { 514 # /MD specifies msvcrt.lib as the CRT library. Rust needs to agree, so 515 # we specify it explicitly. Once 516 # https://github.com/rust-lang/rust/issues/39016 is resolved we should 517 # instead tell rustc which CRT to use (static/dynamic + release/debug). 518 rustflags = [ "-Clink-arg=msvcrt.lib" ] 519 } 520 521 if (use_custom_libcxx) { 522 # On Windows, including libcpmt[d]/msvcprt[d] explicitly links the C++ 523 # standard library, which libc++ needs for exception_ptr internals. 524 ldflags = [ "/DEFAULTLIB:msvcprt.lib" ] 525 } 526 } else { 527 cflags = [ "/MT" ] 528 529 if (rust_prebuilt_stdlib) { 530 rustflags = [ "-Ctarget-feature=+crt-static" ] 531 } else { 532 # /MT specifies libcmt.lib as the CRT library. Rust needs to agree, so 533 # we specify it explicitly. Once 534 # https://github.com/rust-lang/rust/issues/39016 is resolved we should 535 # instead tell rustc which CRT to use (static/dynamic + release/debug). 536 rustflags = [ "-Clink-arg=libcmt.lib" ] 537 } 538 539 if (use_custom_libcxx) { 540 ldflags = [ "/DEFAULTLIB:libcpmt.lib" ] 541 } 542 } 543} 544 545config("dynamic_crt") { 546 if (is_debug) { 547 # This pulls in the DLL debug CRT and defines _DEBUG 548 cflags = [ "/MDd" ] 549 550 # /MDd specifies msvcrtd.lib as the CRT library. Rust needs to agree, so 551 # we specify it explicitly. 552 # Once https://github.com/rust-lang/rust/issues/39016 is resolved we should 553 # instead tell rustc which CRT to use (static/dynamic + release/debug). We 554 # can't support prebuilt stdlib in this path until then. 555 rustflags = [ "-Clink-arg=msvcrtd.lib" ] 556 557 if (use_custom_libcxx) { 558 ldflags = [ "/DEFAULTLIB:msvcprtd.lib" ] 559 } 560 } else { 561 cflags = [ "/MD" ] 562 563 if (rust_prebuilt_stdlib) { 564 rustflags = [ "-Ctarget-feature=-crt-static" ] 565 } else { 566 # /MD specifies msvcrt.lib as the CRT library. Rust needs to agree, so 567 # we specify it explicitly. 568 # Once https://github.com/rust-lang/rust/issues/39016 is resolved we 569 # should instead tell rustc which CRT to use (static/dynamic + 570 # release/debug). 571 rustflags = [ "-Clink-arg=msvcrt.lib" ] 572 } 573 574 if (use_custom_libcxx) { 575 ldflags = [ "/DEFAULTLIB:msvcprt.lib" ] 576 } 577 } 578} 579 580config("static_crt") { 581 if (is_debug) { 582 # This pulls in the static debug CRT and defines _DEBUG 583 cflags = [ "/MTd" ] 584 585 # /MTd specifies libcmtd.lib as the CRT library. Rust needs to agree, so 586 # we specify it explicitly. 587 # Once https://github.com/rust-lang/rust/issues/39016 is resolved we should 588 # instead tell rustc which CRT to use (static/dynamic + release/debug). We 589 # can't support prebuilt stdlib in this path until then. 590 rustflags = [ "-Clink-arg=libcmtd.lib" ] 591 592 if (use_custom_libcxx) { 593 ldflags = [ "/DEFAULTLIB:libcpmtd.lib" ] 594 } 595 } else { 596 cflags = [ "/MT" ] 597 598 if (rust_prebuilt_stdlib) { 599 rustflags = [ "-Ctarget-feature=+crt-static" ] 600 } else { 601 # /MT specifies libcmt.lib as the CRT library. Rust needs to agree, so 602 # we specify it explicitly. 603 # Once https://github.com/rust-lang/rust/issues/39016 is resolved we 604 # should instead tell rustc which CRT to use (static/dynamic + 605 # release/debug). 606 rustflags = [ "-Clink-arg=libcmt.lib" ] 607 } 608 609 if (use_custom_libcxx) { 610 ldflags = [ "/DEFAULTLIB:libcpmt.lib" ] 611 } 612 } 613} 614 615# Subsystem -------------------------------------------------------------------- 616 617# This is appended to the subsystem to specify a minimum version. 618if (current_cpu == "x64") { 619 # The number after the comma is the minimum required OS version. 620 # 5.02 = Windows Server 2003. 621 subsystem_version_suffix = ",5.02" 622} else if (current_cpu == "arm64") { 623 # Windows ARM64 requires Windows 10. 624 subsystem_version_suffix = ",10.0" 625} else { 626 # 5.01 = Windows XP. 627 subsystem_version_suffix = ",5.01" 628} 629 630config("console") { 631 ldflags = [ "/SUBSYSTEM:CONSOLE$subsystem_version_suffix" ] 632} 633config("windowed") { 634 ldflags = [ "/SUBSYSTEM:WINDOWS$subsystem_version_suffix" ] 635} 636 637# Incremental linking ---------------------------------------------------------- 638 639# Applies incremental linking or not depending on the current configuration. 640config("default_incremental_linking") { 641 # Enable incremental linking for debug builds and all component builds - any 642 # builds where performance is not job one. 643 # TODO(thakis): Always turn this on with lld, no reason not to. 644 if (is_debug || is_component_build) { 645 ldflags = [ "/INCREMENTAL" ] 646 if (use_lld) { 647 # lld doesn't use ilk files and doesn't really have an incremental link 648 # mode; the only effect of the flag is that the .lib file timestamp isn't 649 # updated if the .lib doesn't change. 650 # TODO(thakis): Why pass /OPT:NOREF for lld, but not otherwise? 651 # TODO(thakis): /INCREMENTAL is on by default in link.exe, but not in 652 # lld. 653 ldflags += [ "/OPT:NOREF" ] 654 655 # TODO(crbug.com/1444129): Mixing incrememntal and icf produces an error 656 # in lld-link. 657 ldflags += [ "/OPT:NOICF" ] 658 } 659 } else { 660 ldflags = [ "/INCREMENTAL:NO" ] 661 } 662} 663 664# Character set ---------------------------------------------------------------- 665 666# Not including this config means "ansi" (8-bit system codepage). 667config("unicode") { 668 defines = [ 669 "_UNICODE", 670 "UNICODE", 671 ] 672} 673 674# Lean and mean ---------------------------------------------------------------- 675 676# Some third party code might not compile with WIN32_LEAN_AND_MEAN so we have 677# to have a separate config for it. Remove this config from your target to 678# get the "bloaty and accommodating" version of windows.h. 679config("lean_and_mean") { 680 defines = [ "WIN32_LEAN_AND_MEAN" ] 681} 682 683# Nominmax -------------------------------------------------------------------- 684 685# Some third party code defines NOMINMAX before including windows.h, which 686# then causes warnings when it's been previously defined on the command line. 687# For such targets, this config can be removed. 688 689config("nominmax") { 690 defines = [ "NOMINMAX" ] 691} 692