diff options
Diffstat (limited to 'deps/v8/build/toolchain/win/BUILD.gn')
-rw-r--r-- | deps/v8/build/toolchain/win/BUILD.gn | 496 |
1 files changed, 496 insertions, 0 deletions
diff --git a/deps/v8/build/toolchain/win/BUILD.gn b/deps/v8/build/toolchain/win/BUILD.gn new file mode 100644 index 0000000000..478a98774b --- /dev/null +++ b/deps/v8/build/toolchain/win/BUILD.gn @@ -0,0 +1,496 @@ +# 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. + +import("//build/config/clang/clang.gni") +import("//build/config/compiler/compiler.gni") +import("//build/config/sanitizers/sanitizers.gni") +import("//build/config/win/visual_studio_version.gni") +import("//build/toolchain/cc_wrapper.gni") +import("//build/toolchain/goma.gni") +import("//build/toolchain/toolchain.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. + +# This tool will is used as a wrapper for various commands below. +tool_wrapper_path = rebase_path("tool_wrapper.py", root_build_dir) + +if (use_goma) { + if (host_os == "win") { + goma_prefix = "$goma_dir/gomacc.exe " + } else { + goma_prefix = "$goma_dir/gomacc " + } + clang_prefix = goma_prefix +} else { + goma_prefix = "" + if (cc_wrapper != "") { + clang_prefix = cc_wrapper + " " + } else { + clang_prefix = "" + } +} + +# Copy the VS runtime DLL for the default toolchain to the root build directory +# so things will run. +if (current_toolchain == default_toolchain) { + if (is_debug) { + configuration_name = "Debug" + } else { + configuration_name = "Release" + } + exec_script("../../vs_toolchain.py", + [ + "copy_dlls", + rebase_path(root_build_dir), + configuration_name, + target_cpu, + ]) +} + +if (host_os == "win") { + clang_cl = "clang-cl.exe" +} else { + clang_cl = "clang-cl" +} + +# Parameters: +# environment: File name of environment file. +# +# You would also define a toolchain_args variable with at least these set: +# current_cpu: current_cpu to pass as a build arg +# current_os: current_os to pass as a build arg +template("msvc_toolchain") { + toolchain(target_name) { + # 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. + assert(defined(invoker.toolchain_args)) + toolchain_args = { + if (defined(invoker.toolchain_args)) { + forward_variables_from(invoker.toolchain_args, "*") + } + + # This value needs to be passed through unchanged. + host_toolchain = host_toolchain + } + + # Make these apply to all tools below. + lib_switch = "" + lib_dir_switch = "/LIBPATH:" + + # Object files go in this directory. + object_subdir = "{{target_out_dir}}/{{label_name}}" + + env = invoker.environment + + cl = invoker.cl + + if (use_lld) { + if (host_os == "win") { + lld_link = "lld-link.exe" + } else { + lld_link = "lld-link" + } + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + + # lld-link includes a replacement for lib.exe that can produce thin + # archives and understands bitcode (for lto builds). + lib = "$prefix/$lld_link /lib" + link = "$prefix/$lld_link" + if (host_os != "win") { + # See comment adding --rsp-quoting to $cl above for more information. + link = "$link --rsp-quoting=posix" + } + } else { + lib = "lib.exe" + link = "link.exe" + } + + # If possible, pass system includes as flags to the compiler. When that's + # not possible, load a full environment file (containing %INCLUDE% and + # %PATH%) -- e.g. 32-bit MSVS builds require %PATH% to be set and just + # passing in a list of include directories isn't enough. + if (defined(invoker.sys_include_flags)) { + env_wrapper = "" + sys_include_flags = "${invoker.sys_include_flags} " # Note trailing space. + } else { + # clang-cl doesn't need this env hoop, so omit it there. + assert((defined(toolchain_args.is_clang) && !toolchain_args.is_clang) || + !is_clang) + env_wrapper = "ninja -t msvc -e $env -- " # Note trailing space. + sys_include_flags = "" + } + + # ninja does not have -t msvc other than windows, and lld doesn't depend on + # mt.exe in PATH on non-Windows, so it's not needed there anyways. + if (defined(invoker.sys_lib_flags)) { + linker_wrapper = "" + sys_lib_flags = "${invoker.sys_lib_flags} " # Note trailing space + } else if (use_lld) { + # Invoke ninja as wrapper instead of tool wrapper, because python + # invocation requires higher cpu usage compared to ninja invocation, and + # the python wrapper is only needed to work around link.exe problems. + # TODO(thakis): Remove wrapper once lld-link can merge manifests without + # relying on mt.exe being in %PATH% on Windows, https://crbug.com/872740 + linker_wrapper = "ninja -t msvc -e $env -- " # Note trailing space. + sys_lib_flags = "" + } else { + linker_wrapper = + "$python_path $tool_wrapper_path link-wrapper $env False " # Note trailing space. + sys_lib_flags = "" + } + + tool("cc") { + precompiled_header_type = "msvc" + pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" + + # Label names may have spaces in them so the pdbname must be quoted. The + # source and output don't need to be quoted because GN knows they're a + # full file name and will quote automatically when necessary. + depsformat = "msvc" + description = "CC {{output}}" + outputs = [ + "$object_subdir/{{source_name_part}}.obj", + ] + + command = "$env_wrapper$cl /nologo /showIncludes $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" + } + + tool("cxx") { + precompiled_header_type = "msvc" + + # The PDB name needs to be different between C and C++ compiled files. + pdbname = "{{target_out_dir}}/{{label_name}}_cc.pdb" + + # See comment in CC tool about quoting. + depsformat = "msvc" + description = "CXX {{output}}" + outputs = [ + "$object_subdir/{{source_name_part}}.obj", + ] + + command = "$env_wrapper$cl /nologo /showIncludes $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" + } + + tool("rc") { + command = "$python_path $tool_wrapper_path rc-wrapper $env rc.exe /nologo {{defines}} {{include_dirs}} /fo{{output}} {{source}}" + depsformat = "msvc" + outputs = [ + "$object_subdir/{{source_name_part}}.res", + ] + description = "RC {{output}}" + } + + tool("asm") { + if (toolchain_args.current_cpu == "arm64") { + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + ml = "${clang_prefix}${prefix}/${clang_cl} --target=arm64-windows" + ml += " -c -o{{output}}" + } else { + if (toolchain_args.current_cpu == "x64") { + ml = "ml64.exe" + } else { + ml = "ml.exe" + } + ml += " /nologo /c /Fo{{output}}" + if (use_lld) { + # Wrap ml(64).exe with a script that makes its output deterministic. + # It's lld only because the script zaps obj Timestamp which + # link.exe /incremental looks at. + # TODO(https://crbug.com/762167): If we end up writing an llvm-ml64, + # make sure it has deterministic output (maybe with /Brepro or + # something) and remove this wrapper. + ml_py = rebase_path("ml.py", root_build_dir) + ml = "$python_path $ml_py $ml" + } + } + command = "$python_path $tool_wrapper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} {{source}}" + description = "ASM {{output}}" + outputs = [ + "$object_subdir/{{source_name_part}}.obj", + ] + } + + tool("alink") { + rspfile = "{{output}}.rsp" + command = "$linker_wrapper$lib /nologo ${sys_lib_flags}{{arflags}} /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. + "{{output_dir}}/{{target_output_name}}.lib", + ] + default_output_extension = ".lib" + default_output_dir = "{{target_out_dir}}" + + # 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 = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e.g. foo.dll + libname = "${dllname}.lib" # e.g. foo.dll.lib + pdbname = "${dllname}.pdb" + rspfile = "${dllname}.rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" + + command = "$linker_wrapper$link /nologo ${sys_lib_flags}/IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" + + default_output_extension = ".dll" + default_output_dir = "{{root_out_dir}}" + description = "LINK(DLL) {{output}}" + outputs = [ + dllname, + libname, + ] + link_output = libname + depend_output = libname + runtime_outputs = [ dllname ] + if (symbol_level != 0) { + outputs += [ pdbname ] + runtime_outputs += [ pdbname ] + } + + # Since the above commands only updates the .lib file when it changes, ask + # Ninja to check if the timestamp actually changed to know if downstream + # dependencies should be recompiled. + restat = true + + # 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("solink_module") { + dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e.g. foo.dll + pdbname = "${dllname}.pdb" + rspfile = "${dllname}.rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" + + command = "$linker_wrapper$link /nologo ${sys_lib_flags}/DLL /OUT:$dllname /PDB:$pdbname @$rspfile" + + default_output_extension = ".dll" + default_output_dir = "{{root_out_dir}}" + description = "LINK_MODULE(DLL) {{output}}" + outputs = [ + dllname, + ] + if (symbol_level != 0) { + outputs += [ pdbname ] + } + runtime_outputs = outputs + + # 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") { + exename = "{{output_dir}}/{{target_output_name}}{{output_extension}}" + pdbname = "$exename.pdb" + rspfile = "$exename.rsp" + pool = "//build/toolchain:link_pool($default_toolchain)" + + command = "$linker_wrapper$link /nologo ${sys_lib_flags}/OUT:$exename /PDB:$pdbname @$rspfile" + + default_output_extension = ".exe" + default_output_dir = "{{root_out_dir}}" + description = "LINK {{output}}" + outputs = [ + exename, + ] + if (symbol_level != 0) { + outputs += [ pdbname ] + } + runtime_outputs = outputs + + # 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}}" + } + + # These two are really entirely generic, but have to be repeated in + # each toolchain because GN doesn't allow a template to be used here. + # See //build/toolchain/toolchain.gni for details. + tool("stamp") { + command = stamp_command + description = stamp_description + pool = "//build/toolchain:action_pool($default_toolchain)" + } + tool("copy") { + command = copy_command + description = copy_description + pool = "//build/toolchain:action_pool($default_toolchain)" + } + + tool("action") { + pool = "//build/toolchain:action_pool($default_toolchain)" + } + } +} + +if (target_cpu == "x86" || target_cpu == "x64") { + win_build_host_cpu = target_cpu +} else { + win_build_host_cpu = host_cpu +} + +# x86, arm and arm64 build cpu toolchains for Windows (not WinUWP). Only +# define when the build cpu is one of these architectures since we don't +# do any cross compiles when targeting x64-bit (the build does generate +# some 64-bit stuff from x86/arm/arm64 target builds). +if (win_build_host_cpu != "x64") { + build_cpu_toolchain_data = exec_script("setup_toolchain.py", + [ + visual_studio_path, + windows_sdk_path, + visual_studio_runtime_dirs, + host_os, + win_build_host_cpu, + "environment." + win_build_host_cpu, + ], + "scope") + + msvc_toolchain(win_build_host_cpu) { + environment = "environment." + win_build_host_cpu + cl = "${goma_prefix}\"${build_cpu_toolchain_data.vc_bin_dir}/cl.exe\"" + if (host_os != "win") { + # For win cross build. + sys_lib_flags = "${build_cpu_toolchain_data.libpath_flags}" + } + toolchain_args = { + current_os = "win" + current_cpu = win_build_host_cpu + is_clang = false + } + } + + msvc_toolchain("win_clang_" + win_build_host_cpu) { + environment = "environment." + win_build_host_cpu + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + cl = "${clang_prefix}$prefix/${clang_cl}" + sys_include_flags = "${build_cpu_toolchain_data.include_flags_imsvc}" + if (host_os != "win") { + # For win cross build. + sys_lib_flags = "${build_cpu_toolchain_data.libpath_flags}" + } + + toolchain_args = { + current_os = "win" + current_cpu = win_build_host_cpu + is_clang = true + } + } +} + +# 64-bit toolchains, including x64 and arm64. +template("win_64bit_toolchains") { + assert(defined(invoker.toolchain_arch)) + toolchain_arch = invoker.toolchain_arch + + win_64bit_toolchain_data = exec_script("setup_toolchain.py", + [ + visual_studio_path, + windows_sdk_path, + visual_studio_runtime_dirs, + "win", + toolchain_arch, + "environment." + toolchain_arch, + ], + "scope") + + msvc_toolchain(target_name) { + environment = "environment." + toolchain_arch + cl = "${goma_prefix}\"${win_64bit_toolchain_data.vc_bin_dir}/cl.exe\"" + if (host_os != "win") { + # For win cross build + sys_lib_flags = "${win_64bit_toolchain_data.libpath_flags}" + } + + toolchain_args = { + if (defined(invoker.toolchain_args)) { + forward_variables_from(invoker.toolchain_args, "*") + } + is_clang = false + current_os = "win" + current_cpu = toolchain_arch + } + } + + msvc_toolchain("win_clang_" + target_name) { + environment = "environment." + toolchain_arch + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + cl = "${clang_prefix}$prefix/${clang_cl}" + sys_include_flags = "${win_64bit_toolchain_data.include_flags_imsvc}" + if (host_os != "win") { + # For win cross build + sys_lib_flags = "${win_64bit_toolchain_data.libpath_flags}" + } + + toolchain_args = { + if (defined(invoker.toolchain_args)) { + forward_variables_from(invoker.toolchain_args, "*") + } + is_clang = true + current_os = "win" + current_cpu = toolchain_arch + } + } +} + +win_64bit_toolchains("x64") { + toolchain_arch = "x64" +} + +if (target_cpu == "arm64") { + win_64bit_toolchains("arm64") { + toolchain_arch = "arm64" + } +} + +# The nacl_win64 toolchain is nearly identical to the plain x64 toolchain. +# It's used solely for building nacl64.exe (//components/nacl/broker:nacl64). +# The only reason it's a separate toolchain is so that it can force +# is_component_build to false in the toolchain_args() block, because +# building nacl64.exe in component style does not work. +win_64bit_toolchains("nacl_win64") { + toolchain_arch = "x64" + toolchain_args = { + is_component_build = false + } +} + +# WinUWP toolchains. Only define these when targeting them. + +if (target_os == "winuwp") { + assert(target_cpu == "x64" || target_cpu == "x86" || target_cpu == "arm" || + target_cpu == "arm64") + store_cpu_toolchain_data = exec_script("setup_toolchain.py", + [ + visual_studio_path, + windows_sdk_path, + visual_studio_runtime_dirs, + target_os, + target_cpu, + "environment.store_" + target_cpu, + ], + "scope") + + msvc_toolchain("uwp_" + target_cpu) { + environment = "environment.store_" + target_cpu + cl = "${goma_prefix}\"${store_cpu_toolchain_data.vc_bin_dir}/cl.exe\"" + toolchain_args = { + current_os = "winuwp" + current_cpu = target_cpu + is_clang = false + } + } +} |