Rework vs_toolchain.py and vs_env.py.
Chromium's VS toolchains now maintain JSON files with the expected
environment, so we don't need to pull in gyp to figure out the batch
file to run. This drops a long obsolete dependency and will make it
possible to handle other VS architectures. (gyp internally only handled
x86 and x64.)
Also trim away the logic in vs_toolchain.py to account for
non-depot_tools toolchains. Unlike Chromium, we don't use these scripts
outside of CI/CQ.
Change-Id: I2c9fddac52eef7b4895731d78c637fdcf9c85033
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/43504
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/.gitignore b/.gitignore
index 8ce23d1..83a64740 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,6 @@
util/bot/cmake-win32
util/bot/cmake-win32.zip
util/bot/golang
-util/bot/gyp
util/bot/libcxx
util/bot/libcxxabi
util/bot/llvm-build
diff --git a/util/bot/DEPS b/util/bot/DEPS
index 8fe7b35..8544fe9 100644
--- a/util/bot/DEPS
+++ b/util/bot/DEPS
@@ -40,9 +40,6 @@
'dep_type': 'cipd',
},
- 'boringssl/util/bot/gyp':
- Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb',
-
'boringssl/util/bot/libFuzzer': {
'url': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git' +'@' + 'debe7d2d1982e540fbd6bd78604bf001753f9e74',
'condition': 'checkout_fuzzer',
diff --git a/util/bot/vs_env.py b/util/bot/vs_env.py
index 1847500..13217ca 100644
--- a/util/bot/vs_env.py
+++ b/util/bot/vs_env.py
@@ -16,8 +16,6 @@
import sys
import vs_toolchain
-# vs_toolchain adds gyp to sys.path.
-import gyp.MSVSVersion
if len(sys.argv) < 2:
print >>sys.stderr, "Usage: vs_env.py TARGET_ARCH CMD..."
@@ -26,12 +24,5 @@
target_arch = sys.argv[1]
cmd = sys.argv[2:]
-vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
-vs_version = gyp.MSVSVersion.SelectVisualStudioVersion()
-
-# Using shell=True is somewhat ugly, but the alternative is to pull in a copy
-# of the Chromium GN build's setup_toolchain.py which runs the setup script,
-# then 'set', and then parses the environment variables out. (GYP internally
-# does the same thing.)
-sys.exit(subprocess.call(vs_version.SetupScript(target_arch) + ["&&"] + cmd,
- shell=True))
+vs_toolchain.SetEnvironmentForCPU(target_arch)
+sys.exit(subprocess.call(cmd))
diff --git a/util/bot/vs_toolchain.py b/util/bot/vs_toolchain.py
index eb3e049..6e94df3 100644
--- a/util/bot/vs_toolchain.py
+++ b/util/bot/vs_toolchain.py
@@ -4,65 +4,54 @@
import json
import os
-import pipes
-import shutil
+import os.path
import subprocess
import sys
script_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.insert(0, os.path.join(script_dir, 'gyp', 'pylib'))
json_data_file = os.path.join(script_dir, 'win_toolchain.json')
-import gyp
-
-
# Use MSVS2015 as the default toolchain.
CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2015'
-def SetEnvironmentAndGetRuntimeDllDirs():
- """Sets up os.environ to use the depot_tools VS toolchain with gyp, and
- returns the location of the VS runtime DLLs so they can be copied into
- the output directory after gyp generation.
- """
- vs_runtime_dll_dirs = None
- depot_tools_win_toolchain = \
- bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
- if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
- if not os.path.exists(json_data_file):
- Update()
- with open(json_data_file, 'r') as tempf:
- toolchain_data = json.load(tempf)
+def SetEnvironmentForCPU(cpu):
+ """Sets the environment to build with the selected toolchain for |cpu|."""
+ with open(json_data_file, 'r') as tempf:
+ toolchain_data = json.load(tempf)
+ sdk_dir = toolchain_data['win_sdk']
+ os.environ['WINDOWSSDKDIR'] = sdk_dir
+ os.environ['WDK_DIR'] = toolchain_data['wdk']
+ # Include the VS runtime in the PATH in case it's not machine-installed.
+ vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
+ runtime_path = os.pathsep.join(vs_runtime_dll_dirs)
+ os.environ['PATH'] = runtime_path + os.pathsep + os.environ['PATH']
- toolchain = toolchain_data['path']
- version = toolchain_data['version']
- win_sdk = toolchain_data.get('win_sdk')
- if not win_sdk:
- win_sdk = toolchain_data['win8sdk']
- wdk = toolchain_data['wdk']
- # TODO(scottmg): The order unfortunately matters in these. They should be
- # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
- # below). http://crbug.com/345992
- vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
+ # Set up the architecture-specific environment from the SetEnv files. See
+ # _LoadToolchainEnv() from setup_toolchain.py in Chromium.
+ assert cpu in ('x86', 'x64', 'arm', 'arm64')
+ with open(os.path.join(sdk_dir, 'bin', 'SetEnv.%s.json' % cpu)) as f:
+ env = json.load(f)['env']
+ if env['VSINSTALLDIR'] == [["..", "..\\"]]:
+ # Old-style paths were relative to the win_sdk\bin directory.
+ json_relative_dir = os.path.join(sdk_dir, 'bin')
+ else:
+ # New-style paths are relative to the toolchain directory, which is the
+ # parent of the SDK directory.
+ json_relative_dir = os.path.split(sdk_dir)[0]
+ for k in env:
+ entries = [os.path.join(*([json_relative_dir] + e)) for e in env[k]]
+ # clang-cl wants INCLUDE to be ;-separated even on non-Windows,
+ # lld-link wants LIB to be ;-separated even on non-Windows. Path gets :.
+ sep = os.pathsep if k == 'PATH' else ';'
+ env[k] = sep.join(entries)
+ # PATH is a bit of a special case, it's in addition to the current PATH.
+ env['PATH'] = env['PATH'] + os.pathsep + os.environ['PATH']
- os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
- os.environ['GYP_MSVS_VERSION'] = version
- # We need to make sure windows_sdk_path is set to the automated
- # toolchain values in GYP_DEFINES, but don't want to override any
- # otheroptions.express
- # values there.
- gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
- gyp_defines_dict['windows_sdk_path'] = win_sdk
- os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
- for k, v in gyp_defines_dict.iteritems())
- os.environ['WINDOWSSDKDIR'] = win_sdk
- os.environ['WDK_DIR'] = wdk
- # Include the VS runtime in the PATH in case it's not machine-installed.
- runtime_path = ';'.join(vs_runtime_dll_dirs)
- os.environ['PATH'] = runtime_path + ';' + os.environ['PATH']
- return vs_runtime_dll_dirs
+ for k, v in env.items():
+ os.environ[k] = v
def FindDepotTools():
@@ -76,6 +65,8 @@
def GetVisualStudioVersion():
"""Return GYP_MSVS_VERSION of Visual Studio.
"""
+ # TODO(davidben): Replace this with a command-line argument. The depot_tools
+ # script no longer needs this environment variable.
return os.environ.get('GYP_MSVS_VERSION', CURRENT_DEFAULT_TOOLCHAIN_VERSION)
@@ -97,24 +88,18 @@
def Update():
"""Requests an update of the toolchain to the specific hashes we have at
this revision. The update outputs a .json of the various configuration
- information required to pass to gyp which we use in |GetToolchainDir()|.
+ information required to pass to vs_env.py which we use in
+ |SetEnvironmentForCPU()|.
"""
- depot_tools_win_toolchain = \
- bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
- if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
- depot_tools_path = FindDepotTools()
- # Necessary so that get_toolchain_if_necessary.py will put the VS toolkit
- # in the correct directory.
- os.environ['GYP_MSVS_VERSION'] = GetVisualStudioVersion()
- get_toolchain_args = [
- sys.executable,
- os.path.join(depot_tools_path,
- 'win_toolchain',
- 'get_toolchain_if_necessary.py'),
- '--output-json', json_data_file,
- ] + _GetDesiredVsToolchainHashes()
- subprocess.check_call(get_toolchain_args)
-
+ depot_tools_path = FindDepotTools()
+ get_toolchain_args = [
+ sys.executable,
+ os.path.join(depot_tools_path,
+ 'win_toolchain',
+ 'get_toolchain_if_necessary.py'),
+ '--output-json', json_data_file,
+ ] + _GetDesiredVsToolchainHashes()
+ subprocess.check_call(get_toolchain_args)
return 0