Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(884)

Side by Side Diff: build/vs_toolchain.py

Issue 1237803003: Use msvs toolchain from depot_tools. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Adding a landmine Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/standalone.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2015 the V8 project authors. All rights reserved.
3 # Copyright 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 import json
8 import os
9 import pipes
10 import shutil
11 import subprocess
12 import sys
13 import vs_toolchain
14
15
16 script_dir = os.path.dirname(os.path.realpath(__file__))
17 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir))
18 SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
19 sys.path.insert(1, os.path.join(chrome_src, 'tools'))
20 sys.path.insert(0, os.path.join(chrome_src, 'build', 'gyp', 'pylib'))
21 json_data_file = os.path.join(script_dir, 'win_toolchain.json')
22
23
24 import gyp
25
26
27 def SetEnvironmentAndGetRuntimeDllDirs():
28 """Sets up os.environ to use the depot_tools VS toolchain with gyp, and
29 returns the location of the VS runtime DLLs so they can be copied into
30 the output directory after gyp generation.
31 """
32 vs2013_runtime_dll_dirs = None
33 depot_tools_win_toolchain = \
34 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
35 # When running on a non-Windows host, only do this if the SDK has explicitly
36 # been downloaded before (in which case json_data_file will exist).
37 if ((sys.platform in ('win32', 'cygwin') or os.path.exists(json_data_file))
38 and depot_tools_win_toolchain):
39 if not os.path.exists(json_data_file):
40 Update()
41 with open(json_data_file, 'r') as tempf:
42 toolchain_data = json.load(tempf)
43
44 toolchain = toolchain_data['path']
45 version = toolchain_data['version']
46 win_sdk = toolchain_data.get('win_sdk')
47 if not win_sdk:
48 win_sdk = toolchain_data['win8sdk']
49 wdk = toolchain_data['wdk']
50 # TODO(scottmg): The order unfortunately matters in these. They should be
51 # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
52 # below). http://crbug.com/345992
53 vs2013_runtime_dll_dirs = toolchain_data['runtime_dirs']
54
55 os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
56 os.environ['GYP_MSVS_VERSION'] = version
57 # We need to make sure windows_sdk_path is set to the automated
58 # toolchain values in GYP_DEFINES, but don't want to override any
59 # otheroptions.express
60 # values there.
61 gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
62 gyp_defines_dict['windows_sdk_path'] = win_sdk
63 os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
64 for k, v in gyp_defines_dict.iteritems())
65 os.environ['WINDOWSSDKDIR'] = win_sdk
66 os.environ['WDK_DIR'] = wdk
67 # Include the VS runtime in the PATH in case it's not machine-installed.
68 runtime_path = ';'.join(vs2013_runtime_dll_dirs)
69 os.environ['PATH'] = runtime_path + ';' + os.environ['PATH']
70 return vs2013_runtime_dll_dirs
71
72
73 def _VersionNumber():
74 """Gets the standard version number ('120', '140', etc.) based on
75 GYP_MSVS_VERSION."""
76 if os.environ['GYP_MSVS_VERSION'] == '2013':
77 return '120'
78 elif os.environ['GYP_MSVS_VERSION'] == '2015':
79 return '140'
80 else:
81 raise ValueError('Unexpected GYP_MSVS_VERSION')
82
83
84 def _CopyRuntimeImpl(target, source):
85 """Copy |source| to |target| if it doesn't already exist or if it
86 needs to be updated.
87 """
88 if (os.path.isdir(os.path.dirname(target)) and
89 (not os.path.isfile(target) or
90 os.stat(target).st_mtime != os.stat(source).st_mtime)):
91 print 'Copying %s to %s...' % (source, target)
92 if os.path.exists(target):
93 os.unlink(target)
94 shutil.copy2(source, target)
95
96
97 def _CopyRuntime2013(target_dir, source_dir, dll_pattern):
98 """Copy both the msvcr and msvcp runtime DLLs, only if the target doesn't
99 exist, but the target directory does exist."""
100 for file_part in ('p', 'r'):
101 dll = dll_pattern % file_part
102 target = os.path.join(target_dir, dll)
103 source = os.path.join(source_dir, dll)
104 _CopyRuntimeImpl(target, source)
105
106
107 def _CopyRuntime2015(target_dir, source_dir, dll_pattern):
108 """Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't
109 exist, but the target directory does exist."""
110 for file_part in ('msvcp', 'vccorlib'):
111 dll = dll_pattern % file_part
112 target = os.path.join(target_dir, dll)
113 source = os.path.join(source_dir, dll)
114 _CopyRuntimeImpl(target, source)
115
116
117 def CopyVsRuntimeDlls(output_dir, runtime_dirs):
118 """Copies the VS runtime DLLs from the given |runtime_dirs| to the output
119 directory so that even if not system-installed, built binaries are likely to
120 be able to run.
121
122 This needs to be run after gyp has been run so that the expected target
123 output directories are already created.
124 """
125 x86, x64 = runtime_dirs
126 out_debug = os.path.join(output_dir, 'Debug')
127 out_debug_nacl64 = os.path.join(output_dir, 'Debug', 'x64')
128 out_release = os.path.join(output_dir, 'Release')
129 out_release_nacl64 = os.path.join(output_dir, 'Release', 'x64')
130 out_debug_x64 = os.path.join(output_dir, 'Debug_x64')
131 out_release_x64 = os.path.join(output_dir, 'Release_x64')
132
133 if os.path.exists(out_debug) and not os.path.exists(out_debug_nacl64):
134 os.makedirs(out_debug_nacl64)
135 if os.path.exists(out_release) and not os.path.exists(out_release_nacl64):
136 os.makedirs(out_release_nacl64)
137 if os.environ.get('GYP_MSVS_VERSION') == '2015':
138 _CopyRuntime2015(out_debug, x86, '%s140d.dll')
139 _CopyRuntime2015(out_release, x86, '%s140.dll')
140 _CopyRuntime2015(out_debug_x64, x64, '%s140d.dll')
141 _CopyRuntime2015(out_release_x64, x64, '%s140.dll')
142 _CopyRuntime2015(out_debug_nacl64, x64, '%s140d.dll')
143 _CopyRuntime2015(out_release_nacl64, x64, '%s140.dll')
144 else:
145 # VS2013 is the default.
146 _CopyRuntime2013(out_debug, x86, 'msvc%s120d.dll')
147 _CopyRuntime2013(out_release, x86, 'msvc%s120.dll')
148 _CopyRuntime2013(out_debug_x64, x64, 'msvc%s120d.dll')
149 _CopyRuntime2013(out_release_x64, x64, 'msvc%s120.dll')
150 _CopyRuntime2013(out_debug_nacl64, x64, 'msvc%s120d.dll')
151 _CopyRuntime2013(out_release_nacl64, x64, 'msvc%s120.dll')
152
153 # Copy the PGO runtime library to the release directories.
154 if os.environ.get('GYP_MSVS_OVERRIDE_PATH'):
155 pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
156 'VC', 'bin')
157 pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
158 pgo_runtime_dll = 'pgort' + _VersionNumber() + '.dll'
159 source_x86 = os.path.join(pgo_x86_runtime_dir, pgo_runtime_dll)
160 if os.path.exists(source_x86):
161 _CopyRuntimeImpl(os.path.join(out_release, pgo_runtime_dll), source_x86)
162 source_x64 = os.path.join(pgo_x64_runtime_dir, pgo_runtime_dll)
163 if os.path.exists(source_x64):
164 _CopyRuntimeImpl(os.path.join(out_release_x64, pgo_runtime_dll),
165 source_x64)
166
167
168 def CopyDlls(target_dir, configuration, target_cpu):
169 """Copy the VS runtime DLLs into the requested directory as needed.
170
171 configuration is one of 'Debug' or 'Release'.
172 target_cpu is one of 'x86' or 'x64'.
173
174 The debug configuration gets both the debug and release DLLs; the
175 release config only the latter.
176 """
177 vs2013_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
178 if not vs2013_runtime_dll_dirs:
179 return
180
181 x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
182 runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime
183 _CopyRuntime2013(
184 target_dir, runtime_dir, 'msvc%s' + _VersionNumber() + '.dll')
185 if configuration == 'Debug':
186 _CopyRuntime2013(
187 target_dir, runtime_dir, 'msvc%s' + _VersionNumber() + 'd.dll')
188
189
190 def _GetDesiredVsToolchainHashes():
191 """Load a list of SHA1s corresponding to the toolchains that we want installed
192 to build with."""
193 if os.environ.get('GYP_MSVS_VERSION') == '2015':
194 return ['49ae4b60d898182fc3f521c2fcda82c453915011']
195 else:
196 # Default to VS2013.
197 return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef']
198
199
200 def Update(force=False):
201 """Requests an update of the toolchain to the specific hashes we have at
202 this revision. The update outputs a .json of the various configuration
203 information required to pass to gyp which we use in |GetToolchainDir()|.
204 """
205 if force != False and force != '--force':
206 print >>sys.stderr, 'Unknown parameter "%s"' % force
207 return 1
208 if force == '--force' or os.path.exists(json_data_file):
209 force = True
210
211 depot_tools_win_toolchain = \
212 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
213 if ((sys.platform in ('win32', 'cygwin') or force) and
214 depot_tools_win_toolchain):
215 import find_depot_tools
216 depot_tools_path = find_depot_tools.add_depot_tools_to_path()
217 get_toolchain_args = [
218 sys.executable,
219 os.path.join(depot_tools_path,
220 'win_toolchain',
221 'get_toolchain_if_necessary.py'),
222 '--output-json', json_data_file,
223 ] + _GetDesiredVsToolchainHashes()
224 if force:
225 get_toolchain_args.append('--force')
226 subprocess.check_call(get_toolchain_args)
227
228 return 0
229
230
231 def GetToolchainDir():
232 """Gets location information about the current toolchain (must have been
233 previously updated by 'update'). This is used for the GN build."""
234 runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
235
236 # If WINDOWSSDKDIR is not set, search the default SDK path and set it.
237 if not 'WINDOWSSDKDIR' in os.environ:
238 default_sdk_path = 'C:\\Program Files (x86)\\Windows Kits\\8.1'
239 if os.path.isdir(default_sdk_path):
240 os.environ['WINDOWSSDKDIR'] = default_sdk_path
241
242 print '''vs_path = "%s"
243 sdk_path = "%s"
244 vs_version = "%s"
245 wdk_dir = "%s"
246 runtime_dirs = "%s"
247 ''' % (
248 os.environ['GYP_MSVS_OVERRIDE_PATH'],
249 os.environ['WINDOWSSDKDIR'],
250 os.environ['GYP_MSVS_VERSION'],
251 os.environ.get('WDK_DIR', ''),
252 ';'.join(runtime_dll_dirs or ['None']))
253
254
255 def main():
256 commands = {
257 'update': Update,
258 'get_toolchain_dir': GetToolchainDir,
259 'copy_dlls': CopyDlls,
260 }
261 if len(sys.argv) < 2 or sys.argv[1] not in commands:
262 print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands)
263 return 1
264 return commands[sys.argv[1]](*sys.argv[2:])
265
266
267 if __name__ == '__main__':
268 sys.exit(main())
OLDNEW
« no previous file with comments | « build/standalone.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698