blob: 655512739ea590aea1a3eb8a864236b686d59f12 [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
Bruce Dawsonb43c2ef2017-07-18 01:39:20 +090025# Use MSVS2015 as the default toolchain.
26CURRENT_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'))
Nico Webere6d34d92017-07-25 07:23:12 +0900210 ucrt_dll_dirs = os.path.join(win_sdk_dir, 'Redist', 'ucrt', 'DLLs',
211 target_cpu)
brucedawsonbdf66b62017-03-14 06:12:31 +0900212 ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll'))
brucedawson815cd432016-06-02 03:37:18 +0900213 assert len(ucrt_files) > 0
214 for ucrt_src_file in ucrt_files:
brucedawson83e79e92016-02-23 08:09:18 +0900215 file_part = os.path.basename(ucrt_src_file)
216 ucrt_dst_file = os.path.join(target_dir, file_part)
217 _CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False)
218 _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
219 os.path.join(source_dir, 'ucrtbase' + suffix))
dpranke650b37f2014-11-15 09:09:14 +0900220
221
sebmarchand2448ed22017-05-21 00:00:06 +0900222def FindVCToolsRoot():
223 """In VS2017 the PGO runtime dependencies are located in
224 {toolchain_root}/VC/Tools/MSVC/{x.y.z}/bin/Host{target_cpu}/{target_cpu}/, the
225 {version_number} part is likely to change in case of a minor update of the
226 toolchain so we don't hardcode this value here (except for the major number).
227
228 This returns the '{toolchain_root}/VC/Tools/MSVC/{x.y.z}/bin/' path.
229
230 This function should only be called when using VS2017.
231 """
232 assert GetVisualStudioVersion() == '2017'
sebmarchand75c49282017-05-23 11:08:31 +0900233 SetEnvironmentAndGetRuntimeDllDirs()
sebmarchand2448ed22017-05-21 00:00:06 +0900234 assert ('GYP_MSVS_OVERRIDE_PATH' in os.environ)
235 vc_tools_msvc_root = os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
236 'VC', 'Tools', 'MSVC')
237 for directory in os.listdir(vc_tools_msvc_root):
238 if not os.path.isdir(os.path.join(vc_tools_msvc_root, directory)):
239 continue
240 if re.match('14\.\d+\.\d+', directory):
241 return os.path.join(vc_tools_msvc_root, directory, 'bin')
242 raise Exception('Unable to find the VC tools directory.')
243
244
sebmarchand3a2260f2017-05-13 00:29:26 +0900245def _CopyPGORuntime(target_dir, target_cpu):
246 """Copy the runtime dependencies required during a PGO build.
247 """
248 env_version = GetVisualStudioVersion()
249 # These dependencies will be in a different location depending on the version
250 # of the toolchain.
251 if env_version == '2015':
252 pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
253 'VC', 'bin')
254 pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
255 elif env_version == '2017':
sebmarchand2448ed22017-05-21 00:00:06 +0900256 pgo_runtime_root = FindVCToolsRoot()
sebmarchand3a2260f2017-05-13 00:29:26 +0900257 assert pgo_runtime_root
258 # There's no version of pgosweep.exe in HostX64/x86, so we use the copy
259 # from HostX86/x86.
260 pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86')
261 pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64')
262 else:
263 raise Exception('Unexpected toolchain version: %s.' % env_version)
264
265 # We need to copy 2 runtime dependencies used during the profiling step:
266 # - pgort140.dll: runtime library required to run the instrumented image.
267 # - pgosweep.exe: executable used to collect the profiling data
268 pgo_runtimes = ['pgort140.dll', 'pgosweep.exe']
269 for runtime in pgo_runtimes:
270 if target_cpu == 'x86':
271 source = os.path.join(pgo_x86_runtime_dir, runtime)
272 elif target_cpu == 'x64':
273 source = os.path.join(pgo_x64_runtime_dir, runtime)
274 else:
275 raise NotImplementedError("Unexpected target_cpu value: " + target_cpu)
276 if not os.path.exists(source):
277 raise Exception('Unable to find %s.' % source)
278 _CopyRuntimeImpl(os.path.join(target_dir, runtime), source)
279
280
brucedawson0db1b9b2015-11-21 11:21:52 +0900281def _CopyRuntime(target_dir, source_dir, target_cpu, debug):
282 """Copy the VS runtime DLLs, only if the target doesn't exist, but the target
brucedawson6de24072017-03-28 05:59:15 +0900283 directory does exist. Handles VS 2015 and VS 2017."""
brucedawson0db1b9b2015-11-21 11:21:52 +0900284 suffix = "d.dll" if debug else ".dll"
brucedawson6de24072017-03-28 05:59:15 +0900285 # VS 2017 uses the same CRT DLLs as VS 2015.
286 _CopyUCRTRuntime(target_dir, source_dir, target_cpu, '%s140' + suffix,
287 suffix)
brucedawson0db1b9b2015-11-21 11:21:52 +0900288
dpranke650b37f2014-11-15 09:09:14 +0900289
dpranke487f3cf2015-02-20 11:55:19 +0900290def CopyDlls(target_dir, configuration, target_cpu):
dpranke650b37f2014-11-15 09:09:14 +0900291 """Copy the VS runtime DLLs into the requested directory as needed.
292
293 configuration is one of 'Debug' or 'Release'.
dpranke487f3cf2015-02-20 11:55:19 +0900294 target_cpu is one of 'x86' or 'x64'.
dpranke650b37f2014-11-15 09:09:14 +0900295
296 The debug configuration gets both the debug and release DLLs; the
297 release config only the latter.
298 """
brucedawson0db1b9b2015-11-21 11:21:52 +0900299 vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
300 if not vs_runtime_dll_dirs:
dpranke650b37f2014-11-15 09:09:14 +0900301 return
302
brucedawson0db1b9b2015-11-21 11:21:52 +0900303 x64_runtime, x86_runtime = vs_runtime_dll_dirs
dpranke487f3cf2015-02-20 11:55:19 +0900304 runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime
brucedawson0db1b9b2015-11-21 11:21:52 +0900305 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
dpranke650b37f2014-11-15 09:09:14 +0900306 if configuration == 'Debug':
brucedawson0db1b9b2015-11-21 11:21:52 +0900307 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
sebmarchand3a2260f2017-05-13 00:29:26 +0900308 else:
309 _CopyPGORuntime(target_dir, target_cpu)
sebmarchand@chromium.orgf1d42ff2014-07-22 09:18:32 +0900310
brucedawson7649bc72017-04-20 07:27:40 +0900311 _CopyDebugger(target_dir, target_cpu)
312
313
314def _CopyDebugger(target_dir, target_cpu):
sebmarchand7e78f532017-06-30 07:24:39 +0900315 """Copy dbghelp.dll and dbgcore.dll into the requested directory as needed.
brucedawson7649bc72017-04-20 07:27:40 +0900316
317 target_cpu is one of 'x86' or 'x64'.
318
319 dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file
320 from the SDK directory avoids using the system copy of dbghelp.dll which then
321 ensures compatibility with recent debug information formats, such as VS
322 2017 /debug:fastlink PDBs.
sebmarchand7e78f532017-06-30 07:24:39 +0900323
324 dbgcore.dll is needed when using some functions from dbghelp.dll (like
325 MinidumpWriteDump).
brucedawson7649bc72017-04-20 07:27:40 +0900326 """
327 win_sdk_dir = SetEnvironmentAndGetSDKDir()
328 if not win_sdk_dir:
329 return
330
sebmarchand7e78f532017-06-30 07:24:39 +0900331 debug_files = ['dbghelp.dll', 'dbgcore.dll']
332 for debug_file in debug_files:
333 full_path = os.path.join(win_sdk_dir, 'Debuggers', target_cpu, debug_file)
334 if not os.path.exists(full_path):
335 raise Exception('%s not found in "%s"\r\nYou must install the '
336 '"Debugging Tools for Windows" feature from the Windows '
337 '10 SDK.' % (debug_file, full_path))
338 target_path = os.path.join(target_dir, debug_file)
339 _CopyRuntimeImpl(target_path, full_path)
brucedawson7649bc72017-04-20 07:27:40 +0900340
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +0900341
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900342def _GetDesiredVsToolchainHashes():
343 """Load a list of SHA1s corresponding to the toolchains that we want installed
344 to build with."""
thestig85803602017-03-11 10:46:42 +0900345 env_version = GetVisualStudioVersion()
thestig85803602017-03-11 10:46:42 +0900346 if env_version == '2015':
brucedawsone3f14f32017-06-23 02:40:42 +0900347 # Update 3 final with 10.0.15063.468 SDK and no vctip.exe.
348 return ['f53e4598951162bad6330f7a167486c7ae5db1e5']
brucedawsondc100362017-03-25 08:10:01 +0900349 if env_version == '2017':
Bruce Dawsoncd5982d2017-07-15 11:20:35 +0900350 # VS 2017 Update 3 Preview 4 with 10.0.15063.468 SDK.
351 return ['1f52d730755ac72dddaf121b73c9d6fd5c24ddf8']
thestig85803602017-03-11 10:46:42 +0900352 raise Exception('Unsupported VS version %s' % env_version)
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900353
354
sebmarchandd84a2ff2016-01-16 07:29:57 +0900355def ShouldUpdateToolchain():
356 """Check if the toolchain should be upgraded."""
357 if not os.path.exists(json_data_file):
358 return True
359 with open(json_data_file, 'r') as tempf:
360 toolchain_data = json.load(tempf)
361 version = toolchain_data['version']
362 env_version = GetVisualStudioVersion()
363 # If there's a mismatch between the version set in the environment and the one
364 # in the json file then the toolchain should be updated.
365 return version != env_version
366
367
thakis79870e22015-08-12 07:25:00 +0900368def Update(force=False):
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900369 """Requests an update of the toolchain to the specific hashes we have at
370 this revision. The update outputs a .json of the various configuration
371 information required to pass to gyp which we use in |GetToolchainDir()|.
372 """
thakis79870e22015-08-12 07:25:00 +0900373 if force != False and force != '--force':
374 print >>sys.stderr, 'Unknown parameter "%s"' % force
375 return 1
376 if force == '--force' or os.path.exists(json_data_file):
377 force = True
378
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900379 depot_tools_win_toolchain = \
380 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
thakis79870e22015-08-12 07:25:00 +0900381 if ((sys.platform in ('win32', 'cygwin') or force) and
382 depot_tools_win_toolchain):
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900383 import find_depot_tools
384 depot_tools_path = find_depot_tools.add_depot_tools_to_path()
brucedawson31d3f672016-03-12 04:55:25 +0900385 # Necessary so that get_toolchain_if_necessary.py will put the VS toolkit
386 # in the correct directory.
387 os.environ['GYP_MSVS_VERSION'] = GetVisualStudioVersion()
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900388 get_toolchain_args = [
389 sys.executable,
390 os.path.join(depot_tools_path,
391 'win_toolchain',
392 'get_toolchain_if_necessary.py'),
393 '--output-json', json_data_file,
394 ] + _GetDesiredVsToolchainHashes()
thakis79870e22015-08-12 07:25:00 +0900395 if force:
396 get_toolchain_args.append('--force')
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900397 subprocess.check_call(get_toolchain_args)
398
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +0900399 return 0
400
scottmg@chromium.org0efdbb72014-03-21 02:42:25 +0900401
brucedawson5b777252016-03-23 09:58:06 +0900402def NormalizePath(path):
403 while path.endswith("\\"):
404 path = path[:-1]
405 return path
406
407
jochencc14d662017-02-16 07:45:26 +0900408def SetEnvironmentAndGetSDKDir():
409 """Gets location information about the current sdk (must have been
brettw@chromium.org4d8b4232014-05-29 05:32:01 +0900410 previously updated by 'update'). This is used for the GN build."""
tikuta0c091c02017-05-02 15:12:31 +0900411 SetEnvironmentAndGetRuntimeDllDirs()
ckocagilcca62d42014-10-01 04:31:43 +0900412
413 # If WINDOWSSDKDIR is not set, search the default SDK path and set it.
414 if not 'WINDOWSSDKDIR' in os.environ:
brucedawson738bfff2016-01-22 08:35:35 +0900415 default_sdk_path = 'C:\\Program Files (x86)\\Windows Kits\\10'
ckocagilcca62d42014-10-01 04:31:43 +0900416 if os.path.isdir(default_sdk_path):
417 os.environ['WINDOWSSDKDIR'] = default_sdk_path
418
jochencc14d662017-02-16 07:45:26 +0900419 return NormalizePath(os.environ['WINDOWSSDKDIR'])
420
421
422def GetToolchainDir():
423 """Gets location information about the current toolchain (must have been
424 previously updated by 'update'). This is used for the GN build."""
425 runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
426 win_sdk_dir = SetEnvironmentAndGetSDKDir()
427
brettw@chromium.org4d8b4232014-05-29 05:32:01 +0900428 print '''vs_path = "%s"
429sdk_path = "%s"
430vs_version = "%s"
431wdk_dir = "%s"
scottmgd24020c2014-11-20 04:33:28 +0900432runtime_dirs = "%s"
brettw@chromium.org4d8b4232014-05-29 05:32:01 +0900433''' % (
brucedawson5b777252016-03-23 09:58:06 +0900434 NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH']),
jochencc14d662017-02-16 07:45:26 +0900435 win_sdk_dir,
halton.huo08f76172016-01-13 11:23:30 +0900436 GetVisualStudioVersion(),
brucedawson5b777252016-03-23 09:58:06 +0900437 NormalizePath(os.environ.get('WDK_DIR', '')),
thakisfe3b08a2016-02-16 03:18:01 +0900438 os.path.pathsep.join(runtime_dll_dirs or ['None']))
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900439
440
441def main():
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900442 commands = {
443 'update': Update,
444 'get_toolchain_dir': GetToolchainDir,
dpranke650b37f2014-11-15 09:09:14 +0900445 'copy_dlls': CopyDlls,
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900446 }
447 if len(sys.argv) < 2 or sys.argv[1] not in commands:
448 print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands)
449 return 1
dpranke650b37f2014-11-15 09:09:14 +0900450 return commands[sys.argv[1]](*sys.argv[2:])
scottmg@chromium.orgf867a392014-04-09 10:56:20 +0900451
452
scottmg@chromium.org73ab3a52014-03-20 07:01:39 +0900453if __name__ == '__main__':
454 sys.exit(main())