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