Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 2 | # 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 | |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 6 | # For Dart developers: |
| 7 | # This file keeps the MSVC toolchain up-to-date for Google developers. |
| 8 | # It is copied from Chromium: |
| 9 | # https://cs.chromium.org/chromium/src/build/vs_toolchain.py |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 10 | # with modifications that update paths and remove dependencies on gyp. |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 11 | # To update to a new MSVC toolchain, copy the updated script from the Chromium |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 12 | # tree, edit to make it work in the Dart tree by updating paths in the original script. |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 13 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 14 | from __future__ import print_function |
| 15 | |
| 16 | import collections |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 17 | import glob |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 18 | import json |
| 19 | import os |
| 20 | import pipes |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 21 | import platform |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 22 | import re |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 23 | import shutil |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 24 | import stat |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 25 | import subprocess |
| 26 | import sys |
Alexander Thomas | fd7b86e | 2018-11-18 22:06:49 +0000 | [diff] [blame] | 27 | |
Alexander Aprelev | e7d71be | 2018-09-26 17:09:36 +0000 | [diff] [blame] | 28 | from gn_helpers import ToGNString |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 29 | |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 30 | # VS 2019 16.61 with 10.0.19041 SDK, and 10.0.17134 version of |
| 31 | # d3dcompiler_47.dll, with ARM64 libraries and UWP support. |
| 32 | # See go/chromium-msvc-toolchain for instructions about how to update the |
| 33 | # toolchain. |
| 34 | # |
| 35 | # When updating the toolchain, consider the following areas impacted by the |
| 36 | # toolchain version: |
| 37 | # |
| 38 | # * //base/win/windows_version.cc NTDDI preprocessor check |
| 39 | # Triggers a compiler error if the available SDK is older than the minimum. |
| 40 | # * //build/config/win/BUILD.gn NTDDI_VERSION value |
| 41 | # Affects the availability of APIs in the toolchain headers. |
| 42 | # * //docs/windows_build_instructions.md mentions of VS or Windows SDK. |
| 43 | # Keeps the document consistent with the toolchain version. |
| 44 | TOOLCHAIN_HASH = '20d5f2553f' |
| 45 | |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 46 | script_dir = os.path.dirname(os.path.realpath(__file__)) |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 47 | dart_src = os.path.abspath(os.path.join(script_dir, os.pardir)) |
| 48 | sys.path.insert(0, os.path.join(dart_src, 'tools')) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 49 | json_data_file = os.path.join(script_dir, 'win_toolchain.json') |
| 50 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 51 | # VS versions are listed in descending order of priority (highest first). |
| 52 | MSVS_VERSIONS = collections.OrderedDict([ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 53 | ('2019', '16.0'), |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 54 | ('2017', '15.0'), |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 55 | ]) |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 56 | |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 57 | # List of preferred VC toolset version based on MSVS |
| 58 | MSVC_TOOLSET_VERSION = { |
| 59 | '2019': 'VC142', |
| 60 | '2017': 'VC141', |
| 61 | } |
| 62 | |
| 63 | |
| 64 | def _HostIsWindows(): |
| 65 | """Returns True if running on a Windows host (including under cygwin).""" |
| 66 | return sys.platform in ('win32', 'cygwin') |
| 67 | |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 68 | |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 69 | def SetEnvironmentAndGetRuntimeDllDirs(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 70 | """Sets up os.environ to use the depot_tools VS toolchain with gyp, and |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 71 | returns the location of the VC runtime DLLs so they can be copied into |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 72 | the output directory after gyp generation. |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 73 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 74 | Return value is [x64path, x86path, 'Arm64Unused'] or None. arm64path is |
| 75 | generated separately because there are multiple folders for the arm64 VC |
| 76 | runtime. |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 77 | """ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 78 | vs_runtime_dll_dirs = None |
| 79 | depot_tools_win_toolchain = \ |
| 80 | bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))) |
| 81 | # When running on a non-Windows host, only do this if the SDK has explicitly |
| 82 | # been downloaded before (in which case json_data_file will exist). |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 83 | if ((_HostIsWindows() or os.path.exists(json_data_file)) and |
| 84 | depot_tools_win_toolchain): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 85 | if ShouldUpdateToolchain(): |
| 86 | if len(sys.argv) > 1 and sys.argv[1] == 'update': |
| 87 | update_result = Update() |
| 88 | else: |
| 89 | update_result = Update(no_download=True) |
| 90 | if update_result != 0: |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 91 | raise Exception('Failed to update, error code %d.' % |
| 92 | update_result) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 93 | with open(json_data_file, 'r') as tempf: |
| 94 | toolchain_data = json.load(tempf) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 95 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 96 | toolchain = toolchain_data['path'] |
| 97 | version = toolchain_data['version'] |
| 98 | win_sdk = toolchain_data.get('win_sdk') |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 99 | wdk = toolchain_data['wdk'] |
| 100 | # TODO(scottmg): The order unfortunately matters in these. They should be |
| 101 | # split into separate keys for x64/x86/arm64. (See CopyDlls call below). |
| 102 | # http://crbug.com/345992 |
| 103 | vs_runtime_dll_dirs = toolchain_data['runtime_dirs'] |
| 104 | # The number of runtime_dirs in the toolchain_data was two (x64/x86) but |
| 105 | # changed to three (x64/x86/arm64) and this code needs to handle both |
| 106 | # possibilities, which can change independently from this code. |
| 107 | if len(vs_runtime_dll_dirs) == 2: |
| 108 | vs_runtime_dll_dirs.append('Arm64Unused') |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 109 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 110 | os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 111 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 112 | os.environ['WINDOWSSDKDIR'] = win_sdk |
| 113 | os.environ['WDK_DIR'] = wdk |
| 114 | # Include the VS runtime in the PATH in case it's not machine-installed. |
| 115 | runtime_path = os.path.pathsep.join(vs_runtime_dll_dirs) |
| 116 | os.environ['PATH'] = runtime_path + os.path.pathsep + os.environ['PATH'] |
| 117 | elif sys.platform == 'win32' and not depot_tools_win_toolchain: |
| 118 | if not 'GYP_MSVS_OVERRIDE_PATH' in os.environ: |
| 119 | os.environ['GYP_MSVS_OVERRIDE_PATH'] = DetectVisualStudioPath() |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 120 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 121 | # When using an installed toolchain these files aren't needed in the output |
| 122 | # directory in order to run binaries locally, but they are needed in order |
| 123 | # to create isolates or the mini_installer. Copying them to the output |
| 124 | # directory ensures that they are available when needed. |
| 125 | bitness = platform.architecture()[0] |
| 126 | # When running 64-bit python the x64 DLLs will be in System32 |
| 127 | # ARM64 binaries will not be available in the system directories because we |
| 128 | # don't build on ARM64 machines. |
| 129 | x64_path = 'System32' if bitness == '64bit' else 'Sysnative' |
| 130 | x64_path = os.path.join(os.path.expandvars('%windir%'), x64_path) |
| 131 | vs_runtime_dll_dirs = [ |
| 132 | x64_path, |
| 133 | os.path.join(os.path.expandvars('%windir%'), 'SysWOW64'), |
| 134 | 'Arm64Unused' |
| 135 | ] |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 136 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 137 | return vs_runtime_dll_dirs |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 138 | |
| 139 | |
| 140 | def _RegistryGetValueUsingWinReg(key, value): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 141 | """Use the _winreg module to obtain the value of a registry key. |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 142 | |
| 143 | Args: |
| 144 | key: The registry key. |
| 145 | value: The particular registry value to read. |
| 146 | Return: |
| 147 | contents of the registry key's value, or None on failure. Throws |
| 148 | ImportError if _winreg is unavailable. |
| 149 | """ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 150 | import _winreg |
| 151 | try: |
| 152 | root, subkey = key.split('\\', 1) |
| 153 | assert root == 'HKLM' # Only need HKLM for now. |
| 154 | with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: |
| 155 | return _winreg.QueryValueEx(hkey, value)[0] |
| 156 | except WindowsError: |
| 157 | return None |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 158 | |
| 159 | |
| 160 | def _RegistryGetValue(key, value): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 161 | try: |
| 162 | return _RegistryGetValueUsingWinReg(key, value) |
| 163 | except ImportError: |
| 164 | raise Exception('The python library _winreg not found.') |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 165 | |
| 166 | |
| 167 | def GetVisualStudioVersion(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 168 | """Return best available version of Visual Studio. |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 169 | """ |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 170 | supported_versions = list(MSVS_VERSIONS.keys()) |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 171 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 172 | # VS installed in depot_tools for Googlers |
| 173 | if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))): |
| 174 | return supported_versions[0] |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 175 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 176 | # VS installed in system for external developers |
| 177 | supported_versions_str = ', '.join( |
| 178 | '{} ({})'.format(v, k) for k, v in MSVS_VERSIONS.items()) |
| 179 | available_versions = [] |
| 180 | for version in supported_versions: |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 181 | # Checking vs%s_install environment variables. |
| 182 | # For example, vs2019_install could have the value |
| 183 | # "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community". |
| 184 | # Only vs2017_install and vs2019_install are supported. |
| 185 | path = os.environ.get('vs%s_install' % version) |
| 186 | if path and os.path.exists(path): |
| 187 | available_versions.append(version) |
| 188 | break |
| 189 | # Detecting VS under possible paths. |
| 190 | path = os.path.expandvars('%ProgramFiles(x86)%' + |
| 191 | '/Microsoft Visual Studio/%s' % version) |
| 192 | if path and any( |
| 193 | os.path.exists(os.path.join(path, edition)) |
| 194 | for edition in ('Enterprise', 'Professional', 'Community', |
| 195 | 'Preview', 'BuildTools')): |
| 196 | available_versions.append(version) |
| 197 | break |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 198 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 199 | if not available_versions: |
| 200 | raise Exception('No supported Visual Studio can be found.' |
| 201 | ' Supported versions are: %s.' % supported_versions_str) |
| 202 | return available_versions[0] |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 203 | |
| 204 | |
| 205 | def DetectVisualStudioPath(): |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 206 | """Return path to the installed Visual Studio. |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 207 | """ |
| 208 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 209 | # Note that this code is used from |
| 210 | # build/toolchain/win/setup_toolchain.py as well. |
| 211 | version_as_year = GetVisualStudioVersion() |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 212 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 213 | # The VC++ >=2017 install location needs to be located using COM instead of |
| 214 | # the registry. For details see: |
| 215 | # https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/ |
| 216 | # For now we use a hardcoded default with an environment variable override. |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 217 | for path in (os.environ.get('vs%s_install' % version_as_year), |
| 218 | os.path.expandvars('%ProgramFiles(x86)%' + |
| 219 | '/Microsoft Visual Studio/%s/Enterprise' % |
| 220 | version_as_year), |
| 221 | os.path.expandvars('%ProgramFiles(x86)%' + |
| 222 | '/Microsoft Visual Studio/%s/Professional' % |
| 223 | version_as_year), |
| 224 | os.path.expandvars('%ProgramFiles(x86)%' + |
| 225 | '/Microsoft Visual Studio/%s/Community' % |
| 226 | version_as_year), |
| 227 | os.path.expandvars('%ProgramFiles(x86)%' + |
| 228 | '/Microsoft Visual Studio/%s/Preview' % |
| 229 | version_as_year), |
| 230 | os.path.expandvars('%ProgramFiles(x86)%' + |
| 231 | '/Microsoft Visual Studio/%s/BuildTools' % |
| 232 | version_as_year)): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 233 | if path and os.path.exists(path): |
| 234 | return path |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 235 | |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 236 | raise Exception('Visual Studio Version %s not found.' % version_as_year) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 237 | |
| 238 | |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 239 | def _CopyRuntimeImpl(target, source, verbose=True): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 240 | """Copy |source| to |target| if it doesn't already exist or if it needs to be |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 241 | updated (comparing last modified time as an approximate float match as for |
| 242 | some reason the values tend to differ by ~1e-07 despite being copies of the |
| 243 | same file... https://crbug.com/603603). |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 244 | """ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 245 | if (os.path.isdir(os.path.dirname(target)) and |
| 246 | (not os.path.isfile(target) or |
| 247 | abs(os.stat(target).st_mtime - os.stat(source).st_mtime) >= 0.01)): |
| 248 | if verbose: |
| 249 | print('Copying %s to %s...' % (source, target)) |
| 250 | if os.path.exists(target): |
| 251 | # Make the file writable so that we can delete it now, and keep it |
| 252 | # readable. |
| 253 | os.chmod(target, stat.S_IWRITE | stat.S_IREAD) |
| 254 | os.unlink(target) |
| 255 | shutil.copy2(source, target) |
| 256 | # Make the file writable so that we can overwrite or delete it later, |
| 257 | # keep it readable. |
| 258 | os.chmod(target, stat.S_IWRITE | stat.S_IREAD) |
| 259 | |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 260 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 261 | def _SortByHighestVersionNumberFirst(list_of_str_versions): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 262 | """This sorts |list_of_str_versions| according to version number rules |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 263 | so that version "1.12" is higher than version "1.9". Does not work |
| 264 | with non-numeric versions like 1.4.a8 which will be higher than |
| 265 | 1.4.a12. It does handle the versions being embedded in file paths. |
| 266 | """ |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 267 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 268 | def to_int_if_int(x): |
| 269 | try: |
| 270 | return int(x) |
| 271 | except ValueError: |
| 272 | return x |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 273 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 274 | def to_number_sequence(x): |
| 275 | part_sequence = re.split(r'[\\/\.]', x) |
| 276 | return [to_int_if_int(x) for x in part_sequence] |
| 277 | |
| 278 | list_of_str_versions.sort(key=to_number_sequence, reverse=True) |
| 279 | |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 280 | |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 281 | def _CopyUCRTRuntime(target_dir, source_dir, target_cpu, suffix): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 282 | """Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 283 | exist, but the target directory does exist.""" |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 284 | if target_cpu == 'arm64': |
| 285 | # Windows ARM64 VCRuntime is located at {toolchain_root}/VC/Redist/MSVC/ |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 286 | # {x.y.z}/[debug_nonredist/]arm64/Microsoft.VC14x.CRT/. |
| 287 | # Select VC toolset directory based on Visual Studio version |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 288 | vc_redist_root = FindVCRedistRoot() |
| 289 | if suffix.startswith('.'): |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 290 | vc_toolset_dir = 'Microsoft.{}.CRT' \ |
| 291 | .format(MSVC_TOOLSET_VERSION[GetVisualStudioVersion()]) |
| 292 | source_dir = os.path.join(vc_redist_root, 'arm64', vc_toolset_dir) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 293 | else: |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 294 | vc_toolset_dir = 'Microsoft.{}.DebugCRT' \ |
| 295 | .format(MSVC_TOOLSET_VERSION[GetVisualStudioVersion()]) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 296 | source_dir = os.path.join(vc_redist_root, 'debug_nonredist', |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 297 | 'arm64', vc_toolset_dir) |
| 298 | file_parts = ('msvcp140', 'vccorlib140', 'vcruntime140') |
| 299 | if target_cpu == 'x64' and GetVisualStudioVersion() != '2017': |
| 300 | file_parts = file_parts + ('vcruntime140_1',) |
| 301 | for file_part in file_parts: |
| 302 | dll = file_part + suffix |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 303 | target = os.path.join(target_dir, dll) |
| 304 | source = os.path.join(source_dir, dll) |
| 305 | _CopyRuntimeImpl(target, source) |
| 306 | # Copy the UCRT files from the Windows SDK. This location includes the |
| 307 | # api-ms-win-crt-*.dll files that are not found in the Windows directory. |
| 308 | # These files are needed for component builds. If WINDOWSSDKDIR is not set |
| 309 | # use the default SDK path. This will be the case when |
| 310 | # DEPOT_TOOLS_WIN_TOOLCHAIN=0 and vcvarsall.bat has not been run. |
| 311 | win_sdk_dir = os.path.normpath( |
| 312 | os.environ.get( |
| 313 | 'WINDOWSSDKDIR', |
| 314 | os.path.expandvars('%ProgramFiles(x86)%' |
| 315 | '\\Windows Kits\\10'))) |
| 316 | # ARM64 doesn't have a redist for the ucrt DLLs because they are always |
| 317 | # present in the OS. |
| 318 | if target_cpu != 'arm64': |
| 319 | # Starting with the 10.0.17763 SDK the ucrt files are in a version-named |
| 320 | # directory - this handles both cases. |
| 321 | redist_dir = os.path.join(win_sdk_dir, 'Redist') |
| 322 | version_dirs = glob.glob(os.path.join(redist_dir, '10.*')) |
| 323 | if len(version_dirs) > 0: |
| 324 | _SortByHighestVersionNumberFirst(version_dirs) |
| 325 | redist_dir = version_dirs[0] |
| 326 | ucrt_dll_dirs = os.path.join(redist_dir, 'ucrt', 'DLLs', target_cpu) |
| 327 | ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll')) |
| 328 | assert len(ucrt_files) > 0 |
| 329 | for ucrt_src_file in ucrt_files: |
| 330 | file_part = os.path.basename(ucrt_src_file) |
| 331 | ucrt_dst_file = os.path.join(target_dir, file_part) |
| 332 | _CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False) |
| 333 | # We must copy ucrtbase.dll for x64/x86, and ucrtbased.dll for all CPU types. |
| 334 | if target_cpu != 'arm64' or not suffix.startswith('.'): |
| 335 | if not suffix.startswith('.'): |
| 336 | # ucrtbased.dll is located at {win_sdk_dir}/bin/{a.b.c.d}/{target_cpu}/ |
| 337 | # ucrt/. |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 338 | sdk_bin_root = os.path.join(win_sdk_dir, 'bin') |
| 339 | sdk_bin_sub_dirs = glob.glob(os.path.join(sdk_bin_root, '10.*')) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 340 | # Select the most recent SDK if there are multiple versions installed. |
| 341 | _SortByHighestVersionNumberFirst(sdk_bin_sub_dirs) |
| 342 | for directory in sdk_bin_sub_dirs: |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 343 | sdk_redist_root_version = os.path.join(sdk_bin_root, directory) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 344 | if not os.path.isdir(sdk_redist_root_version): |
| 345 | continue |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 346 | source_dir = os.path.join(sdk_redist_root_version, target_cpu, |
| 347 | 'ucrt') |
| 348 | break |
| 349 | _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix), |
| 350 | os.path.join(source_dir, 'ucrtbase' + suffix)) |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 351 | |
| 352 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 353 | def FindVCComponentRoot(component): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 354 | """Find the most recent Tools or Redist or other directory in an MSVC install. |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 355 | Typical results are {toolchain_root}/VC/{component}/MSVC/{x.y.z}. The {x.y.z} |
| 356 | version number part changes frequently so the highest version number found is |
| 357 | used. |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 358 | """ |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 359 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 360 | SetEnvironmentAndGetRuntimeDllDirs() |
| 361 | assert ('GYP_MSVS_OVERRIDE_PATH' in os.environ) |
| 362 | vc_component_msvc_root = os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'], |
| 363 | 'VC', component, 'MSVC') |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 364 | vc_component_msvc_contents = glob.glob( |
| 365 | os.path.join(vc_component_msvc_root, '14.*')) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 366 | # Select the most recent toolchain if there are several. |
| 367 | _SortByHighestVersionNumberFirst(vc_component_msvc_contents) |
| 368 | for directory in vc_component_msvc_contents: |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 369 | if os.path.isdir(directory): |
| 370 | return directory |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 371 | raise Exception('Unable to find the VC %s directory.' % component) |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 372 | |
| 373 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 374 | def FindVCRedistRoot(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 375 | """In >=VS2017, Redist binaries are located in |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 376 | {toolchain_root}/VC/Redist/MSVC/{x.y.z}/{target_cpu}/. |
| 377 | |
| 378 | This returns the '{toolchain_root}/VC/Redist/MSVC/{x.y.z}/' path. |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 379 | """ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 380 | return FindVCComponentRoot('Redist') |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 381 | |
| 382 | |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 383 | def _CopyRuntime(target_dir, source_dir, target_cpu, debug): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 384 | """Copy the VS runtime DLLs, only if the target doesn't exist, but the target |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 385 | directory does exist. Handles VS 2015, 2017 and 2019.""" |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 386 | suffix = 'd.dll' if debug else '.dll' |
| 387 | # VS 2015, 2017 and 2019 use the same CRT DLLs. |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 388 | _CopyUCRTRuntime(target_dir, source_dir, target_cpu, suffix) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 389 | |
| 390 | |
| 391 | def CopyDlls(target_dir, configuration, target_cpu): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 392 | """Copy the VS runtime DLLs into the requested directory as needed. |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 393 | |
| 394 | configuration is one of 'Debug' or 'Release'. |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 395 | target_cpu is one of 'x86', 'x64' or 'arm64'. |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 396 | |
| 397 | The debug configuration gets both the debug and release DLLs; the |
| 398 | release config only the latter. |
| 399 | """ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 400 | vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs() |
| 401 | if not vs_runtime_dll_dirs: |
| 402 | return |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 403 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 404 | x64_runtime, x86_runtime, arm64_runtime = vs_runtime_dll_dirs |
| 405 | if target_cpu == 'x64': |
| 406 | runtime_dir = x64_runtime |
| 407 | elif target_cpu == 'x86': |
| 408 | runtime_dir = x86_runtime |
| 409 | elif target_cpu == 'arm64': |
| 410 | runtime_dir = arm64_runtime |
| 411 | else: |
| 412 | raise Exception('Unknown target_cpu: ' + target_cpu) |
| 413 | _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False) |
| 414 | if configuration == 'Debug': |
| 415 | _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True) |
| 416 | _CopyDebugger(target_dir, target_cpu) |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 417 | |
| 418 | |
| 419 | def _CopyDebugger(target_dir, target_cpu): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 420 | """Copy dbghelp.dll and dbgcore.dll into the requested directory as needed. |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 421 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 422 | target_cpu is one of 'x86', 'x64' or 'arm64'. |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 423 | |
| 424 | dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file |
| 425 | from the SDK directory avoids using the system copy of dbghelp.dll which then |
| 426 | ensures compatibility with recent debug information formats, such as VS |
| 427 | 2017 /debug:fastlink PDBs. |
| 428 | |
| 429 | dbgcore.dll is needed when using some functions from dbghelp.dll (like |
| 430 | MinidumpWriteDump). |
| 431 | """ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 432 | win_sdk_dir = SetEnvironmentAndGetSDKDir() |
| 433 | if not win_sdk_dir: |
| 434 | return |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 435 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 436 | # List of debug files that should be copied, the first element of the tuple is |
| 437 | # the name of the file and the second indicates if it's optional. |
| 438 | debug_files = [('dbghelp.dll', False), ('dbgcore.dll', True)] |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 439 | # The UCRT is not a redistributable component on arm64. |
| 440 | if target_cpu != 'arm64': |
| 441 | debug_files.extend([('api-ms-win-downlevel-kernel32-l2-1-0.dll', False), |
| 442 | ('api-ms-win-eventing-provider-l1-1-0.dll', False)]) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 443 | for debug_file, is_optional in debug_files: |
| 444 | full_path = os.path.join(win_sdk_dir, 'Debuggers', target_cpu, |
| 445 | debug_file) |
| 446 | if not os.path.exists(full_path): |
| 447 | if is_optional: |
| 448 | continue |
| 449 | else: |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 450 | raise Exception( |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 451 | '%s not found in "%s"\r\nYou must install' |
| 452 | 'Windows 10 SDK version 10.0.19041.0 including the ' |
| 453 | '"Debugging Tools for Windows" feature.' % |
| 454 | (debug_file, full_path)) |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 455 | target_path = os.path.join(target_dir, debug_file) |
| 456 | _CopyRuntimeImpl(target_path, full_path) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 457 | |
| 458 | |
| 459 | def _GetDesiredVsToolchainHashes(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 460 | """Load a list of SHA1s corresponding to the toolchains that we want installed |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 461 | to build with.""" |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 462 | # Third parties that do not have access to the canonical toolchain can map |
| 463 | # canonical toolchain version to their own toolchain versions. |
| 464 | toolchain_hash_mapping_key = 'GYP_MSVS_HASH_%s' % TOOLCHAIN_HASH |
| 465 | return [os.environ.get(toolchain_hash_mapping_key, TOOLCHAIN_HASH)] |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 466 | |
| 467 | |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 468 | def ShouldUpdateToolchain(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 469 | """Check if the toolchain should be upgraded.""" |
| 470 | if not os.path.exists(json_data_file): |
| 471 | return True |
| 472 | with open(json_data_file, 'r') as tempf: |
| 473 | toolchain_data = json.load(tempf) |
| 474 | version = toolchain_data['version'] |
| 475 | env_version = GetVisualStudioVersion() |
| 476 | # If there's a mismatch between the version set in the environment and the one |
| 477 | # in the json file then the toolchain should be updated. |
| 478 | return version != env_version |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 479 | |
| 480 | |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 481 | def Update(force=False, no_download=False): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 482 | """Requests an update of the toolchain to the specific hashes we have at |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 483 | this revision. The update outputs a .json of the various configuration |
| 484 | information required to pass to gyp which we use in |GetToolchainDir()|. |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 485 | If no_download is true then the toolchain will be configured if present but |
| 486 | will not be downloaded. |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 487 | """ |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 488 | if force != False and force != '--force': |
| 489 | print('Unknown parameter "%s"' % force, file=sys.stderr) |
| 490 | return 1 |
| 491 | if force == '--force' or os.path.exists(json_data_file): |
| 492 | force = True |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 493 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 494 | depot_tools_win_toolchain = \ |
| 495 | bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))) |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 496 | if (_HostIsWindows() or force) and depot_tools_win_toolchain: |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 497 | import find_depot_tools |
| 498 | depot_tools_path = find_depot_tools.add_depot_tools_to_path() |
Alexander Aprelev | e7d71be | 2018-09-26 17:09:36 +0000 | [diff] [blame] | 499 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 500 | # On Linux, the file system is usually case-sensitive while the Windows |
| 501 | # SDK only works on case-insensitive file systems. If it doesn't already |
| 502 | # exist, set up a ciopfs fuse mount to put the SDK in a case-insensitive |
| 503 | # part of the file system. |
| 504 | toolchain_dir = os.path.join(depot_tools_path, 'win_toolchain', |
| 505 | 'vs_files') |
| 506 | # For testing this block, unmount existing mounts with |
| 507 | # fusermount -u third_party/depot_tools/win_toolchain/vs_files |
| 508 | if sys.platform.startswith( |
| 509 | 'linux') and not os.path.ismount(toolchain_dir): |
| 510 | import distutils.spawn |
| 511 | ciopfs = distutils.spawn.find_executable('ciopfs') |
| 512 | if not ciopfs: |
| 513 | # ciopfs not found in PATH; try the one downloaded from the DEPS hook. |
| 514 | ciopfs = os.path.join(script_dir, 'ciopfs') |
| 515 | if not os.path.isdir(toolchain_dir): |
| 516 | os.mkdir(toolchain_dir) |
| 517 | if not os.path.isdir(toolchain_dir + '.ciopfs'): |
| 518 | os.mkdir(toolchain_dir + '.ciopfs') |
| 519 | # Without use_ino, clang's #pragma once and Wnonportable-include-path |
| 520 | # both don't work right, see https://llvm.org/PR34931 |
| 521 | # use_ino doesn't slow down builds, so it seems there's no drawback to |
| 522 | # just using it always. |
| 523 | subprocess.check_call([ |
| 524 | ciopfs, '-o', 'use_ino', toolchain_dir + '.ciopfs', |
| 525 | toolchain_dir |
| 526 | ]) |
Alexander Aprelev | e7d71be | 2018-09-26 17:09:36 +0000 | [diff] [blame] | 527 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 528 | get_toolchain_args = [ |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 529 | # TODO(athom): use sys.executable (python3). |
Vyacheslav Egorov | f364c8b | 2021-05-21 11:04:22 +0000 | [diff] [blame] | 530 | # Note: depot_tools contains python.bat not python.exe |
| 531 | # so for python to land on the first python in the PATH |
| 532 | # irrespective of its extension we pass shell=True below. |
Alexander Thomas | b5c63ce | 2021-04-15 10:10:20 +0000 | [diff] [blame] | 533 | 'python', |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 534 | os.path.join(depot_tools_path, 'win_toolchain', |
| 535 | 'get_toolchain_if_necessary.py'), |
| 536 | '--output-json', |
| 537 | json_data_file, |
| 538 | ] + _GetDesiredVsToolchainHashes() |
| 539 | if force: |
| 540 | get_toolchain_args.append('--force') |
| 541 | if no_download: |
| 542 | get_toolchain_args.append('--no-download') |
Vyacheslav Egorov | f364c8b | 2021-05-21 11:04:22 +0000 | [diff] [blame] | 543 | subprocess.check_call(get_toolchain_args, shell=True) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 544 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 545 | return 0 |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 546 | |
| 547 | |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 548 | def NormalizePath(path): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 549 | while path.endswith('\\'): |
| 550 | path = path[:-1] |
| 551 | return path |
Zach Anderson | 9a6797e | 2016-10-04 09:19:07 -0700 | [diff] [blame] | 552 | |
| 553 | |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 554 | def SetEnvironmentAndGetSDKDir(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 555 | """Gets location information about the current sdk (must have been |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 556 | previously updated by 'update'). This is used for the GN build.""" |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 557 | SetEnvironmentAndGetRuntimeDllDirs() |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 558 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 559 | # If WINDOWSSDKDIR is not set, search the default SDK path and set it. |
| 560 | if not 'WINDOWSSDKDIR' in os.environ: |
| 561 | default_sdk_path = os.path.expandvars('%ProgramFiles(x86)%' |
| 562 | '\\Windows Kits\\10') |
| 563 | if os.path.isdir(default_sdk_path): |
| 564 | os.environ['WINDOWSSDKDIR'] = default_sdk_path |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 565 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 566 | return NormalizePath(os.environ['WINDOWSSDKDIR']) |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 567 | |
| 568 | |
| 569 | def GetToolchainDir(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 570 | """Gets location information about the current toolchain (must have been |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 571 | previously updated by 'update'). This is used for the GN build.""" |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 572 | runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs() |
| 573 | win_sdk_dir = SetEnvironmentAndGetSDKDir() |
Zach Anderson | 381c506 | 2017-09-28 09:25:37 +0000 | [diff] [blame] | 574 | |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 575 | print('''vs_path = %s |
Alexander Aprelev | e7d71be | 2018-09-26 17:09:36 +0000 | [diff] [blame] | 576 | sdk_path = %s |
| 577 | vs_version = %s |
| 578 | wdk_dir = %s |
| 579 | runtime_dirs = %s |
Alexander Aprelev | 521a106 | 2019-07-31 20:01:01 +0000 | [diff] [blame] | 580 | ''' % (ToGNString(NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH'])), |
| 581 | ToGNString(win_sdk_dir), ToGNString(GetVisualStudioVersion()), |
| 582 | ToGNString(NormalizePath(os.environ.get('WDK_DIR', ''))), |
| 583 | ToGNString(os.path.pathsep.join(runtime_dll_dirs or ['None'])))) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 584 | |
| 585 | |
| 586 | def main(): |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 587 | commands = { |
| 588 | 'update': Update, |
| 589 | 'get_toolchain_dir': GetToolchainDir, |
| 590 | 'copy_dlls': CopyDlls, |
| 591 | } |
| 592 | if len(sys.argv) < 2 or sys.argv[1] not in commands: |
| 593 | print('Expected one of: %s' % ', '.join(commands), file=sys.stderr) |
| 594 | return 1 |
| 595 | return commands[sys.argv[1]](*sys.argv[2:]) |
John McCutchan | 36af994 | 2016-07-01 11:09:28 -0700 | [diff] [blame] | 596 | |
| 597 | |
| 598 | if __name__ == '__main__': |
Nate Bosch | 55f81f2 | 2019-08-05 20:34:31 +0000 | [diff] [blame] | 599 | sys.exit(main()) |