|  | # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | declare_args() { | 
|  | # Path to the directory containing the VC binaries for the right | 
|  | # combination of host and target architectures. Currently only the | 
|  | # 64-bit host toolchain is supported, with either 32-bit or 64-bit targets. | 
|  | # If vc_bin_dir is not specified on the command line (and it normally | 
|  | # isn't), we will dynamically determine the right value to use at runtime. | 
|  | vc_bin_dir = "" | 
|  | } | 
|  |  | 
|  | import("//build/config/win/visual_studio_version.gni") | 
|  | import("//build/toolchain/goma.gni") | 
|  |  | 
|  | # Should only be running on Windows. | 
|  | assert(is_win) | 
|  |  | 
|  | # Setup the Visual Studio state. | 
|  | # | 
|  | # Its arguments are the VS path and the compiler wrapper tool. It will write | 
|  | # "environment.x86" and "environment.x64" to the build directory and return a | 
|  | # list to us. | 
|  | gyp_win_tool_path = | 
|  | rebase_path("//tools/gyp/pylib/gyp/win_tool.py", root_build_dir) | 
|  |  | 
|  | toolchain_data = exec_script("setup_toolchain.py", | 
|  | [ | 
|  | visual_studio_path, | 
|  | gyp_win_tool_path, | 
|  | windows_sdk_path, | 
|  | visual_studio_runtime_dirs, | 
|  | current_cpu, | 
|  | ], | 
|  | "scope") | 
|  |  | 
|  | if (vc_bin_dir == "") { | 
|  | vc_bin_dir = toolchain_data.vc_bin_dir | 
|  | } | 
|  |  | 
|  | if (use_goma) { | 
|  | goma_prefix = "$goma_dir/gomacc.exe " | 
|  | } else { | 
|  | goma_prefix = "" | 
|  | } | 
|  |  | 
|  | # This value will be inherited in the toolchain below. | 
|  | concurrent_links = exec_script("../get_concurrent_links.py", [], "value") | 
|  |  | 
|  | # Parameters: | 
|  | #  current_cpu: current_cpu to pass as a build arg | 
|  | #  environment: File name of environment file. | 
|  | template("msvc_toolchain") { | 
|  | if (defined(invoker.concurrent_links)) { | 
|  | concurrent_links = invoker.concurrent_links | 
|  | } | 
|  |  | 
|  | env = invoker.environment | 
|  |  | 
|  | if (is_debug) { | 
|  | configuration = "Debug" | 
|  | } else { | 
|  | configuration = "Release" | 
|  | } | 
|  | exec_script("../../vs_toolchain.py", | 
|  | [ | 
|  | "copy_dlls", | 
|  | rebase_path(root_build_dir), | 
|  | configuration, | 
|  | invoker.current_cpu, | 
|  | ]) | 
|  |  | 
|  | cl = invoker.cl | 
|  |  | 
|  | toolchain(target_name) { | 
|  | # Make these apply to all tools below. | 
|  | lib_switch = "" | 
|  | lib_dir_switch = "/LIBPATH:" | 
|  |  | 
|  | tool("cc") { | 
|  | rspfile = "{{output}}.rsp" | 
|  |  | 
|  | # TODO(brettw) enable this when GN support in the binary has been rolled. | 
|  | #precompiled_header_type = "msvc" | 
|  | pdbname = "{{target_out_dir}}/{{target_output_name}}_c.pdb" | 
|  | command = "ninja -t msvc -e $env -- $cl /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname" | 
|  | depsformat = "msvc" | 
|  | description = "CC {{output}}" | 
|  | outputs = [ | 
|  | "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.obj", | 
|  | ] | 
|  | rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}" | 
|  | } | 
|  |  | 
|  | tool("cxx") { | 
|  | rspfile = "{{output}}.rsp" | 
|  |  | 
|  | # TODO(brettw) enable this when GN support in the binary has been rolled. | 
|  | #precompiled_header_type = "msvc" | 
|  |  | 
|  | # The PDB name needs to be different between C and C++ compiled files. | 
|  | pdbname = "{{target_out_dir}}/{{target_output_name}}_cc.pdb" | 
|  | command = "ninja -t msvc -e $env -- $cl /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname" | 
|  | depsformat = "msvc" | 
|  | description = "CXX {{output}}" | 
|  | outputs = [ | 
|  | "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.obj", | 
|  | ] | 
|  | rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}" | 
|  | } | 
|  |  | 
|  | tool("rc") { | 
|  | command = "$python_path gyp-win-tool rc-wrapper $env rc.exe {{defines}} {{include_dirs}} /fo{{output}} {{source}}" | 
|  | outputs = [ | 
|  | "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.res", | 
|  | ] | 
|  | description = "RC {{output}}" | 
|  | } | 
|  |  | 
|  | tool("asm") { | 
|  | # TODO(brettw): "/safeseh" assembler argument is hardcoded here. Extract | 
|  | # assembler flags to a variable like cflags. crbug.com/418613 | 
|  | command = "$python_path gyp-win-tool asm-wrapper $env ml.exe {{defines}} {{include_dirs}} /safeseh /c /Fo {{output}} {{source}}" | 
|  | description = "ASM {{output}}" | 
|  | outputs = [ | 
|  | "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.obj", | 
|  | ] | 
|  | } | 
|  |  | 
|  | tool("alink") { | 
|  | rspfile = "{{output}}.rsp" | 
|  | command = "$python_path gyp-win-tool link-wrapper $env False lib.exe /nologo /ignore:4221 /OUT:{{output}} @$rspfile" | 
|  | description = "LIB {{output}}" | 
|  | outputs = [ | 
|  | # Ignore {{output_extension}} and always use .lib, there's no reason to | 
|  | # allow targets to override this extension on Windows. | 
|  | "{{target_out_dir}}/{{target_output_name}}.lib", | 
|  | ] | 
|  | default_output_extension = ".lib" | 
|  |  | 
|  | # The use of inputs_newline is to work around a fixed per-line buffer | 
|  | # size in the linker. | 
|  | rspfile_content = "{{inputs_newline}}" | 
|  | } | 
|  |  | 
|  | tool("solink") { | 
|  | dllname = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"  # e.g. foo.dll | 
|  | libname = | 
|  | "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.lib"  # e.g. foo.dll.lib | 
|  | rspfile = "${dllname}.rsp" | 
|  |  | 
|  | link_command = "$python_path gyp-win-tool link-wrapper $env False link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:${dllname}.pdb @$rspfile" | 
|  |  | 
|  | # TODO(brettw) support manifests | 
|  | #manifest_command = "$python_path gyp-win-tool manifest-wrapper $env mt.exe -nologo -manifest $manifests -out:${dllname}.manifest" | 
|  | #command = "cmd /c $link_command && $manifest_command" | 
|  | command = link_command | 
|  |  | 
|  | default_output_extension = ".dll" | 
|  | description = "LINK(DLL) {{output}}" | 
|  | outputs = [ | 
|  | dllname, | 
|  | libname, | 
|  | ] | 
|  | link_output = libname | 
|  | depend_output = libname | 
|  |  | 
|  | # The use of inputs_newline is to work around a fixed per-line buffer | 
|  | # size in the linker. | 
|  | rspfile_content = "{{libs}} {{solibs}} {{inputs_newline}} {{ldflags}}" | 
|  | } | 
|  |  | 
|  | tool("link") { | 
|  | rspfile = "{{output}}.rsp" | 
|  |  | 
|  | link_command = "$python_path gyp-win-tool link-wrapper $env False link.exe /nologo /OUT:{{output}} /PDB:{{output}}.pdb @$rspfile" | 
|  |  | 
|  | # TODO(brettw) support manifests | 
|  | #manifest_command = "$python_path gyp-win-tool manifest-wrapper $env mt.exe -nologo -manifest $manifests -out:{{output}}.manifest" | 
|  | #command = "cmd /c $link_command && $manifest_command" | 
|  | command = link_command | 
|  |  | 
|  | default_output_extension = ".exe" | 
|  | description = "LINK {{output}}" | 
|  | outputs = [ | 
|  | "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", | 
|  | ] | 
|  |  | 
|  | # The use of inputs_newline is to work around a fixed per-line buffer | 
|  | # size in the linker. | 
|  | rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" | 
|  | } | 
|  |  | 
|  | tool("stamp") { | 
|  | command = "$python_path gyp-win-tool stamp {{output}}" | 
|  | description = "STAMP {{output}}" | 
|  | } | 
|  |  | 
|  | tool("copy") { | 
|  | command = | 
|  | "$python_path gyp-win-tool recursive-mirror {{source}} {{output}}" | 
|  | description = "COPY {{source}} {{output}}" | 
|  | } | 
|  |  | 
|  | # When invoking this toolchain not as the default one, these args will be | 
|  | # passed to the build. They are ignored when this is the default toolchain. | 
|  | toolchain_args() { | 
|  | current_cpu = invoker.current_cpu | 
|  | if (defined(invoker.is_clang)) { | 
|  | is_clang = invoker.is_clang | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # TODO(dpranke): Declare both toolchains all of the time when we | 
|  | # get it sorted out how we want to support them both in a single build. | 
|  | # Right now only one of these can be enabled at a time because the | 
|  | # runtime libraries get copied to root_build_dir and would collide. | 
|  | if (current_cpu == "x86") { | 
|  | msvc_toolchain("x86") { | 
|  | environment = "environment.x86" | 
|  | current_cpu = "x86" | 
|  | cl = "${goma_prefix}\"${vc_bin_dir}/cl.exe\"" | 
|  | is_clang = false | 
|  | } | 
|  | msvc_toolchain("clang_x86") { | 
|  | environment = "environment.x86" | 
|  | current_cpu = "x86" | 
|  | prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin", | 
|  | root_build_dir) | 
|  | cl = "${goma_prefix}$prefix/clang-cl.exe" | 
|  | is_clang = true | 
|  | } | 
|  | } | 
|  |  | 
|  | if (current_cpu == "x64") { | 
|  | msvc_toolchain("x64") { | 
|  | environment = "environment.x64" | 
|  | current_cpu = "x64" | 
|  | cl = "${goma_prefix}\"${vc_bin_dir}/cl.exe\"" | 
|  | is_clang = false | 
|  | } | 
|  | msvc_toolchain("clang_x64") { | 
|  | environment = "environment.x64" | 
|  | current_cpu = "x64" | 
|  | prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin", | 
|  | root_build_dir) | 
|  | cl = "${goma_prefix}$prefix/clang-cl.exe" | 
|  | is_clang = true | 
|  | } | 
|  | } |