• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import json
6import os
7import pipes
8import shutil
9import subprocess
10import sys
11
12
13script_dir = os.path.dirname(os.path.realpath(__file__))
14sys.path.insert(0, os.path.join(script_dir, 'gyp', 'pylib'))
15json_data_file = os.path.join(script_dir, 'win_toolchain.json')
16
17
18import gyp
19
20
21# Use MSVS2015 as the default toolchain.
22CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2015'
23
24
25def SetEnvironmentAndGetRuntimeDllDirs():
26  """Sets up os.environ to use the depot_tools VS toolchain with gyp, and
27  returns the location of the VS runtime DLLs so they can be copied into
28  the output directory after gyp generation.
29  """
30  vs_runtime_dll_dirs = None
31  depot_tools_win_toolchain = \
32      bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
33  if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
34    if not os.path.exists(json_data_file):
35      Update()
36    with open(json_data_file, 'r') as tempf:
37      toolchain_data = json.load(tempf)
38
39    toolchain = toolchain_data['path']
40    version = toolchain_data['version']
41    win_sdk = toolchain_data.get('win_sdk')
42    if not win_sdk:
43      win_sdk = toolchain_data['win8sdk']
44    wdk = toolchain_data['wdk']
45    # TODO(scottmg): The order unfortunately matters in these. They should be
46    # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
47    # below). http://crbug.com/345992
48    vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
49
50    os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
51    os.environ['GYP_MSVS_VERSION'] = version
52    # We need to make sure windows_sdk_path is set to the automated
53    # toolchain values in GYP_DEFINES, but don't want to override any
54    # otheroptions.express
55    # values there.
56    gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
57    gyp_defines_dict['windows_sdk_path'] = win_sdk
58    os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
59        for k, v in gyp_defines_dict.iteritems())
60    os.environ['WINDOWSSDKDIR'] = win_sdk
61    os.environ['WDK_DIR'] = wdk
62    # Include the VS runtime in the PATH in case it's not machine-installed.
63    runtime_path = ';'.join(vs_runtime_dll_dirs)
64    os.environ['PATH'] = runtime_path + ';' + os.environ['PATH']
65  return vs_runtime_dll_dirs
66
67
68def FindDepotTools():
69  """Returns the path to depot_tools in $PATH."""
70  for path in os.environ['PATH'].split(os.pathsep):
71    if os.path.isfile(os.path.join(path, 'gclient.py')):
72      return path
73  raise Exception("depot_tools not found!")
74
75
76def GetVisualStudioVersion():
77  """Return GYP_MSVS_VERSION of Visual Studio.
78  """
79  return os.environ.get('GYP_MSVS_VERSION', CURRENT_DEFAULT_TOOLCHAIN_VERSION)
80
81
82def _GetDesiredVsToolchainHashes():
83  """Load a list of SHA1s corresponding to the toolchains that we want installed
84  to build with."""
85  env_version = GetVisualStudioVersion()
86  if env_version == '2015':
87    # Update 3 final with 10.0.15063.468 SDK and no vctip.exe.
88    return ['f53e4598951162bad6330f7a167486c7ae5db1e5']
89  if env_version == '2017':
90    # VS 2017 Update 9 (15.9.12) with 10.0.18362 SDK, 10.0.17763 version of
91    # Debuggers, and 10.0.17134 version of d3dcompiler_47.dll, with ARM64
92    # libraries.
93    return ['418b3076791776573a815eb298c8aa590307af63']
94  raise Exception('Unsupported VS version %s' % env_version)
95
96
97def Update():
98  """Requests an update of the toolchain to the specific hashes we have at
99  this revision. The update outputs a .json of the various configuration
100  information required to pass to gyp which we use in |GetToolchainDir()|.
101  """
102  depot_tools_win_toolchain = \
103      bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
104  if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
105    depot_tools_path = FindDepotTools()
106    # Necessary so that get_toolchain_if_necessary.py will put the VS toolkit
107    # in the correct directory.
108    os.environ['GYP_MSVS_VERSION'] = GetVisualStudioVersion()
109    get_toolchain_args = [
110        sys.executable,
111        os.path.join(depot_tools_path,
112                    'win_toolchain',
113                    'get_toolchain_if_necessary.py'),
114        '--output-json', json_data_file,
115      ] + _GetDesiredVsToolchainHashes()
116    subprocess.check_call(get_toolchain_args)
117
118  return 0
119
120
121def main():
122  if not sys.platform.startswith(('win32', 'cygwin')):
123    return 0
124  commands = {
125      'update': Update,
126  }
127  if len(sys.argv) < 2 or sys.argv[1] not in commands:
128    print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands)
129    return 1
130  return commands[sys.argv[1]](*sys.argv[2:])
131
132
133if __name__ == '__main__':
134  sys.exit(main())
135