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

Side by Side Diff: build/vs_toolchain.py

Issue 2878693002: Make the PGO profiling step work with VS2017 (Closed)
Patch Set: Rebase Created 3 years, 7 months 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 | « no previous file | build/win/run_pgo_profiling_benchmarks.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 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 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import glob 6 import glob
7 import json 7 import json
8 import os 8 import os
9 import pipes 9 import pipes
10 import platform 10 import platform
11 import re
11 import shutil 12 import shutil
12 import stat 13 import stat
13 import subprocess 14 import subprocess
14 import sys 15 import sys
15 16
16 17
17 script_dir = os.path.dirname(os.path.realpath(__file__)) 18 script_dir = os.path.dirname(os.path.realpath(__file__))
18 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir)) 19 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir))
19 SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 20 SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
20 sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib')) 21 sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib'))
(...skipping 23 matching lines...) Expand all
44 with open(json_data_file, 'r') as tempf: 45 with open(json_data_file, 'r') as tempf:
45 toolchain_data = json.load(tempf) 46 toolchain_data = json.load(tempf)
46 47
47 toolchain = toolchain_data['path'] 48 toolchain = toolchain_data['path']
48 version = toolchain_data['version'] 49 version = toolchain_data['version']
49 win_sdk = toolchain_data.get('win_sdk') 50 win_sdk = toolchain_data.get('win_sdk')
50 if not win_sdk: 51 if not win_sdk:
51 win_sdk = toolchain_data['win8sdk'] 52 win_sdk = toolchain_data['win8sdk']
52 wdk = toolchain_data['wdk'] 53 wdk = toolchain_data['wdk']
53 # TODO(scottmg): The order unfortunately matters in these. They should be 54 # TODO(scottmg): The order unfortunately matters in these. They should be
54 # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call 55 # split into separate keys for x86 and x64. (See CopyDlls call below).
55 # below). http://crbug.com/345992 56 # http://crbug.com/345992
56 vs_runtime_dll_dirs = toolchain_data['runtime_dirs'] 57 vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
57 58
58 os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain 59 os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
59 os.environ['GYP_MSVS_VERSION'] = version 60 os.environ['GYP_MSVS_VERSION'] = version
60 61
61 # Limit the scope of the gyp import to only where it is used. This 62 # Limit the scope of the gyp import to only where it is used. This
62 # potentially lets build configs that never execute this block to drop 63 # potentially lets build configs that never execute this block to drop
63 # their GYP checkout. 64 # their GYP checkout.
64 import gyp 65 import gyp
65 66
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 path = _RegistryGetValue(key, 'InstallDir') 164 path = _RegistryGetValue(key, 'InstallDir')
164 if not path: 165 if not path:
165 continue 166 continue
166 path = os.path.normpath(os.path.join(path, '..', '..')) 167 path = os.path.normpath(os.path.join(path, '..', '..'))
167 return path 168 return path
168 169
169 raise Exception(('Visual Studio Version %s (from GYP_MSVS_VERSION)' 170 raise Exception(('Visual Studio Version %s (from GYP_MSVS_VERSION)'
170 ' not found.') % (version_as_year)) 171 ' not found.') % (version_as_year))
171 172
172 173
173 def _VersionNumber():
174 """Gets the standard version number ('120', '140', etc.) based on
175 GYP_MSVS_VERSION."""
176 vs_version = GetVisualStudioVersion()
177 if vs_version == '2015':
178 return '140'
179 if vs_version == '2017':
180 return '150'
181 raise ValueError('Unexpected GYP_MSVS_VERSION')
182
183
184 def _CopyRuntimeImpl(target, source, verbose=True): 174 def _CopyRuntimeImpl(target, source, verbose=True):
185 """Copy |source| to |target| if it doesn't already exist or if it needs to be 175 """Copy |source| to |target| if it doesn't already exist or if it needs to be
186 updated (comparing last modified time as an approximate float match as for 176 updated (comparing last modified time as an approximate float match as for
187 some reason the values tend to differ by ~1e-07 despite being copies of the 177 some reason the values tend to differ by ~1e-07 despite being copies of the
188 same file... https://crbug.com/603603). 178 same file... https://crbug.com/603603).
189 """ 179 """
190 if (os.path.isdir(os.path.dirname(target)) and 180 if (os.path.isdir(os.path.dirname(target)) and
191 (not os.path.isfile(target) or 181 (not os.path.isfile(target) or
192 abs(os.stat(target).st_mtime - os.stat(source).st_mtime) >= 0.01)): 182 abs(os.stat(target).st_mtime - os.stat(source).st_mtime) >= 0.01)):
193 if verbose: 183 if verbose:
(...skipping 27 matching lines...) Expand all
221 ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll')) 211 ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll'))
222 assert len(ucrt_files) > 0 212 assert len(ucrt_files) > 0
223 for ucrt_src_file in ucrt_files: 213 for ucrt_src_file in ucrt_files:
224 file_part = os.path.basename(ucrt_src_file) 214 file_part = os.path.basename(ucrt_src_file)
225 ucrt_dst_file = os.path.join(target_dir, file_part) 215 ucrt_dst_file = os.path.join(target_dir, file_part)
226 _CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False) 216 _CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False)
227 _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix), 217 _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
228 os.path.join(source_dir, 'ucrtbase' + suffix)) 218 os.path.join(source_dir, 'ucrtbase' + suffix))
229 219
230 220
221 def _CopyPGORuntime(target_dir, target_cpu):
222 """Copy the runtime dependencies required during a PGO build.
223 """
224 env_version = GetVisualStudioVersion()
225 # These dependencies will be in a different location depending on the version
226 # of the toolchain.
227 if env_version == '2015':
228 pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
229 'VC', 'bin')
230 pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
231 elif env_version == '2017':
232 # In VS2017 the PGO runtime dependencies are located in
233 # {toolchain_root}/VC/Tools/MSVC/{x.y.z}/Host{target_cpu}/{target_cpu}, the
scottmg 2017/05/11 19:30:28 This comment is missing a "bin/" I think.
Sébastien Marchand 2017/05/11 20:15:35 yep, fixed.
234 # {version_number} part is likely to change in case of a minor update of the
235 # toolchain so we don't hardcode this value here (except for the major
236 # number).
237 vc_tool_msvc_root = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
scottmg 2017/05/11 19:30:28 vc_tools_msvc_root (with an 'S') to match the path
Sébastien Marchand 2017/05/11 20:15:35 Done.
238 'VC', 'Tools', 'MSVC')
239 pgo_runtime_root = None
240 for directory in os.listdir(vc_tool_msvc_root):
241 if not os.path.isdir(os.path.join(vc_tool_msvc_root, directory)):
242 continue
243 if re.match('14\.\d+\.\d+', directory):
244 pgo_runtime_root = os.path.join(vc_tool_msvc_root, directory, 'bin')
245 break
246 assert pgo_runtime_root
247 pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86')
scottmg 2017/05/11 19:30:28 HostX86 should be HostX64, as we only want target
Sébastien Marchand 2017/05/11 20:15:35 Done.
248 pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64')
249 else:
250 raise Exception('Unexpected toolchain version: %s.' % env_version)
251
252 # We need to copy 2 runtime dependencies used during the profiling step:
253 # - pgort140.dll: runtime library required to run the instrumented image.
254 # - pgosweep.exe: executable used to collect the profiling data
255 pgo_runtimes = ['pgort140.dll', 'pgosweep.exe']
256 for runtime in pgo_runtimes:
257 if target_cpu == 'x86':
258 source = os.path.join(pgo_x86_runtime_dir, runtime)
259 elif target_cpu == 'x64':
260 source = os.path.join(pgo_x64_runtime_dir, runtime)
261 else:
262 raise NotImplementedError("Unexpected target_cpu value: " + target_cpu)
263 if not os.path.exists(source):
264 raise Exception('Unable to find %s.' % source)
265 _CopyRuntimeImpl(os.path.join(target_dir, runtime), source)
266
267
231 def _CopyRuntime(target_dir, source_dir, target_cpu, debug): 268 def _CopyRuntime(target_dir, source_dir, target_cpu, debug):
232 """Copy the VS runtime DLLs, only if the target doesn't exist, but the target 269 """Copy the VS runtime DLLs, only if the target doesn't exist, but the target
233 directory does exist. Handles VS 2015 and VS 2017.""" 270 directory does exist. Handles VS 2015 and VS 2017."""
234 suffix = "d.dll" if debug else ".dll" 271 suffix = "d.dll" if debug else ".dll"
235 # VS 2017 uses the same CRT DLLs as VS 2015. 272 # VS 2017 uses the same CRT DLLs as VS 2015.
236 _CopyUCRTRuntime(target_dir, source_dir, target_cpu, '%s140' + suffix, 273 _CopyUCRTRuntime(target_dir, source_dir, target_cpu, '%s140' + suffix,
237 suffix) 274 suffix)
238 275
239 # Copy the PGO runtime library to the release directories.
240 if not debug and os.environ.get('GYP_MSVS_OVERRIDE_PATH'):
241 pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
242 'VC', 'bin')
243 pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
244 pgo_runtime_dll = 'pgort' + _VersionNumber() + '.dll'
245 if target_cpu == "x86":
246 source_x86 = os.path.join(pgo_x86_runtime_dir, pgo_runtime_dll)
247 if os.path.exists(source_x86):
248 _CopyRuntimeImpl(os.path.join(target_dir, pgo_runtime_dll), source_x86)
249 elif target_cpu == "x64":
250 source_x64 = os.path.join(pgo_x64_runtime_dir, pgo_runtime_dll)
251 if os.path.exists(source_x64):
252 _CopyRuntimeImpl(os.path.join(target_dir, pgo_runtime_dll),
253 source_x64)
254 else:
255 raise NotImplementedError("Unexpected target_cpu value:" + target_cpu)
256
257
258 def CopyVsRuntimeDlls(output_dir, runtime_dirs):
scottmg 2017/05/11 19:30:28 https://cs.chromium.org/search/?q=CopyVsRuntimeDll
Sébastien Marchand 2017/05/11 20:15:35 Yeah, and the call to this function is behind a "i
259 """Copies the VS runtime DLLs from the given |runtime_dirs| to the output
260 directory so that even if not system-installed, built binaries are likely to
261 be able to run.
262
263 This needs to be run after gyp has been run so that the expected target
264 output directories are already created.
265
266 This is used for the GYP build and gclient runhooks.
267 """
268 x86, x64 = runtime_dirs
269 out_debug = os.path.join(output_dir, 'Debug')
270 out_debug_nacl64 = os.path.join(output_dir, 'Debug', 'x64')
271 out_release = os.path.join(output_dir, 'Release')
272 out_release_nacl64 = os.path.join(output_dir, 'Release', 'x64')
273 out_debug_x64 = os.path.join(output_dir, 'Debug_x64')
274 out_release_x64 = os.path.join(output_dir, 'Release_x64')
275
276 if os.path.exists(out_debug) and not os.path.exists(out_debug_nacl64):
277 os.makedirs(out_debug_nacl64)
278 if os.path.exists(out_release) and not os.path.exists(out_release_nacl64):
279 os.makedirs(out_release_nacl64)
280 _CopyRuntime(out_debug, x86, "x86", debug=True)
281 _CopyRuntime(out_release, x86, "x86", debug=False)
282 _CopyRuntime(out_debug_x64, x64, "x64", debug=True)
283 _CopyRuntime(out_release_x64, x64, "x64", debug=False)
284 _CopyRuntime(out_debug_nacl64, x64, "x64", debug=True)
285 _CopyRuntime(out_release_nacl64, x64, "x64", debug=False)
286
287 276
288 def CopyDlls(target_dir, configuration, target_cpu): 277 def CopyDlls(target_dir, configuration, target_cpu):
289 """Copy the VS runtime DLLs into the requested directory as needed. 278 """Copy the VS runtime DLLs into the requested directory as needed.
290 279
291 configuration is one of 'Debug' or 'Release'. 280 configuration is one of 'Debug' or 'Release'.
292 target_cpu is one of 'x86' or 'x64'. 281 target_cpu is one of 'x86' or 'x64'.
293 282
294 The debug configuration gets both the debug and release DLLs; the 283 The debug configuration gets both the debug and release DLLs; the
295 release config only the latter. 284 release config only the latter.
296
297 This is used for the GN build.
298 """ 285 """
299 vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs() 286 vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
300 if not vs_runtime_dll_dirs: 287 if not vs_runtime_dll_dirs:
301 return 288 return
302 289
303 x64_runtime, x86_runtime = vs_runtime_dll_dirs 290 x64_runtime, x86_runtime = vs_runtime_dll_dirs
304 runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime 291 runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime
305 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False) 292 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
306 if configuration == 'Debug': 293 if configuration == 'Debug':
307 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True) 294 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
295 else:
296 _CopyPGORuntime(target_dir, target_cpu)
308 297
309 _CopyDebugger(target_dir, target_cpu) 298 _CopyDebugger(target_dir, target_cpu)
310 299
311 300
312 def _CopyDebugger(target_dir, target_cpu): 301 def _CopyDebugger(target_dir, target_cpu):
313 """Copy dbghelp.dll into the requested directory as needed. 302 """Copy dbghelp.dll into the requested directory as needed.
314 303
315 target_cpu is one of 'x86' or 'x64'. 304 target_cpu is one of 'x86' or 'x64'.
316 305
317 dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file 306 dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 'copy_dlls': CopyDlls, 428 'copy_dlls': CopyDlls,
440 } 429 }
441 if len(sys.argv) < 2 or sys.argv[1] not in commands: 430 if len(sys.argv) < 2 or sys.argv[1] not in commands:
442 print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands) 431 print >>sys.stderr, 'Expected one of: %s' % ', '.join(commands)
443 return 1 432 return 1
444 return commands[sys.argv[1]](*sys.argv[2:]) 433 return commands[sys.argv[1]](*sys.argv[2:])
445 434
446 435
447 if __name__ == '__main__': 436 if __name__ == '__main__':
448 sys.exit(main()) 437 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | build/win/run_pgo_profiling_benchmarks.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698