diff --git a/build/build_config.h b/build/build_config.h index d8c3db6ed7..f12d9b612f 100644 --- a/build/build_config.h +++ b/build/build_config.h @@ -73,8 +73,8 @@ // For access to standard POSIXish features, use OS_POSIX instead of a // more specific macro. -#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_FREEBSD) || \ - defined(OS_OPENBSD) || defined(OS_SOLARIS) || defined(OS_ANDROID) || \ +#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_FREEBSD) || \ + defined(OS_OPENBSD) || defined(OS_SOLARIS) || defined(OS_ANDROID) || \ defined(OS_NACL) || defined(OS_QNX) #define OS_POSIX 1 #endif @@ -113,7 +113,7 @@ #define ARCH_CPU_ARMEL 1 #define ARCH_CPU_32_BITS 1 #define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__aarch64__) +#elif defined(__aarch64__) || defined(_M_ARM64) #define ARCH_CPU_ARM_FAMILY 1 #define ARCH_CPU_ARM64 1 #define ARCH_CPU_64_BITS 1 @@ -140,12 +140,10 @@ // Type detection for wchar_t. #if defined(OS_WIN) #define WCHAR_T_IS_UTF16 -#elif defined(OS_POSIX) && defined(COMPILER_GCC) && \ - defined(__WCHAR_MAX__) && \ +#elif defined(OS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \ (__WCHAR_MAX__ == 0x7fffffff || __WCHAR_MAX__ == 0xffffffff) #define WCHAR_T_IS_UTF32 -#elif defined(OS_POSIX) && defined(COMPILER_GCC) && \ - defined(__WCHAR_MAX__) && \ +#elif defined(OS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \ (__WCHAR_MAX__ == 0x7fff || __WCHAR_MAX__ == 0xffff) // On Posix, we'll detect short wchar_t, but projects aren't guaranteed to // compile in this mode (in particular, Chrome doesn't). This is intended for diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index ce3d6eade2..3a316b36a2 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -494,13 +494,12 @@ if (custom_toolchain != "") { set_default_toolchain("//build/toolchain/custom") } else if (is_win) { if (is_clang) { - host_toolchain = "//build/toolchain/win:clang_$current_cpu" + host_toolchain = "//build/toolchain/win:clang_$host_cpu" + set_default_toolchain("//build/toolchain/win:clang_$current_cpu") } else { - host_toolchain = "//build/toolchain/win:$current_cpu" + host_toolchain = "//build/toolchain/win:$host_cpu" + set_default_toolchain("//build/toolchain/win:$current_cpu") } - - # On windows we use the same toolchain for host and target by default. - set_default_toolchain("$host_toolchain") } else if (is_android) { if (host_os == "linux") { # Use clang for the x86/64 Linux host builds. diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 4f3544f93e..d8abe68d50 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -301,6 +301,18 @@ config("compiler") { "_LARGEFILE64_SOURCE", ] } + } else if (is_win) { + if (is_clang) { + if (current_cpu == "x86") { + cflags += [ "-m32" ] + } else if (current_cpu == "x64") { + cflags += [ "-m64" ] + } else if (current_cpu == "arm64") { + cflags += [ "--target=arm64-windows" ] + } else { + assert(false, "unknown current_cpu " + current_cpu) + } + } } if (operator_new_alignment != "default" && is_clang) { diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn index 261a1ac4de..db29dbbe2b 100644 --- a/build/config/win/BUILD.gn +++ b/build/config/win/BUILD.gn @@ -41,7 +41,7 @@ config("sdk_link") { "$visual_studio_path\VC\lib\amd64", "$visual_studio_path\VC\atlmfc\lib\amd64", ] - } else { + } else if (current_cpu == "x86") { ldflags = [ "/MACHINE:X86", "/SAFESEH", # Not compatible with x64 so use only for x86. @@ -54,6 +54,15 @@ config("sdk_link") { if (!is_asan) { ldflags += [ "/largeaddressaware" ] } + } else if (current_cpu == "arm64") { + ldflags = [ "/MACHINE:ARM64" ] + lib_dirs = [ + "$windows_sdk_path\Lib\winv6.3\um\arm64", + "$visual_studio_path\VC\lib\arm64", + "$visual_studio_path\VC\atlmfc\lib\arm64", + ] + } else { + assert(false, "Unsupported CPU type") } } @@ -102,6 +111,9 @@ if (current_cpu == "x64") { # The number after the comma is the minimum required OS version. # 5.02 = Windows Server 2003. subsystem_version_suffix = ",5.02" +} else if (current_cpu == "arm64") { + # Windows ARM64 requires Windows 10. + subsystem_version_suffix = ",10.0" } else { # 5.01 = Windows XP. subsystem_version_suffix = ",5.01" diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index b9f0f3946e..ecb8d9e3fe 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +default_clang_base_path = "//third_party/llvm-build/Release+Asserts" + declare_args() { # Path to the directory containing the VC binaries for the right # combination of host and target architectures. Currently only the @@ -9,6 +11,9 @@ declare_args() { # 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 = "" + + # Path to the clang toolchain. + clang_base_path = default_clang_base_path } import("//build/config/win/visual_studio_version.gni") @@ -45,12 +50,7 @@ if (use_goma) { goma_prefix = "" } -# Parameters: -# current_cpu: current_cpu to pass as a build arg -# environment: File name of environment file. -template("msvc_toolchain") { - env = invoker.environment - +if (current_toolchain == default_toolchain) { if (is_debug) { configuration = "Debug" } else { @@ -61,12 +61,29 @@ template("msvc_toolchain") { "copy_dlls", rebase_path(root_build_dir), configuration, - invoker.current_cpu, + target_cpu, ]) +} - cl = invoker.cl - +# Parameters: +# toolchain_args: Settings for the toolchain, including at least: +# current_cpu: current_cpu to pass as a build arg +# environment: File name of environment file. +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, "*") + } + } + + env = invoker.environment + + cl = invoker.cl + # Make these apply to all tools below. lib_switch = "" lib_dir_switch = "/LIBPATH:" @@ -77,11 +94,7 @@ template("msvc_toolchain") { # 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" - flags = "" - if (is_clang && invoker.current_cpu == "x86") { - flags = "-m32" - } - command = "ninja -t msvc -e $env -- $cl $flags /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname" + command = "ninja -t msvc -e $env -- $cl /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd$pdbname" depsformat = "msvc" description = "CC {{output}}" outputs = [ @@ -120,16 +133,25 @@ template("msvc_toolchain") { } tool("asm") { - # TODO(brettw): "/safeseh" assembler argument is hardcoded here. Extract - # assembler flags to a variable like cflags. crbug.com/418613 - if (invoker.current_cpu == "x64") { + is_msvc_assembler = true + if (toolchain_args.current_cpu == "x64") { ml = "ml64.exe" x64 = "-D_ML64_X64" + } else if (toolchain_args.current_cpu == "arm64") { + is_msvc_assembler = false + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + ml = "${goma_prefix}${prefix}/clang_cl.exe --target=arm64-windows" + x64 = "" } else { ml = "ml.exe" x64 = "" } - command = "$python_path gyp-win-tool asm-wrapper $env $ml $x64 {{defines}} {{include_dirs}} {{asmflags}} /safeseh /c /Fo {{output}} {{source}}" + command = "$python_path gyp-win-tool asm-wrapper $env $ml $x64 {{defines}} {{include_dirs}} {{asmflags}} " + if (is_msvc_assembler) { + command += "-c -o{{output}} {{source}}" + } else { + command += "/c /Fo{{output}} {{source}}" + } outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj", ] @@ -217,52 +239,55 @@ template("msvc_toolchain") { "$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. +template("win_toolchains") { + assert(defined(invoker.toolchain_arch)) + toolchain_arch = invoker.toolchain_arch + + msvc_toolchain(target_name) { + environment = "environment." + toolchain_arch + cl = "${goma_prefix}\"${vc_bin_dir}/cl.exe\"" toolchain_args = { - current_cpu = invoker.current_cpu - if (defined(invoker.is_clang)) { - is_clang = invoker.is_clang + if (defined(invoker.toolchain_args)) { + forward_variables_from(invoker.toolchain_args, "*") } + current_cpu = toolchain_arch + is_clang = false + } + } + msvc_toolchain("clang_" + target_name) { + environment = "environment." + toolchain_arch + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + cl = "${goma_prefix}$prefix/clang-cl.exe" + toolchain_args = { + if (defined(invoker.toolchain_args)) { + forward_variables_from(invoker.toolchain_args, "*") + } + current_cpu = toolchain_arch + is_clang = true } } } -# 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 +if (target_cpu == "x86") { + win_toolchains("x86") { + toolchain_arch = "x86" } - 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 (target_cpu == "x64") { + win_toolchains("x64") { + toolchain_arch = "x64" } } -if (current_cpu == "x64") { - msvc_toolchain("x64") { - environment = "environment.x64" - current_cpu = "x64" - cl = "${goma_prefix}\"${vc_bin_dir}/cl.exe\"" - is_clang = false +if (target_cpu == "arm64") { + win_toolchains("arm64") { + toolchain_arch = "arm64" } - 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 + win_toolchains(host_cpu) { + toolchain_arch = host_cpu } } diff --git a/build/toolchain/win/midl.gni b/build/toolchain/win/midl.gni index 3e7fbecca5..4110cd1781 100644 --- a/build/toolchain/win/midl.gni +++ b/build/toolchain/win/midl.gni @@ -63,6 +63,9 @@ template("midl") { } else if (current_cpu == "x64") { win_tool_arch = "environment.x64" idl_target_platform = "x64" + } else if (current_cpu == "arm64") { + win_tool_arch = "environment.arm64" + idl_target_platform = "arm64" } else { assert(false, "Need environment for this arch") } diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py index 2aae35403c..8c26112b41 100644 --- a/build/toolchain/win/setup_toolchain.py +++ b/build/toolchain/win/setup_toolchain.py @@ -55,9 +55,8 @@ def _SetupScript(target_cpu, sdk_dir): """Returns a command (with arguments) to be used to set up the environment.""" # Check if we are running in the SDK command line environment and use - # the setup script from the SDK if so. |target_cpu| should be either - # 'x86' or 'x64'. - assert target_cpu in ('x86', 'x64') + # the setup script from the SDK if so. + assert target_cpu in ('x86', 'x64', 'arm64') if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir: return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')), '/' + target_cpu] @@ -109,7 +108,7 @@ def main(): _CopyTool(tool_source) - cpus = ('x86', 'x64') + cpus = ('x86', 'x64', 'arm64') assert target_cpu in cpus vc_bin_dir = ''