OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import("//build/config/sanitizers/sanitizers.gni") |
| 6 import("//build/config/win/visual_studio_version.gni") |
| 7 import("//build/toolchain/goma.gni") |
| 8 import("//build/toolchain/toolchain.gni") |
| 9 |
| 10 # Should only be running on Windows. |
| 11 assert(is_win) |
| 12 |
| 13 # Setup the Visual Studio state. |
| 14 # |
| 15 # Its arguments are the VS path and the compiler wrapper tool. It will write |
| 16 # "environment.x86" and "environment.x64" to the build directory and return a |
| 17 # list to us. |
| 18 gyp_win_tool_path = |
| 19 rebase_path("//tools/gyp/pylib/gyp/win_tool.py", root_build_dir) |
| 20 |
| 21 if (use_goma) { |
| 22 goma_prefix = "$goma_dir/gomacc.exe " |
| 23 } else { |
| 24 goma_prefix = "" |
| 25 } |
| 26 |
| 27 # This value will be inherited in the toolchain below. |
| 28 concurrent_links = exec_script("../get_concurrent_links.py", [], "value") |
| 29 |
| 30 # Copy the VS runtime DLL for the default toolchain to the root build directory |
| 31 # so things will run. |
| 32 if (current_toolchain == default_toolchain) { |
| 33 if (is_debug) { |
| 34 configuration_name = "Debug" |
| 35 } else { |
| 36 configuration_name = "Release" |
| 37 } |
| 38 exec_script("../../vs_toolchain.py", |
| 39 [ |
| 40 "copy_dlls", |
| 41 rebase_path(root_build_dir), |
| 42 configuration_name, |
| 43 target_cpu, |
| 44 ]) |
| 45 } |
| 46 |
| 47 # Parameters: |
| 48 # toolchain_cpu: current_cpu to pass as a build arg |
| 49 # toolchain_os: current_os to pass as a build arg |
| 50 # environment: File name of environment file. |
| 51 template("msvc_toolchain") { |
| 52 if (defined(invoker.concurrent_links)) { |
| 53 concurrent_links = invoker.concurrent_links |
| 54 } |
| 55 |
| 56 env = invoker.environment |
| 57 |
| 58 if (invoker.is_clang && host_os != "win") { |
| 59 # This toolchain definition uses response files for compilations. GN uses |
| 60 # the quoting rules of the host OS, while clang-cl always defaults to |
| 61 # cmd.exe quoting rules for parsing response files. Tell clang-cl to use |
| 62 # POSIX quoting rules, so it can understand what GN generates. |
| 63 cl = "${invoker.cl} --rsp-quoting=posix" |
| 64 } else { |
| 65 cl = invoker.cl |
| 66 } |
| 67 |
| 68 if (use_lld) { |
| 69 if (host_os == "win") { |
| 70 lld_link = "lld-link.exe" |
| 71 } else { |
| 72 lld_link = "lld-link" |
| 73 } |
| 74 prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin", |
| 75 root_build_dir) |
| 76 |
| 77 # lld-link includes a replacement for lib.exe that can produce thin |
| 78 # archives and understands bitcode (for lto builds). |
| 79 lib = "$prefix/$lld_link /lib /llvmlibthin" |
| 80 link = "$prefix/$lld_link" |
| 81 } else { |
| 82 lib = "lib.exe" |
| 83 link = "link.exe" |
| 84 } |
| 85 |
| 86 # If possible, pass system includes as flags to the compiler. When that's |
| 87 # not possible, load a full environment file (containing %INCLUDE% and |
| 88 # %PATH%) -- e.g. 32-bit MSVS builds require %PATH% to be set and just passing |
| 89 # in a list of include directories isn't enough. |
| 90 if (defined(invoker.sys_include_flags)) { |
| 91 env_wrapper = "" |
| 92 sys_include_flags = "${invoker.sys_include_flags} " # Note trailing space. |
| 93 } else { |
| 94 # clang-cl doesn't need this env hoop, so omit it there. |
| 95 assert(!invoker.is_clang) |
| 96 env_wrapper = "ninja -t msvc -e $env -- " # Note trailing space. |
| 97 sys_include_flags = "" |
| 98 } |
| 99 |
| 100 toolchain(target_name) { |
| 101 # Make these apply to all tools below. |
| 102 lib_switch = "" |
| 103 lib_dir_switch = "/LIBPATH:" |
| 104 |
| 105 # Object files go in this directory. |
| 106 object_subdir = "{{target_out_dir}}/{{label_name}}" |
| 107 |
| 108 tool("cc") { |
| 109 rspfile = "{{output}}.rsp" |
| 110 precompiled_header_type = "msvc" |
| 111 pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" |
| 112 |
| 113 # Label names may have spaces in them so the pdbname must be quoted. The |
| 114 # source and output don't need to be quoted because GN knows they're a |
| 115 # full file name and will quote automatically when necessary. |
| 116 command = "$env_wrapper$cl /nologo /showIncludes /FC @$rspfile /c {{source
}} /Fo{{output}} /Fd\"$pdbname\"" |
| 117 depsformat = "msvc" |
| 118 description = "CC {{output}}" |
| 119 outputs = [ |
| 120 "$object_subdir/{{source_name_part}}.obj", |
| 121 ] |
| 122 rspfile_content = "$sys_include_flags{{defines}} {{include_dirs}} {{cflags
}} {{cflags_c}}" |
| 123 } |
| 124 |
| 125 tool("cxx") { |
| 126 rspfile = "{{output}}.rsp" |
| 127 precompiled_header_type = "msvc" |
| 128 |
| 129 # The PDB name needs to be different between C and C++ compiled files. |
| 130 pdbname = "{{target_out_dir}}/{{label_name}}_cc.pdb" |
| 131 |
| 132 # See comment in CC tool about quoting. |
| 133 command = "$env_wrapper$cl /nologo /showIncludes /FC @$rspfile /c {{source
}} /Fo{{output}} /Fd\"$pdbname\"" |
| 134 depsformat = "msvc" |
| 135 description = "CXX {{output}}" |
| 136 outputs = [ |
| 137 "$object_subdir/{{source_name_part}}.obj", |
| 138 ] |
| 139 rspfile_content = "$sys_include_flags{{defines}} {{include_dirs}} {{cflags
}} {{cflags_cc}}" |
| 140 } |
| 141 |
| 142 tool("rc") { |
| 143 command = "$python_path gyp-win-tool rc-wrapper $env rc.exe {{defines}} {{
include_dirs}} /fo{{output}} {{source}}" |
| 144 outputs = [ |
| 145 "$object_subdir/{{source_name_part}}.res", |
| 146 ] |
| 147 description = "RC {{output}}" |
| 148 } |
| 149 |
| 150 tool("asm") { |
| 151 if (invoker.toolchain_cpu == "x64") { |
| 152 ml = "ml64.exe" |
| 153 } else { |
| 154 ml = "ml.exe" |
| 155 } |
| 156 command = "$python_path gyp-win-tool asm-wrapper $env $ml {{defines}} {{in
clude_dirs}} {{asmflags}} /c /Fo{{output}} {{source}}" |
| 157 description = "ASM {{output}}" |
| 158 outputs = [ |
| 159 "$object_subdir/{{source_name_part}}.obj", |
| 160 ] |
| 161 } |
| 162 |
| 163 tool("alink") { |
| 164 rspfile = "{{output}}.rsp" |
| 165 command = "$python_path gyp-win-tool link-wrapper $env False $lib /nologo
{{arflags}} /OUT:{{output}} @$rspfile" |
| 166 description = "LIB {{output}}" |
| 167 outputs = [ |
| 168 # Ignore {{output_extension}} and always use .lib, there's no reason to |
| 169 # allow targets to override this extension on Windows. |
| 170 "{{output_dir}}/{{target_output_name}}.lib", |
| 171 ] |
| 172 default_output_extension = ".lib" |
| 173 default_output_dir = "{{target_out_dir}}" |
| 174 |
| 175 # The use of inputs_newline is to work around a fixed per-line buffer |
| 176 # size in the linker. |
| 177 rspfile_content = "{{inputs_newline}}" |
| 178 } |
| 179 |
| 180 tool("solink") { |
| 181 dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e
.g. foo.dll |
| 182 libname = "${dllname}.lib" # e.g. foo.dll.lib |
| 183 rspfile = "${dllname}.rsp" |
| 184 |
| 185 command = "$python_path gyp-win-tool link-wrapper $env False $link /nologo
/IMPLIB:$libname /DLL /OUT:$dllname /PDB:${dllname}.pdb @$rspfile" |
| 186 |
| 187 default_output_extension = ".dll" |
| 188 default_output_dir = "{{root_out_dir}}" |
| 189 description = "LINK(DLL) {{output}}" |
| 190 outputs = [ |
| 191 dllname, |
| 192 libname, |
| 193 ] |
| 194 link_output = libname |
| 195 depend_output = libname |
| 196 runtime_link_output = dllname |
| 197 |
| 198 # Since the above commands only updates the .lib file when it changes, ask |
| 199 # Ninja to check if the timestamp actually changed to know if downstream |
| 200 # dependencies should be recompiled. |
| 201 restat = true |
| 202 |
| 203 # The use of inputs_newline is to work around a fixed per-line buffer |
| 204 # size in the linker. |
| 205 rspfile_content = "{{libs}} {{solibs}} {{inputs_newline}} {{ldflags}}" |
| 206 } |
| 207 |
| 208 tool("solink_module") { |
| 209 dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e
.g. foo.dll |
| 210 rspfile = "${dllname}.rsp" |
| 211 |
| 212 command = "$python_path gyp-win-tool link-wrapper $env False $link /nologo
/DLL /OUT:$dllname /PDB:${dllname}.pdb @$rspfile" |
| 213 |
| 214 default_output_extension = ".dll" |
| 215 default_output_dir = "{{root_out_dir}}" |
| 216 description = "LINK_MODULE(DLL) {{output}}" |
| 217 outputs = [ |
| 218 dllname, |
| 219 ] |
| 220 |
| 221 # The use of inputs_newline is to work around a fixed per-line buffer |
| 222 # size in the linker. |
| 223 rspfile_content = "{{libs}} {{solibs}} {{inputs_newline}} {{ldflags}}" |
| 224 } |
| 225 |
| 226 tool("link") { |
| 227 rspfile = "{{output}}.rsp" |
| 228 |
| 229 command = "$python_path gyp-win-tool link-wrapper $env False $link /nologo
/OUT:{{output}} /PDB:{{output}}.pdb @$rspfile" |
| 230 |
| 231 default_output_extension = ".exe" |
| 232 default_output_dir = "{{root_out_dir}}" |
| 233 description = "LINK {{output}}" |
| 234 outputs = [ |
| 235 "{{output_dir}}/{{target_output_name}}{{output_extension}}", |
| 236 ] |
| 237 |
| 238 # The use of inputs_newline is to work around a fixed per-line buffer |
| 239 # size in the linker. |
| 240 rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" |
| 241 } |
| 242 |
| 243 # These two are really entirely generic, but have to be repeated in |
| 244 # each toolchain because GN doesn't allow a template to be used here. |
| 245 # See //build/toolchain/toolchain.gni for details. |
| 246 tool("stamp") { |
| 247 command = stamp_command |
| 248 description = stamp_description |
| 249 } |
| 250 tool("copy") { |
| 251 command = copy_command |
| 252 description = copy_description |
| 253 } |
| 254 |
| 255 # When invoking this toolchain not as the default one, these args will be |
| 256 # passed to the build. They are ignored when this is the default toolchain. |
| 257 toolchain_args() { |
| 258 current_cpu = invoker.toolchain_cpu |
| 259 if (defined(invoker.toolchain_os)) { |
| 260 current_os = invoker.toolchain_os |
| 261 } |
| 262 |
| 263 # These share a name with global variables that are already defined, and |
| 264 # forward_variables_from won't clobber the existing value, so we need to |
| 265 # set it explicitly. |
| 266 if (defined(invoker.is_clang)) { |
| 267 is_clang = invoker.is_clang |
| 268 } |
| 269 if (defined(invoker.is_component_build)) { |
| 270 is_component_build = invoker.is_component_build |
| 271 } |
| 272 |
| 273 # This value needs to be passed through unchanged. |
| 274 host_toolchain = host_toolchain |
| 275 } |
| 276 } |
| 277 } |
| 278 |
| 279 if (is_clang) { |
| 280 sys_include_prefix = "-imsvc" |
| 281 } else { |
| 282 # MSVC doesn't have the concept of system headers. |
| 283 sys_include_prefix = "/I" |
| 284 } |
| 285 |
| 286 if (host_os == "win") { |
| 287 clang_cl = "clang-cl.exe" |
| 288 } else { |
| 289 clang_cl = "clang-cl" |
| 290 } |
| 291 |
| 292 # 32-bit toolchains. Only define these when the target architecture is 32-bit |
| 293 # since we don't do any 32-bit cross compiles when targeting 64-bit (the |
| 294 # build does generate some 64-bit stuff from 32-bit target builds). |
| 295 if (target_cpu == "x86") { |
| 296 x86_toolchain_data = exec_script("setup_toolchain.py", |
| 297 [ |
| 298 visual_studio_path, |
| 299 gyp_win_tool_path, |
| 300 windows_sdk_path, |
| 301 visual_studio_runtime_dirs, |
| 302 "x86", |
| 303 "${sys_include_prefix}", |
| 304 ], |
| 305 "scope") |
| 306 |
| 307 msvc_toolchain("x86") { |
| 308 environment = "environment.x86" |
| 309 toolchain_cpu = "x86" |
| 310 cl = "${goma_prefix}\"${x86_toolchain_data.vc_bin_dir}/cl.exe\"" |
| 311 is_clang = false |
| 312 } |
| 313 |
| 314 msvc_toolchain("clang_x86") { |
| 315 environment = "environment.x86" |
| 316 toolchain_cpu = "x86" |
| 317 prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin", |
| 318 root_build_dir) |
| 319 cl = "${goma_prefix}$prefix/${clang_cl}" |
| 320 toolchain_os = "win" |
| 321 is_clang = true |
| 322 sys_include_flags = "${x86_toolchain_data.include_flags}" |
| 323 } |
| 324 } |
| 325 |
| 326 # 64-bit toolchains. |
| 327 x64_toolchain_data = exec_script("setup_toolchain.py", |
| 328 [ |
| 329 visual_studio_path, |
| 330 gyp_win_tool_path, |
| 331 windows_sdk_path, |
| 332 visual_studio_runtime_dirs, |
| 333 "x64", |
| 334 "${sys_include_prefix}", |
| 335 ], |
| 336 "scope") |
| 337 |
| 338 template("win_x64_toolchains") { |
| 339 # TODO(mcgrathr): These assignments are only required because of |
| 340 # crbug.com/395883. Drop them if that ever gets fixed in GN. |
| 341 concurrent_links = invoker.concurrent_links |
| 342 goma_prefix = invoker.goma_prefix |
| 343 x64_toolchain_data = invoker.x64_toolchain_data |
| 344 clang_cl = invoker.clang_cl |
| 345 |
| 346 msvc_toolchain(target_name) { |
| 347 environment = "environment.x64" |
| 348 toolchain_cpu = "x64" |
| 349 cl = "${goma_prefix}\"${x64_toolchain_data.vc_bin_dir}/cl.exe\"" |
| 350 is_clang = false |
| 351 |
| 352 # This shares a name with a global and forward_variables_from won't clobber |
| 353 # the existing value, so we need to set it explicitly. |
| 354 if (defined(invoker.is_component_build)) { |
| 355 is_component_build = invoker.is_component_build |
| 356 } |
| 357 } |
| 358 |
| 359 msvc_toolchain("clang_" + target_name) { |
| 360 environment = "environment.x64" |
| 361 toolchain_cpu = "x64" |
| 362 prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin", |
| 363 root_build_dir) |
| 364 cl = "${goma_prefix}$prefix/${clang_cl}" |
| 365 toolchain_os = "win" |
| 366 is_clang = true |
| 367 sys_include_flags = "${x64_toolchain_data.include_flags}" |
| 368 |
| 369 # This shares a name with a global and forward_variables_from won't clobber |
| 370 # the existing value, so we need to set it explicitly. |
| 371 if (defined(invoker.is_component_build)) { |
| 372 is_component_build = invoker.is_component_build |
| 373 } |
| 374 } |
| 375 } |
| 376 |
| 377 win_x64_toolchains("x64") { |
| 378 # TODO(mcgrathr): These assignments are only required because of |
| 379 # crbug.com/395883. Drop them if that ever gets fixed in GN. |
| 380 concurrent_links = concurrent_links |
| 381 goma_prefix = goma_prefix |
| 382 x64_toolchain_data = x64_toolchain_data |
| 383 } |
| 384 |
| 385 # The nacl_win64 toolchain is nearly identical to the plain x64 toolchain. |
| 386 # It's used solely for building nacl64.exe (//components/nacl/broker:nacl64). |
| 387 # The only reason it's a separate toolchain is so that it can force |
| 388 # is_component_build to false in the toolchain_args() block, because |
| 389 # building nacl64.exe in component style does not work. |
| 390 win_x64_toolchains("nacl_win64") { |
| 391 is_component_build = false |
| 392 |
| 393 # TODO(mcgrathr): These assignments are only required because of |
| 394 # crbug.com/395883. Drop them if that ever gets fixed in GN. |
| 395 concurrent_links = concurrent_links |
| 396 goma_prefix = goma_prefix |
| 397 x64_toolchain_data = x64_toolchain_data |
| 398 clang_cl = clang_cl |
| 399 } |
| 400 |
| 401 # WinRT toolchains. Only define these when targeting them. |
| 402 # |
| 403 # NOTE: This is currently broken because it references vc_bin_dir. brettw@ |
| 404 # changed this around a bit, and I don't know what this should be set to |
| 405 # in terms of what setup_toolchain returns for a certain CPU architecture. |
| 406 if (target_os == "winrt_81" || target_os == "winrt_81_phone" || |
| 407 target_os == "winrt_10") { |
| 408 msvc_toolchain("winrt_x86") { |
| 409 environment = "environment.winrt_x86" |
| 410 cl = "${goma_prefix}\"${vc_bin_dir}/cl.exe\"" |
| 411 is_clang = false |
| 412 |
| 413 toolchain_cpu = "x86" |
| 414 toolchain_os = current_os |
| 415 } |
| 416 |
| 417 msvc_toolchain("winrt_x64") { |
| 418 environment = "environment.winrt_x64" |
| 419 cl = "${goma_prefix}\"${vc_bin_dir}/cl.exe\"" |
| 420 is_clang = false |
| 421 |
| 422 toolchain_cpu = "x64" |
| 423 toolchain_os = current_os |
| 424 } |
| 425 } |
OLD | NEW |