• 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
21def SetEnvironmentAndGetRuntimeDllDirs():
22  """Sets up os.environ to use the depot_tools VS toolchain with gyp, and
23  returns the location of the VS runtime DLLs so they can be copied into
24  the output directory after gyp generation.
25  """
26  vs2013_runtime_dll_dirs = None
27  depot_tools_win_toolchain = \
28      bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
29  if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
30    if not os.path.exists(json_data_file):
31      Update()
32    with open(json_data_file, 'r') as tempf:
33      toolchain_data = json.load(tempf)
34
35    toolchain = toolchain_data['path']
36    version = toolchain_data['version']
37    win_sdk = toolchain_data.get('win_sdk')
38    if not win_sdk:
39      win_sdk = toolchain_data['win8sdk']
40    wdk = toolchain_data['wdk']
41    # TODO(scottmg): The order unfortunately matters in these. They should be
42    # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
43    # below). http://crbug.com/345992
44    vs2013_runtime_dll_dirs = toolchain_data['runtime_dirs']
45
46    os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
47    os.environ['GYP_MSVS_VERSION'] = version
48    # We need to make sure windows_sdk_path is set to the automated
49    # toolchain values in GYP_DEFINES, but don't want to override any
50    # otheroptions.express
51    # values there.
52    gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
53    gyp_defines_dict['windows_sdk_path'] = win_sdk
54    os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
55        for k, v in gyp_defines_dict.iteritems())
56    os.environ['WINDOWSSDKDIR'] = win_sdk
57    os.environ['WDK_DIR'] = wdk
58    # Include the VS runtime in the PATH in case it's not machine-installed.
59    runtime_path = ';'.join(vs2013_runtime_dll_dirs)
60    os.environ['PATH'] = runtime_path + ';' + os.environ['PATH']
61  return vs2013_runtime_dll_dirs
62
63
64def _GetDesiredVsToolchainHashes():
65  """Load a list of SHA1s corresponding to the toolchains that we want installed
66  to build with."""
67  # Use Chromium's VS2013.
68  return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef']
69
70
71def FindDepotTools():
72  """Returns the path to depot_tools in $PATH."""
73  for path in os.environ['PATH'].split(os.pathsep):
74    if os.path.isfile(os.path.join(path, 'gclient.py')):
75      return path
76  raise Exception("depot_tools not found!")
77
78
79def Update():
80  """Requests an update of the toolchain to the specific hashes we have at
81  this revision. The update outputs a .json of the various configuration
82  information required to pass to gyp which we use in |GetToolchainDir()|.
83  """
84  depot_tools_win_toolchain = \
85      bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
86  if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
87    depot_tools_path = FindDepotTools()
88    get_toolchain_args = [
89        sys.executable,
90        os.path.join(depot_tools_path,
91                    'win_toolchain',
92                    'get_toolchain_if_necessary.py'),
93        '--output-json', json_data_file,
94      ] + _GetDesiredVsToolchainHashes()
95    subprocess.check_call(get_toolchain_args)
96
97  return 0
98
99
100def main():
101  if not sys.platform.startswith(('win32', 'cygwin')):
102    return 0
103  commands = {
104      'update': Update,
105  }
106  if len(sys.argv) < 2 or sys.argv[1] not in commands:
107    print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands)
108    return 1
109  return commands[sys.argv[1]](*sys.argv[2:])
110
111
112if __name__ == '__main__':
113  sys.exit(main())
114