blob: e131a0db2b428084884a72ac7caaca4ddb378a1d [file] [log] [blame]
thakis79870e22015-08-12 07:25:00 +09001#!/usr/bin/env python
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +09002# Copyright 2014 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
brucedawsondf9e2772016-02-09 13:27:52 +09006import glob
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +09007import json
8import os
9import pipes
brucedawson815cd432016-06-02 03:37:18 +090010import platform
sebmarchand3a2260f2017-05-13 00:29:26 +090011import re
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090012import shutil
brucedawson815cd432016-06-02 03:37:18 +090013import stat
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090014import subprocess
15import sys
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090016
17
18script_dir = os.path.dirname(os.path.realpath(__file__))
19chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir))
20SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090021sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib'))
scottmg@chromium.orgf867a392014-04-09 10:56:20 +090022json_data_file = os.path.join(script_dir, 'win_toolchain.json')
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090023
24
thakisa033c402017-05-30 00:14:30 +090025# Use MSVS2015 as the default toolchain.
brucedawsoncf20a852017-06-19 08:25:50 +090026CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2015'
sebmarchandd84a2ff2016-01-16 07:29:57 +090027
28
scottmg@chromium.orgf867a392014-04-09 10:56:20 +090029def SetEnvironmentAndGetRuntimeDllDirs():
30 """Sets up os.environ to use the depot_tools VS toolchain with gyp, and
31 returns the location of the VS runtime DLLs so they can be copied into
32 the output directory after gyp generation.
brucedawson815cd432016-06-02 03:37:18 +090033
34 Return value is [x64path, x86path] or None
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090035 """
brucedawson0db1b9b2015-11-21 11:21:52 +090036 vs_runtime_dll_dirs = None
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090037 depot_tools_win_toolchain = \
38 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
thakis79870e22015-08-12 07:25:00 +090039 # When running on a non-Windows host, only do this if the SDK has explicitly
40 # been downloaded before (in which case json_data_file will exist).
scottmg3e191762015-08-26 08:03:35 +090041 if ((sys.platform in ('win32', 'cygwin') or os.path.exists(json_data_file))
42 and depot_tools_win_toolchain):
sebmarchandd84a2ff2016-01-16 07:29:57 +090043 if ShouldUpdateToolchain():
scottmg@chromium.org2f8c83b2014-08-14 23:03:30 +090044 Update()
scottmg@chromium.orgf867a392014-04-09 10:56:20 +090045 with open(json_data_file, 'r') as tempf:
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090046 toolchain_data = json.load(tempf)
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090047
48 toolchain = toolchain_data['path']
49 version = toolchain_data['version']
scottmg73c1e862015-06-02 10:15:44 +090050 win_sdk = toolchain_data.get('win_sdk')
51 if not win_sdk:
52 win_sdk = toolchain_data['win8sdk']
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090053 wdk = toolchain_data['wdk']
54 # TODO(scottmg): The order unfortunately matters in these. They should be
sebmarchand3a2260f2017-05-13 00:29:26 +090055 # split into separate keys for x86 and x64. (See CopyDlls call below).
56 # http://crbug.com/345992
brucedawson0db1b9b2015-11-21 11:21:52 +090057 vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090058
59 os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
60 os.environ['GYP_MSVS_VERSION'] = version
thestig85803602017-03-11 10:46:42 +090061
62 # Limit the scope of the gyp import to only where it is used. This
63 # potentially lets build configs that never execute this block to drop
64 # their GYP checkout.
65 import gyp
66
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090067 # We need to make sure windows_sdk_path is set to the automated
68 # toolchain values in GYP_DEFINES, but don't want to override any
69 # otheroptions.express
70 # values there.
71 gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
scottmg73c1e862015-06-02 10:15:44 +090072 gyp_defines_dict['windows_sdk_path'] = win_sdk
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090073 os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
74 for k, v in gyp_defines_dict.iteritems())
thestig85803602017-03-11 10:46:42 +090075
scottmg73c1e862015-06-02 10:15:44 +090076 os.environ['WINDOWSSDKDIR'] = win_sdk
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090077 os.environ['WDK_DIR'] = wdk
78 # Include the VS runtime in the PATH in case it's not machine-installed.
thakisfe3b08a2016-02-16 03:18:01 +090079 runtime_path = os.path.pathsep.join(vs_runtime_dll_dirs)
80 os.environ['PATH'] = runtime_path + os.path.pathsep + os.environ['PATH']
bratell58b9a562016-01-08 01:30:12 +090081 elif sys.platform == 'win32' and not depot_tools_win_toolchain:
82 if not 'GYP_MSVS_OVERRIDE_PATH' in os.environ:
83 os.environ['GYP_MSVS_OVERRIDE_PATH'] = DetectVisualStudioPath()
lwchkgbc6ee722016-01-19 09:39:08 +090084 if not 'GYP_MSVS_VERSION' in os.environ:
85 os.environ['GYP_MSVS_VERSION'] = GetVisualStudioVersion()
bratell58b9a562016-01-08 01:30:12 +090086
brucedawson815cd432016-06-02 03:37:18 +090087 # When using an installed toolchain these files aren't needed in the output
88 # directory in order to run binaries locally, but they are needed in order
89 # to create isolates or the mini_installer. Copying them to the output
90 # directory ensures that they are available when needed.
91 bitness = platform.architecture()[0]
92 # When running 64-bit python the x64 DLLs will be in System32
93 x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
94 x64_path = os.path.join(r'C:\Windows', x64_path)
95 vs_runtime_dll_dirs = [x64_path, r'C:\Windows\SysWOW64']
96
brucedawson0db1b9b2015-11-21 11:21:52 +090097 return vs_runtime_dll_dirs
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +090098
99
bratell58b9a562016-01-08 01:30:12 +0900100def _RegistryGetValueUsingWinReg(key, value):
101 """Use the _winreg module to obtain the value of a registry key.
102
103 Args:
104 key: The registry key.
105 value: The particular registry value to read.
106 Return:
107 contents of the registry key's value, or None on failure. Throws
108 ImportError if _winreg is unavailable.
109 """
110 import _winreg
111 try:
112 root, subkey = key.split('\\', 1)
113 assert root == 'HKLM' # Only need HKLM for now.
114 with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey:
115 return _winreg.QueryValueEx(hkey, value)[0]
116 except WindowsError:
117 return None
118
119
120def _RegistryGetValue(key, value):
121 try:
122 return _RegistryGetValueUsingWinReg(key, value)
123 except ImportError:
124 raise Exception('The python library _winreg not found.')
125
126
halton.huo08f76172016-01-13 11:23:30 +0900127def GetVisualStudioVersion():
sebmarchandd84a2ff2016-01-16 07:29:57 +0900128 """Return GYP_MSVS_VERSION of Visual Studio.
halton.huo08f76172016-01-13 11:23:30 +0900129 """
sebmarchandd84a2ff2016-01-16 07:29:57 +0900130 return os.environ.get('GYP_MSVS_VERSION', CURRENT_DEFAULT_TOOLCHAIN_VERSION)
halton.huo08f76172016-01-13 11:23:30 +0900131
132
bratell58b9a562016-01-08 01:30:12 +0900133def DetectVisualStudioPath():
134 """Return path to the GYP_MSVS_VERSION of Visual Studio.
135 """
136
137 # Note that this code is used from
138 # build/toolchain/win/setup_toolchain.py as well.
halton.huo08f76172016-01-13 11:23:30 +0900139 version_as_year = GetVisualStudioVersion()
bratell58b9a562016-01-08 01:30:12 +0900140 year_to_version = {
bratell58b9a562016-01-08 01:30:12 +0900141 '2015': '14.0',
brucedawson8cb1a642017-01-23 15:57:21 +0900142 '2017': '15.0',
bratell58b9a562016-01-08 01:30:12 +0900143 }
144 if version_as_year not in year_to_version:
145 raise Exception(('Visual Studio version %s (from GYP_MSVS_VERSION)'
146 ' not supported. Supported versions are: %s') % (
147 version_as_year, ', '.join(year_to_version.keys())))
148 version = year_to_version[version_as_year]
brucedawson8cb1a642017-01-23 15:57:21 +0900149 if version_as_year == '2017':
150 # The VC++ 2017 install location needs to be located using COM instead of
151 # the registry. For details see:
152 # https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/
153 # For now we use a hardcoded default with an environment variable override.
drbasic49ee1232017-04-14 11:13:01 +0900154 for path in (
155 os.environ.get('vs2017_install'),
156 r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional',
157 r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community'):
158 if path and os.path.exists(path):
159 return path
brucedawson8cb1a642017-01-23 15:57:21 +0900160 else:
161 keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version,
162 r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version]
163 for key in keys:
164 path = _RegistryGetValue(key, 'InstallDir')
165 if not path:
166 continue
167 path = os.path.normpath(os.path.join(path, '..', '..'))
168 return path
bratell58b9a562016-01-08 01:30:12 +0900169
170 raise Exception(('Visual Studio Version %s (from GYP_MSVS_VERSION)'
171 ' not found.') % (version_as_year))
172
173
brucedawsondf9e2772016-02-09 13:27:52 +0900174def _CopyRuntimeImpl(target, source, verbose=True):
gab22449992016-04-19 00:29:14 +0900175 """Copy |source| to |target| if it doesn't already exist or if it needs to be
176 updated (comparing last modified time as an approximate float match as for
177 some reason the values tend to differ by ~1e-07 despite being copies of the
178 same file... https://crbug.com/603603).
dpranke650b37f2014-11-15 09:09:14 +0900179 """
180 if (os.path.isdir(os.path.dirname(target)) and
181 (not os.path.isfile(target) or
gab22449992016-04-19 00:29:14 +0900182 abs(os.stat(target).st_mtime - os.stat(source).st_mtime) >= 0.01)):
brucedawsondf9e2772016-02-09 13:27:52 +0900183 if verbose:
184 print 'Copying %s to %s...' % (source, target)
dpranke650b37f2014-11-15 09:09:14 +0900185 if os.path.exists(target):
brucedawson815cd432016-06-02 03:37:18 +0900186 # Make the file writable so that we can delete it now.
187 os.chmod(target, stat.S_IWRITE)
dpranke650b37f2014-11-15 09:09:14 +0900188 os.unlink(target)
189 shutil.copy2(source, target)
brucedawson815cd432016-06-02 03:37:18 +0900190 # Make the file writable so that we can overwrite or delete it later.
191 os.chmod(target, stat.S_IWRITE)
dpranke650b37f2014-11-15 09:09:14 +0900192
193
brucedawsonbdf66b62017-03-14 06:12:31 +0900194def _CopyUCRTRuntime(target_dir, source_dir, target_cpu, dll_pattern, suffix):
scottmg73c1e862015-06-02 10:15:44 +0900195 """Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't
196 exist, but the target directory does exist."""
sebmarchand66985722015-12-18 05:44:35 +0900197 for file_part in ('msvcp', 'vccorlib', 'vcruntime'):
scottmg73c1e862015-06-02 10:15:44 +0900198 dll = dll_pattern % file_part
199 target = os.path.join(target_dir, dll)
200 source = os.path.join(source_dir, dll)
201 _CopyRuntimeImpl(target, source)
brucedawsonbdf66b62017-03-14 06:12:31 +0900202 # Copy the UCRT files needed by VS 2015 from the Windows SDK. This location
203 # includes the api-ms-win-crt-*.dll files that are not found in the Windows
204 # directory. These files are needed for component builds.
205 # If WINDOWSSDKDIR is not set use the default SDK path. This will be the case
206 # when DEPOT_TOOLS_WIN_TOOLCHAIN=0 and vcvarsall.bat has not been run.
207 win_sdk_dir = os.path.normpath(
208 os.environ.get('WINDOWSSDKDIR',
209 'C:\\Program Files (x86)\\Windows Kits\\10'))
210 ucrt_dll_dirs = os.path.join(win_sdk_dir, r'Redist\ucrt\DLLs', target_cpu)
211 ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll'))
brucedawson815cd432016-06-02 03:37:18 +0900212 assert len(ucrt_files) > 0
213 for ucrt_src_file in ucrt_files:
brucedawson83e79e92016-02-23 08:09:18 +0900214 file_part = os.path.basename(ucrt_src_file)
215 ucrt_dst_file = os.path.join(target_dir, file_part)
216 _CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False)
217 _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
218 os.path.join(source_dir, 'ucrtbase' + suffix))
dpranke650b37f2014-11-15 09:09:14 +0900219
220
sebmarchand2448ed22017-05-21 00:00:06 +0900221def FindVCToolsRoot():
222 """In VS2017 the PGO runtime dependencies are located in
223 {toolchain_root}/VC/Tools/MSVC/{x.y.z}/bin/Host{target_cpu}/{target_cpu}/, the
224 {version_number} part is likely to change in case of a minor update of the
225 toolchain so we don't hardcode this value here (except for the major number).
226
227 This returns the '{toolchain_root}/VC/Tools/MSVC/{x.y.z}/bin/' path.
228
229 This function should only be called when using VS2017.
230 """
231 assert GetVisualStudioVersion() == '2017'
sebmarchand75c49282017-05-23 11:08:31 +0900232 SetEnvironmentAndGetRuntimeDllDirs()
sebmarchand2448ed22017-05-21 00:00:06 +0900233 assert ('GYP_MSVS_OVERRIDE_PATH' in os.environ)
234 vc_tools_msvc_root = os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
235 'VC', 'Tools', 'MSVC')
236 for directory in os.listdir(vc_tools_msvc_root):
237 if not os.path.isdir(os.path.join(vc_tools_msvc_root, directory)):
238 continue
239 if re.match('14\.\d+\.\d+', directory):
240 return os.path.join(vc_tools_msvc_root, directory, 'bin')
241 raise Exception('Unable to find the VC tools directory.')
242
243
sebmarchand3a2260f2017-05-13 00:29:26 +0900244def _CopyPGORuntime(target_dir, target_cpu):
245 """Copy the runtime dependencies required during a PGO build.
246 """
247 env_version = GetVisualStudioVersion()
248 # These dependencies will be in a different location depending on the version
249 # of the toolchain.
250 if env_version == '2015':
251 pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
252 'VC', 'bin')
253 pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
254 elif env_version == '2017':
sebmarchand2448ed22017-05-21 00:00:06 +0900255 pgo_runtime_root = FindVCToolsRoot()
sebmarchand3a2260f2017-05-13 00:29:26 +0900256 assert pgo_runtime_root
257 # There's no version of pgosweep.exe in HostX64/x86, so we use the copy
258 # from HostX86/x86.
259 pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86')
260 pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64')
261 else:
262 raise Exception('Unexpected toolchain version: %s.' % env_version)
263
264 # We need to copy 2 runtime dependencies used during the profiling step:
265 # - pgort140.dll: runtime library required to run the instrumented image.
266 # - pgosweep.exe: executable used to collect the profiling data
267 pgo_runtimes = ['pgort140.dll', 'pgosweep.exe']
268 for runtime in pgo_runtimes:
269 if target_cpu == 'x86':
270 source = os.path.join(pgo_x86_runtime_dir, runtime)
271 elif target_cpu == 'x64':
272 source = os.path.join(pgo_x64_runtime_dir, runtime)
273 else:
274 raise NotImplementedError("Unexpected target_cpu value: " + target_cpu)
275 if not os.path.exists(source):
276 raise Exception('Unable to find %s.' % source)
277 _CopyRuntimeImpl(os.path.join(target_dir, runtime), source)
278
279
brucedawson0db1b9b2015-11-21 11:21:52 +0900280def _CopyRuntime(target_dir, source_dir, target_cpu, debug):
281 """Copy the VS runtime DLLs, only if the target doesn't exist, but the target
brucedawson6de24072017-03-28 05:59:15 +0900282 directory does exist. Handles VS 2015 and VS 2017."""
brucedawson0db1b9b2015-11-21 11:21:52 +0900283 suffix = "d.dll" if debug else ".dll"
brucedawson6de24072017-03-28 05:59:15 +0900284 # VS 2017 uses the same CRT DLLs as VS 2015.
285 _CopyUCRTRuntime(target_dir, source_dir, target_cpu, '%s140' + suffix,
286 suffix)
brucedawson0db1b9b2015-11-21 11:21:52 +0900287
dpranke650b37f2014-11-15 09:09:14 +0900288
dpranke487f3cf2015-02-20 11:55:19 +0900289def CopyDlls(target_dir, configuration, target_cpu):
dpranke650b37f2014-11-15 09:09:14 +0900290 """Copy the VS runtime DLLs into the requested directory as needed.
291
292 configuration is one of 'Debug' or 'Release'.
dpranke487f3cf2015-02-20 11:55:19 +0900293 target_cpu is one of 'x86' or 'x64'.
dpranke650b37f2014-11-15 09:09:14 +0900294
295 The debug configuration gets both the debug and release DLLs; the
296 release config only the latter.
297 """
brucedawson0db1b9b2015-11-21 11:21:52 +0900298 vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
299 if not vs_runtime_dll_dirs:
dpranke650b37f2014-11-15 09:09:14 +0900300 return
301
brucedawson0db1b9b2015-11-21 11:21:52 +0900302 x64_runtime, x86_runtime = vs_runtime_dll_dirs
dpranke487f3cf2015-02-20 11:55:19 +0900303 runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime
brucedawson0db1b9b2015-11-21 11:21:52 +0900304 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
dpranke650b37f2014-11-15 09:09:14 +0900305 if configuration == 'Debug':
brucedawson0db1b9b2015-11-21 11:21:52 +0900306 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
sebmarchand3a2260f2017-05-13 00:29:26 +0900307 else:
308 _CopyPGORuntime(target_dir, target_cpu)
sebmarchand@chromium.orgf1d42ff2014-07-22 09:18:32 +0900309
brucedawson7649bc72017-04-20 07:27:40 +0900310 _CopyDebugger(target_dir, target_cpu)
311
312
313def _CopyDebugger(target_dir, target_cpu):
sebmarchand7e78f532017-06-30 07:24:39 +0900314 """Copy dbghelp.dll and dbgcore.dll into the requested directory as needed.
brucedawson7649bc72017-04-20 07:27:40 +0900315
316 target_cpu is one of 'x86' or 'x64'.
317
318 dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file
319 from the SDK directory avoids using the system copy of dbghelp.dll which then
320 ensures compatibility with recent debug information formats, such as VS
321 2017 /debug:fastlink PDBs.
sebmarchand7e78f532017-06-30 07:24:39 +0900322
323 dbgcore.dll is needed when using some functions from dbghelp.dll (like
324 MinidumpWriteDump).
brucedawson7649bc72017-04-20 07:27:40 +0900325 """
326 win_sdk_dir = SetEnvironmentAndGetSDKDir()
327 if not win_sdk_dir:
328 return
329
sebmarchand7e78f532017-06-30 07:24:39 +0900330 debug_files = ['dbghelp.dll', 'dbgcore.dll']
331 for debug_file in debug_files:
332 full_path = os.path.join(win_sdk_dir, 'Debuggers', target_cpu, debug_file)
333 if not os.path.exists(full_path):
334 raise Exception('%s not found in "%s"\r\nYou must install the '
335 '"Debugging Tools for Windows" feature from the Windows '
336 '10 SDK.' % (debug_file, full_path))
337 target_path = os.path.join(target_dir, debug_file)
338 _CopyRuntimeImpl(target_path, full_path)
brucedawson7649bc72017-04-20 07:27:40 +0900339
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +0900340
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900341def _GetDesiredVsToolchainHashes():
342 """Load a list of SHA1s corresponding to the toolchains that we want installed
343 to build with."""
thestig85803602017-03-11 10:46:42 +0900344 env_version = GetVisualStudioVersion()
thestig85803602017-03-11 10:46:42 +0900345 if env_version == '2015':
brucedawsone3f14f32017-06-23 02:40:42 +0900346 # Update 3 final with 10.0.15063.468 SDK and no vctip.exe.
347 return ['f53e4598951162bad6330f7a167486c7ae5db1e5']
brucedawsondc100362017-03-25 08:10:01 +0900348 if env_version == '2017':
brucedawson2beb9772017-06-15 09:31:12 +0900349 # VS 2017 Update 3 Preview 2 with 10.0.15063.0 SDK and patched event.h.
350 return ['425bd64734a387734dfcf445b285a7c5073e4262']
thestig85803602017-03-11 10:46:42 +0900351 raise Exception('Unsupported VS version %s' % env_version)
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900352
353
sebmarchandd84a2ff2016-01-16 07:29:57 +0900354def ShouldUpdateToolchain():
355 """Check if the toolchain should be upgraded."""
356 if not os.path.exists(json_data_file):
357 return True
358 with open(json_data_file, 'r') as tempf:
359 toolchain_data = json.load(tempf)
360 version = toolchain_data['version']
361 env_version = GetVisualStudioVersion()
362 # If there's a mismatch between the version set in the environment and the one
363 # in the json file then the toolchain should be updated.
364 return version != env_version
365
366
thakis79870e22015-08-12 07:25:00 +0900367def Update(force=False):
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900368 """Requests an update of the toolchain to the specific hashes we have at
369 this revision. The update outputs a .json of the various configuration
370 information required to pass to gyp which we use in |GetToolchainDir()|.
371 """
thakis79870e22015-08-12 07:25:00 +0900372 if force != False and force != '--force':
373 print >>sys.stderr, 'Unknown parameter "%s"' % force
374 return 1
375 if force == '--force' or os.path.exists(json_data_file):
376 force = True
377
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900378 depot_tools_win_toolchain = \
379 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
thakis79870e22015-08-12 07:25:00 +0900380 if ((sys.platform in ('win32', 'cygwin') or force) and
381 depot_tools_win_toolchain):
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900382 import find_depot_tools
383 depot_tools_path = find_depot_tools.add_depot_tools_to_path()
brucedawson31d3f672016-03-12 04:55:25 +0900384 # Necessary so that get_toolchain_if_necessary.py will put the VS toolkit
385 # in the correct directory.
386 os.environ['GYP_MSVS_VERSION'] = GetVisualStudioVersion()
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900387 get_toolchain_args = [
388 sys.executable,
389 os.path.join(depot_tools_path,
390 'win_toolchain',
391 'get_toolchain_if_necessary.py'),
392 '--output-json', json_data_file,
393 ] + _GetDesiredVsToolchainHashes()
thakis79870e22015-08-12 07:25:00 +0900394 if force:
395 get_toolchain_args.append('--force')
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900396 subprocess.check_call(get_toolchain_args)
397
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +0900398 return 0
399
scottmg@chromium.org0efdbb72014-03-21 02:42:25 +0900400
brucedawson5b777252016-03-23 09:58:06 +0900401def NormalizePath(path):
402 while path.endswith("\\"):
403 path = path[:-1]
404 return path
405
406
jochencc14d662017-02-16 07:45:26 +0900407def SetEnvironmentAndGetSDKDir():
408 """Gets location information about the current sdk (must have been
brettw@chromium.org4d8b4232014-05-29 05:32:01 +0900409 previously updated by 'update'). This is used for the GN build."""
tikuta0c091c02017-05-02 15:12:31 +0900410 SetEnvironmentAndGetRuntimeDllDirs()
ckocagilcca62d42014-10-01 04:31:43 +0900411
412 # If WINDOWSSDKDIR is not set, search the default SDK path and set it.
413 if not 'WINDOWSSDKDIR' in os.environ:
brucedawson738bfff2016-01-22 08:35:35 +0900414 default_sdk_path = 'C:\\Program Files (x86)\\Windows Kits\\10'
ckocagilcca62d42014-10-01 04:31:43 +0900415 if os.path.isdir(default_sdk_path):
416 os.environ['WINDOWSSDKDIR'] = default_sdk_path
417
jochencc14d662017-02-16 07:45:26 +0900418 return NormalizePath(os.environ['WINDOWSSDKDIR'])
419
420
421def GetToolchainDir():
422 """Gets location information about the current toolchain (must have been
423 previously updated by 'update'). This is used for the GN build."""
424 runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
425 win_sdk_dir = SetEnvironmentAndGetSDKDir()
426
brettw@chromium.org4d8b4232014-05-29 05:32:01 +0900427 print '''vs_path = "%s"
428sdk_path = "%s"
429vs_version = "%s"
430wdk_dir = "%s"
scottmgd24020c2014-11-20 04:33:28 +0900431runtime_dirs = "%s"
brettw@chromium.org4d8b4232014-05-29 05:32:01 +0900432''' % (
brucedawson5b777252016-03-23 09:58:06 +0900433 NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH']),
jochencc14d662017-02-16 07:45:26 +0900434 win_sdk_dir,
halton.huo08f76172016-01-13 11:23:30 +0900435 GetVisualStudioVersion(),
brucedawson5b777252016-03-23 09:58:06 +0900436 NormalizePath(os.environ.get('WDK_DIR', '')),
thakisfe3b08a2016-02-16 03:18:01 +0900437 os.path.pathsep.join(runtime_dll_dirs or ['None']))
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900438
439
440def main():
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900441 commands = {
442 'update': Update,
443 'get_toolchain_dir': GetToolchainDir,
dpranke650b37f2014-11-15 09:09:14 +0900444 'copy_dlls': CopyDlls,
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900445 }
446 if len(sys.argv) < 2 or sys.argv[1] not in commands:
447 print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands)
448 return 1
dpranke650b37f2014-11-15 09:09:14 +0900449 return commands[sys.argv[1]](*sys.argv[2:])
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900450
451
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +0900452if __name__ == '__main__':
453 sys.exit(main())