Commit d5bf2062 authored by Tom Tan's avatar Tom Tan Committed by Commit Bot

Add Windows ARM64 support to Chromium build scripts.

This change mostly contains build script change under //chrome/build only.
It is targeting MSVC arm64 toolset, but enable clang-cl
could be based on this change.

Bug: 893460
Change-Id: Ia6f69f067a97fcaeb77021c1019bc594b0859eda
Reviewed-on: https://chromium-review.googlesource.com/c/1272076
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Reviewed-by: default avatarSteven Valdez <svaldez@chromium.org>
Reviewed-by: default avatarBruce Dawson <brucedawson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600083}
parent 5e4bcd0c
...@@ -140,7 +140,7 @@ ...@@ -140,7 +140,7 @@
#define ARCH_CPU_ARMEL 1 #define ARCH_CPU_ARMEL 1
#define ARCH_CPU_32_BITS 1 #define ARCH_CPU_32_BITS 1
#define ARCH_CPU_LITTLE_ENDIAN 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_ARM_FAMILY 1
#define ARCH_CPU_ARM64 1 #define ARCH_CPU_ARM64 1
#define ARCH_CPU_64_BITS 1 #define ARCH_CPU_64_BITS 1
......
...@@ -203,6 +203,7 @@ if (host_toolchain == "") { ...@@ -203,6 +203,7 @@ if (host_toolchain == "") {
} else if (host_os == "win") { } else if (host_os == "win") {
# On Windows always use the target CPU for host builds for x86/x64. On the # On Windows always use the target CPU for host builds for x86/x64. On the
# configurations we support this will always work and it saves build steps. # configurations we support this will always work and it saves build steps.
# Windows ARM64 targets require an x64 host for cross build.
if (target_cpu == "x86" || target_cpu == "x64") { if (target_cpu == "x86" || target_cpu == "x64") {
if (is_clang) { if (is_clang) {
host_toolchain = "//build/toolchain/win:win_clang_$target_cpu" host_toolchain = "//build/toolchain/win:win_clang_$target_cpu"
......
...@@ -1772,7 +1772,7 @@ config("no_size_t_to_int_warning") { ...@@ -1772,7 +1772,7 @@ config("no_size_t_to_int_warning") {
# Code that currently generates warnings for this can include this # Code that currently generates warnings for this can include this
# config to disable them. # config to disable them.
config("no_shorten_64_warnings") { config("no_shorten_64_warnings") {
if (current_cpu == "x64") { if (current_cpu == "x64" || current_cpu == "arm64") {
if (is_clang) { if (is_clang) {
cflags = [ "-Wno-shorten-64-to-32" ] cflags = [ "-Wno-shorten-64-to-32" ]
} else { } else {
......
...@@ -479,6 +479,9 @@ if (current_cpu == "x64") { ...@@ -479,6 +479,9 @@ if (current_cpu == "x64") {
# The number after the comma is the minimum required OS version. # The number after the comma is the minimum required OS version.
# 5.02 = Windows Server 2003. # 5.02 = Windows Server 2003.
subsystem_version_suffix = ",5.02" subsystem_version_suffix = ",5.02"
} else if (current_cpu == "arm64") {
# Windows ARM64 requires Windows 10.
subsystem_version_suffix = ",10.0"
} else { } else {
# 5.01 = Windows XP. # 5.01 = Windows XP.
subsystem_version_suffix = ",5.01" subsystem_version_suffix = ",5.01"
......
...@@ -49,6 +49,12 @@ if (current_toolchain == default_toolchain) { ...@@ -49,6 +49,12 @@ if (current_toolchain == default_toolchain) {
]) ])
} }
if (host_os == "win") {
clang_cl = "clang-cl.exe"
} else {
clang_cl = "clang-cl"
}
# Parameters: # Parameters:
# environment: File name of environment file. # environment: File name of environment file.
# #
...@@ -203,10 +209,18 @@ template("msvc_toolchain") { ...@@ -203,10 +209,18 @@ template("msvc_toolchain") {
tool("asm") { tool("asm") {
if (toolchain_args.current_cpu == "x64") { if (toolchain_args.current_cpu == "x64") {
ml = "ml64.exe" ml = "ml64.exe"
} else if (toolchain_args.current_cpu == "arm64") {
prefix = rebase_path("$clang_base_path/bin", root_build_dir)
ml = "${goma_prefix}${prefix}/${clang_cl} --target=arm64-windows"
} else { } else {
ml = "ml.exe" ml = "ml.exe"
} }
command = "$python_path $tool_wrapper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} /c /Fo{{output}} {{source}}" command = "$python_path $tool_wrapper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} "
if (toolchain_args.current_cpu == "arm64") {
command += "-c -o{{output}} {{source}}"
} else {
command += "/c /Fo{{output}} {{source}}"
}
description = "ASM {{output}}" description = "ASM {{output}}"
outputs = [ outputs = [
"$object_subdir/{{source_name_part}}.obj", "$object_subdir/{{source_name_part}}.obj",
...@@ -332,12 +346,6 @@ template("msvc_toolchain") { ...@@ -332,12 +346,6 @@ template("msvc_toolchain") {
} }
} }
if (host_os == "win") {
clang_cl = "clang-cl.exe"
} else {
clang_cl = "clang-cl"
}
if (target_cpu == "x86" || target_cpu == "x64") { if (target_cpu == "x86" || target_cpu == "x64") {
win_build_host_cpu = target_cpu win_build_host_cpu = target_cpu
} else { } else {
...@@ -392,25 +400,28 @@ if (win_build_host_cpu != "x64") { ...@@ -392,25 +400,28 @@ if (win_build_host_cpu != "x64") {
} }
} }
# 64-bit toolchains. # 64-bit toolchains, including x64 and arm64.
x64_toolchain_data = exec_script("setup_toolchain.py", template("win_64bit_toolchains") {
[ assert(defined(invoker.toolchain_arch))
visual_studio_path, toolchain_arch = invoker.toolchain_arch
windows_sdk_path,
visual_studio_runtime_dirs, win_64bit_toolchain_data = exec_script("setup_toolchain.py",
"win", [
"x64", visual_studio_path,
"environment.x64", windows_sdk_path,
], visual_studio_runtime_dirs,
"scope") "win",
toolchain_arch,
template("win_x64_toolchains") { "environment." + toolchain_arch,
],
"scope")
msvc_toolchain(target_name) { msvc_toolchain(target_name) {
environment = "environment.x64" environment = "environment." + toolchain_arch
cl = "${goma_prefix}\"${x64_toolchain_data.vc_bin_dir}/cl.exe\"" cl = "${goma_prefix}\"${win_64bit_toolchain_data.vc_bin_dir}/cl.exe\""
if (host_os != "win") { if (host_os != "win") {
# For win cross build # For win cross build
sys_lib_flags = "${x64_toolchain_data.libpath_flags}" sys_lib_flags = "${win_64bit_toolchain_data.libpath_flags}"
} }
toolchain_args = { toolchain_args = {
...@@ -419,18 +430,18 @@ template("win_x64_toolchains") { ...@@ -419,18 +430,18 @@ template("win_x64_toolchains") {
} }
is_clang = false is_clang = false
current_os = "win" current_os = "win"
current_cpu = "x64" current_cpu = toolchain_arch
} }
} }
msvc_toolchain("win_clang_" + target_name) { msvc_toolchain("win_clang_" + target_name) {
environment = "environment.x64" environment = "environment." + toolchain_arch
prefix = rebase_path("$clang_base_path/bin", root_build_dir) prefix = rebase_path("$clang_base_path/bin", root_build_dir)
cl = "${goma_prefix}$prefix/${clang_cl}" cl = "${goma_prefix}$prefix/${clang_cl}"
sys_include_flags = "${x64_toolchain_data.include_flags_imsvc}" sys_include_flags = "${win_64bit_toolchain_data.include_flags_imsvc}"
if (host_os != "win") { if (host_os != "win") {
# For win cross build # For win cross build
sys_lib_flags = "${x64_toolchain_data.libpath_flags}" sys_lib_flags = "${win_64bit_toolchain_data.libpath_flags}"
} }
toolchain_args = { toolchain_args = {
...@@ -439,23 +450,34 @@ template("win_x64_toolchains") { ...@@ -439,23 +450,34 @@ template("win_x64_toolchains") {
} }
is_clang = true is_clang = true
current_os = "win" current_os = "win"
current_cpu = "x64" current_cpu = toolchain_arch
} }
} }
} }
win_x64_toolchains("x64") { win_64bit_toolchains("x64") {
toolchain_arch = "x64"
toolchain_args = { toolchain_args = {
# Use the defaults. # Use the defaults.
} }
} }
if (target_cpu == "arm64") {
win_64bit_toolchains("arm64") {
toolchain_arch = "arm64"
toolchain_args = {
# Use the defaults.
}
}
}
# The nacl_win64 toolchain is nearly identical to the plain x64 toolchain. # The nacl_win64 toolchain is nearly identical to the plain x64 toolchain.
# It's used solely for building nacl64.exe (//components/nacl/broker:nacl64). # 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 # 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 # is_component_build to false in the toolchain_args() block, because
# building nacl64.exe in component style does not work. # building nacl64.exe in component style does not work.
win_x64_toolchains("nacl_win64") { win_64bit_toolchains("nacl_win64") {
toolchain_arch = "x64"
toolchain_args = { toolchain_args = {
is_component_build = false is_component_build = false
} }
......
...@@ -77,6 +77,9 @@ template("midl") { ...@@ -77,6 +77,9 @@ template("midl") {
} else if (current_cpu == "x64") { } else if (current_cpu == "x64") {
win_tool_arch = "environment.x64" win_tool_arch = "environment.x64"
idl_target_platform = "x64" idl_target_platform = "x64"
} else if (current_cpu == "arm64") {
win_tool_arch = "environment.arm64"
idl_target_platform = "arm64"
} else { } else {
assert(false, "Need environment for this arch") assert(false, "Need environment for this arch")
} }
......
...@@ -168,6 +168,11 @@ class WinTool(object): ...@@ -168,6 +168,11 @@ class WinTool(object):
def ExecAsmWrapper(self, arch, *args): def ExecAsmWrapper(self, arch, *args):
"""Filter logo banner from invocations of asm.exe.""" """Filter logo banner from invocations of asm.exe."""
env = self._GetEnv(arch) env = self._GetEnv(arch)
if sys.platform == 'win32':
# Windows ARM64 uses clang-cl as assembler which has '/' as path
# separator, convert it to '\\' when running on Windows.
args = list(args) # *args is a tuple by default, which is read-only
args[0] = args[0].replace('/', '\\')
popen = subprocess.Popen(args, shell=True, env=env, popen = subprocess.Popen(args, shell=True, env=env,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = popen.communicate() out, _ = popen.communicate()
......
...@@ -238,6 +238,7 @@ def _CopyPGORuntime(target_dir, target_cpu): ...@@ -238,6 +238,7 @@ def _CopyPGORuntime(target_dir, target_cpu):
# from HostX86/x86. # from HostX86/x86.
pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86') pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86')
pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64') pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64')
pgo_arm64_runtime_dir = os.path.join(pgo_runtime_root, 'arm64')
else: else:
raise Exception('Unexpected toolchain version: %s.' % env_version) raise Exception('Unexpected toolchain version: %s.' % env_version)
...@@ -250,6 +251,8 @@ def _CopyPGORuntime(target_dir, target_cpu): ...@@ -250,6 +251,8 @@ def _CopyPGORuntime(target_dir, target_cpu):
source = os.path.join(pgo_x86_runtime_dir, runtime) source = os.path.join(pgo_x86_runtime_dir, runtime)
elif target_cpu == 'x64': elif target_cpu == 'x64':
source = os.path.join(pgo_x64_runtime_dir, runtime) source = os.path.join(pgo_x64_runtime_dir, runtime)
elif target_cpu == 'arm64':
source = os.path.join(pgo_arm64_runtime_dir, runtime)
else: else:
raise NotImplementedError("Unexpected target_cpu value: " + target_cpu) raise NotImplementedError("Unexpected target_cpu value: " + target_cpu)
if not os.path.exists(source): if not os.path.exists(source):
......
...@@ -36,7 +36,7 @@ def reorder_imports(input_dir, output_dir, architecture): ...@@ -36,7 +36,7 @@ def reorder_imports(input_dir, output_dir, architecture):
# through the Structure, while other data must bet set through # through the Structure, while other data must bet set through
# the set_bytes_*() methods. # the set_bytes_*() methods.
pe = pefile.PE(input_image, fast_load=True) pe = pefile.PE(input_image, fast_load=True)
if architecture == 'x64': if architecture == 'x64' or architecture == 'arm64':
assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS
else: else:
assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE
......
...@@ -49,7 +49,8 @@ all_headers = crypto_headers + ssl_headers ...@@ -49,7 +49,8 @@ all_headers = crypto_headers + ssl_headers
# Windows' assembly is built with Yasm. The other platforms use the platform # Windows' assembly is built with Yasm. The other platforms use the platform
# assembler. # assembler.
if (is_win && !is_msan) { # Exclude Yasm for Windows ARM64 because Yasm targets to x86 and x64 only.
if (is_win && !is_msan && current_cpu != "arm64") {
import("//third_party/yasm/yasm_assemble.gni") import("//third_party/yasm/yasm_assemble.gni")
yasm_assemble("boringssl_asm") { yasm_assemble("boringssl_asm") {
if (current_cpu == "x64") { if (current_cpu == "x64") {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment