OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2013 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 |
| 5 # This file copies the logic from GYP to find the MSVC configuration. It's not |
| 6 # currently used because it is too slow. We will probably build this |
| 7 # functionality into the C++ code in the future. |
| 8 |
| 9 """Handle version information related to Visual Stuio.""" |
| 10 |
| 11 import errno |
| 12 import os |
| 13 import re |
| 14 import subprocess |
| 15 import sys |
| 16 |
| 17 class VisualStudioVersion(object): |
| 18 """Information regarding a version of Visual Studio.""" |
| 19 |
| 20 def __init__(self, short_name, description, |
| 21 solution_version, project_version, flat_sln, uses_vcxproj, |
| 22 path, sdk_based, default_toolset=None): |
| 23 self.short_name = short_name |
| 24 self.description = description |
| 25 self.solution_version = solution_version |
| 26 self.project_version = project_version |
| 27 self.flat_sln = flat_sln |
| 28 self.uses_vcxproj = uses_vcxproj |
| 29 self.path = path |
| 30 self.sdk_based = sdk_based |
| 31 self.default_toolset = default_toolset |
| 32 |
| 33 def ShortName(self): |
| 34 return self.short_name |
| 35 |
| 36 def Description(self): |
| 37 """Get the full description of the version.""" |
| 38 return self.description |
| 39 |
| 40 def SolutionVersion(self): |
| 41 """Get the version number of the sln files.""" |
| 42 return self.solution_version |
| 43 |
| 44 def ProjectVersion(self): |
| 45 """Get the version number of the vcproj or vcxproj files.""" |
| 46 return self.project_version |
| 47 |
| 48 def FlatSolution(self): |
| 49 return self.flat_sln |
| 50 |
| 51 def UsesVcxproj(self): |
| 52 """Returns true if this version uses a vcxproj file.""" |
| 53 return self.uses_vcxproj |
| 54 |
| 55 def ProjectExtension(self): |
| 56 """Returns the file extension for the project.""" |
| 57 return self.uses_vcxproj and '.vcxproj' or '.vcproj' |
| 58 |
| 59 def Path(self): |
| 60 """Returns the path to Visual Studio installation.""" |
| 61 return self.path |
| 62 |
| 63 def ToolPath(self, tool): |
| 64 """Returns the path to a given compiler tool. """ |
| 65 return os.path.normpath(os.path.join(self.path, "VC/bin", tool)) |
| 66 |
| 67 def DefaultToolset(self): |
| 68 """Returns the msbuild toolset version that will be used in the absence |
| 69 of a user override.""" |
| 70 return self.default_toolset |
| 71 |
| 72 def SetupScript(self, target_arch): |
| 73 """Returns a command (with arguments) to be used to set up the |
| 74 environment.""" |
| 75 # Check if we are running in the SDK command line environment and use |
| 76 # the setup script from the SDK if so. |target_arch| should be either |
| 77 # 'x86' or 'x64'. |
| 78 assert target_arch in ('x86', 'x64') |
| 79 sdk_dir = os.environ.get('WindowsSDKDir') |
| 80 if self.sdk_based and sdk_dir: |
| 81 return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')), |
| 82 '/' + target_arch] |
| 83 else: |
| 84 # We don't use VC/vcvarsall.bat for x86 because vcvarsall calls |
| 85 # vcvars32, which it can only find if VS??COMNTOOLS is set, which it |
| 86 # isn't always. |
| 87 if target_arch == 'x86': |
| 88 return [os.path.normpath( |
| 89 os.path.join(self.path, 'Common7/Tools/vsvars32.bat'))] |
| 90 else: |
| 91 assert target_arch == 'x64' |
| 92 arg = 'x86_amd64' |
| 93 if (os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or |
| 94 os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'): |
| 95 # Use the 64-on-64 compiler if we can. |
| 96 arg = 'amd64' |
| 97 return [os.path.normpath( |
| 98 os.path.join(self.path, 'VC/vcvarsall.bat')), arg] |
| 99 |
| 100 |
| 101 def _RegistryQueryBase(sysdir, key, value): |
| 102 """Use reg.exe to read a particular key. |
| 103 |
| 104 While ideally we might use the win32 module, we would like gyp to be |
| 105 python neutral, so for instance cygwin python lacks this module. |
| 106 |
| 107 Arguments: |
| 108 sysdir: The system subdirectory to attempt to launch reg.exe from. |
| 109 key: The registry key to read from. |
| 110 value: The particular value to read. |
| 111 Return: |
| 112 stdout from reg.exe, or None for failure. |
| 113 """ |
| 114 # Skip if not on Windows or Python Win32 setup issue |
| 115 if sys.platform not in ('win32', 'cygwin'): |
| 116 return None |
| 117 # Setup params to pass to and attempt to launch reg.exe |
| 118 cmd = [os.path.join(os.environ.get('WINDIR', ''), sysdir, 'reg.exe'), |
| 119 'query', key] |
| 120 if value: |
| 121 cmd.extend(['/v', value]) |
| 122 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 123 # Obtain the stdout from reg.exe, reading to the end so p.returncode is valid |
| 124 # Note that the error text may be in [1] in some cases |
| 125 text = p.communicate()[0] |
| 126 # Check return code from reg.exe; officially 0==success and 1==error |
| 127 if p.returncode: |
| 128 return None |
| 129 return text |
| 130 |
| 131 |
| 132 def _RegistryQuery(key, value=None): |
| 133 """Use reg.exe to read a particular key through _RegistryQueryBase. |
| 134 |
| 135 First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If |
| 136 that fails, it falls back to System32. Sysnative is available on Vista and |
| 137 up and available on Windows Server 2003 and XP through KB patch 942589. Note |
| 138 that Sysnative will always fail if using 64-bit python due to it being a |
| 139 virtual directory and System32 will work correctly in the first place. |
| 140 |
| 141 KB 942589 - http://support.microsoft.com/kb/942589/en-us. |
| 142 |
| 143 Arguments: |
| 144 key: The registry key. |
| 145 value: The particular registry value to read (optional). |
| 146 Return: |
| 147 stdout from reg.exe, or None for failure. |
| 148 """ |
| 149 text = None |
| 150 try: |
| 151 text = _RegistryQueryBase('Sysnative', key, value) |
| 152 except OSError, e: |
| 153 if e.errno == errno.ENOENT: |
| 154 text = _RegistryQueryBase('System32', key, value) |
| 155 else: |
| 156 raise |
| 157 return text |
| 158 |
| 159 |
| 160 def _RegistryGetValue(key, value): |
| 161 """Use reg.exe to obtain the value of a registry key. |
| 162 |
| 163 Args: |
| 164 key: The registry key. |
| 165 value: The particular registry value to read. |
| 166 Return: |
| 167 contents of the registry key's value, or None on failure. |
| 168 """ |
| 169 text = _RegistryQuery(key, value) |
| 170 if not text: |
| 171 return None |
| 172 # Extract value. |
| 173 match = re.search(r'REG_\w+\s+([^\r]+)\r\n', text) |
| 174 if not match: |
| 175 return None |
| 176 return match.group(1) |
| 177 |
| 178 |
| 179 def _RegistryKeyExists(key): |
| 180 """Use reg.exe to see if a key exists. |
| 181 |
| 182 Args: |
| 183 key: The registry key to check. |
| 184 Return: |
| 185 True if the key exists |
| 186 """ |
| 187 if not _RegistryQuery(key): |
| 188 return False |
| 189 return True |
| 190 |
| 191 |
| 192 def _CreateVersion(name, path, sdk_based=False): |
| 193 """Sets up MSVS project generation. |
| 194 |
| 195 Setup is based off the GYP_MSVS_VERSION environment variable or whatever is |
| 196 autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is |
| 197 passed in that doesn't match a value in versions python will throw a error. |
| 198 """ |
| 199 if path: |
| 200 path = os.path.normpath(path) |
| 201 versions = { |
| 202 '2013': VisualStudioVersion('2013', |
| 203 'Visual Studio 2013', |
| 204 solution_version='13.00', |
| 205 project_version='4.0', |
| 206 flat_sln=False, |
| 207 uses_vcxproj=True, |
| 208 path=path, |
| 209 sdk_based=sdk_based, |
| 210 default_toolset='v110'), |
| 211 '2013e': VisualStudioVersion('2013e', |
| 212 'Visual Studio 2013', |
| 213 solution_version='13.00', |
| 214 project_version='4.0', |
| 215 flat_sln=True, |
| 216 uses_vcxproj=True, |
| 217 path=path, |
| 218 sdk_based=sdk_based, |
| 219 default_toolset='v110'), |
| 220 '2012': VisualStudioVersion('2012', |
| 221 'Visual Studio 2012', |
| 222 solution_version='12.00', |
| 223 project_version='4.0', |
| 224 flat_sln=False, |
| 225 uses_vcxproj=True, |
| 226 path=path, |
| 227 sdk_based=sdk_based, |
| 228 default_toolset='v110'), |
| 229 '2012e': VisualStudioVersion('2012e', |
| 230 'Visual Studio 2012', |
| 231 solution_version='12.00', |
| 232 project_version='4.0', |
| 233 flat_sln=True, |
| 234 uses_vcxproj=True, |
| 235 path=path, |
| 236 sdk_based=sdk_based, |
| 237 default_toolset='v110'), |
| 238 '2010': VisualStudioVersion('2010', |
| 239 'Visual Studio 2010', |
| 240 solution_version='11.00', |
| 241 project_version='4.0', |
| 242 flat_sln=False, |
| 243 uses_vcxproj=True, |
| 244 path=path, |
| 245 sdk_based=sdk_based), |
| 246 '2010e': VisualStudioVersion('2010e', |
| 247 'Visual Studio 2010', |
| 248 solution_version='11.00', |
| 249 project_version='4.0', |
| 250 flat_sln=True, |
| 251 uses_vcxproj=True, |
| 252 path=path, |
| 253 sdk_based=sdk_based), |
| 254 '2008': VisualStudioVersion('2008', |
| 255 'Visual Studio 2008', |
| 256 solution_version='10.00', |
| 257 project_version='9.00', |
| 258 flat_sln=False, |
| 259 uses_vcxproj=False, |
| 260 path=path, |
| 261 sdk_based=sdk_based), |
| 262 '2008e': VisualStudioVersion('2008e', |
| 263 'Visual Studio 2008', |
| 264 solution_version='10.00', |
| 265 project_version='9.00', |
| 266 flat_sln=True, |
| 267 uses_vcxproj=False, |
| 268 path=path, |
| 269 sdk_based=sdk_based), |
| 270 '2005': VisualStudioVersion('2005', |
| 271 'Visual Studio 2005', |
| 272 solution_version='9.00', |
| 273 project_version='8.00', |
| 274 flat_sln=False, |
| 275 uses_vcxproj=False, |
| 276 path=path, |
| 277 sdk_based=sdk_based), |
| 278 '2005e': VisualStudioVersion('2005e', |
| 279 'Visual Studio 2005', |
| 280 solution_version='9.00', |
| 281 project_version='8.00', |
| 282 flat_sln=True, |
| 283 uses_vcxproj=False, |
| 284 path=path, |
| 285 sdk_based=sdk_based), |
| 286 } |
| 287 return versions[str(name)] |
| 288 |
| 289 |
| 290 def _ConvertToCygpath(path): |
| 291 """Convert to cygwin path if we are using cygwin.""" |
| 292 if sys.platform == 'cygwin': |
| 293 p = subprocess.Popen(['cygpath', path], stdout=subprocess.PIPE) |
| 294 path = p.communicate()[0].strip() |
| 295 return path |
| 296 |
| 297 |
| 298 def _DetectVisualStudioVersions(versions_to_check, force_express): |
| 299 """Collect the list of installed visual studio versions. |
| 300 |
| 301 Returns: |
| 302 A list of visual studio versions installed in descending order of |
| 303 usage preference. |
| 304 Base this on the registry and a quick check if devenv.exe exists. |
| 305 Only versions 8-10 are considered. |
| 306 Possibilities are: |
| 307 2005(e) - Visual Studio 2005 (8) |
| 308 2008(e) - Visual Studio 2008 (9) |
| 309 2010(e) - Visual Studio 2010 (10) |
| 310 2012(e) - Visual Studio 2012 (11) |
| 311 2013(e) - Visual Studio 2013 (11) |
| 312 Where (e) is e for express editions of MSVS and blank otherwise. |
| 313 """ |
| 314 version_to_year = { |
| 315 '8.0': '2005', |
| 316 '9.0': '2008', |
| 317 '10.0': '2010', |
| 318 '11.0': '2012', |
| 319 '12.0': '2013', |
| 320 } |
| 321 versions = [] |
| 322 for version in versions_to_check: |
| 323 # Old method of searching for which VS version is installed |
| 324 # We don't use the 2010-encouraged-way because we also want to get the |
| 325 # path to the binaries, which it doesn't offer. |
| 326 keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version, |
| 327 r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version, |
| 328 r'HKLM\Software\Microsoft\VCExpress\%s' % version, |
| 329 r'HKLM\Software\Wow6432Node\Microsoft\VCExpress\%s' % version] |
| 330 for index in range(len(keys)): |
| 331 path = _RegistryGetValue(keys[index], 'InstallDir') |
| 332 if not path: |
| 333 continue |
| 334 path = _ConvertToCygpath(path) |
| 335 # Check for full. |
| 336 full_path = os.path.join(path, 'devenv.exe') |
| 337 express_path = os.path.join(path, 'vcexpress.exe') |
| 338 if not force_express and os.path.exists(full_path): |
| 339 # Add this one. |
| 340 versions.append(_CreateVersion(version_to_year[version], |
| 341 os.path.join(path, '..', '..'))) |
| 342 # Check for express. |
| 343 elif os.path.exists(express_path): |
| 344 # Add this one. |
| 345 versions.append(_CreateVersion(version_to_year[version] + 'e', |
| 346 os.path.join(path, '..', '..'))) |
| 347 |
| 348 # The old method above does not work when only SDK is installed. |
| 349 keys = [r'HKLM\Software\Microsoft\VisualStudio\SxS\VC7', |
| 350 r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7'] |
| 351 for index in range(len(keys)): |
| 352 path = _RegistryGetValue(keys[index], version) |
| 353 if not path: |
| 354 continue |
| 355 path = _ConvertToCygpath(path) |
| 356 versions.append(_CreateVersion(version_to_year[version] + 'e', |
| 357 os.path.join(path, '..'), sdk_based=True)) |
| 358 |
| 359 return versions |
| 360 |
| 361 |
| 362 def SelectVisualStudioVersion(version='auto'): |
| 363 """Select which version of Visual Studio projects to generate. |
| 364 |
| 365 Arguments: |
| 366 version: Hook to allow caller to force a particular version (vs auto). |
| 367 Returns: |
| 368 An object representing a visual studio project format version. |
| 369 """ |
| 370 # In auto mode, check environment variable for override. |
| 371 if version == 'auto': |
| 372 version = os.environ.get('GYP_MSVS_VERSION', 'auto') |
| 373 version_map = { |
| 374 'auto': ('10.0', '9.0', '8.0', '11.0'), |
| 375 '2005': ('8.0',), |
| 376 '2005e': ('8.0',), |
| 377 '2008': ('9.0',), |
| 378 '2008e': ('9.0',), |
| 379 '2010': ('10.0',), |
| 380 '2010e': ('10.0',), |
| 381 '2012': ('11.0',), |
| 382 '2012e': ('11.0',), |
| 383 '2013': ('12.0',), |
| 384 '2013e': ('12.0',), |
| 385 } |
| 386 override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH') |
| 387 if override_path: |
| 388 msvs_version = os.environ.get('GYP_MSVS_VERSION') |
| 389 if not msvs_version or 'e' not in msvs_version: |
| 390 raise ValueError('GYP_MSVS_OVERRIDE_PATH requires GYP_MSVS_VERSION to be ' |
| 391 'set to an "e" version (e.g. 2010e)') |
| 392 return _CreateVersion(msvs_version, override_path, sdk_based=True) |
| 393 version = str(version) |
| 394 versions = _DetectVisualStudioVersions(version_map[version], 'e' in version) |
| 395 if not versions: |
| 396 if version == 'auto': |
| 397 # Default to 2005 if we couldn't find anything |
| 398 return _CreateVersion('2005', None) |
| 399 else: |
| 400 return _CreateVersion(version, None) |
| 401 return versions[0] |
| 402 |
| 403 def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags, open_out): |
| 404 """It's not sufficient to have the absolute path to the compiler, linker, |
| 405 etc. on Windows, as those tools rely on .dlls being in the PATH. We also |
| 406 need to support both x86 and x64 compilers within the same build (to support |
| 407 msvs_target_platform hackery). Different architectures require a different |
| 408 compiler binary, and different supporting environment variables (INCLUDE, |
| 409 LIB, LIBPATH). So, we extract the environment here, wrap all invocations |
| 410 of compiler tools (cl, link, lib, rc, midl, etc.) via win_tool.py which |
| 411 sets up the environment, and then we do not prefix the compiler with |
| 412 an absolute path, instead preferring something like "cl.exe" in the rule |
| 413 which will then run whichever the environment setup has put in the path. |
| 414 When the following procedure to generate environment files does not |
| 415 meet your requirement (e.g. for custom toolchains), you can pass |
| 416 "-G ninja_use_custom_environment_files" to the gyp to suppress file |
| 417 generation and use custom environment files prepared by yourself.""" |
| 418 archs = ('x86', 'x64') |
| 419 if generator_flags.get('ninja_use_custom_environment_files', 0): |
| 420 cl_paths = {} |
| 421 for arch in archs: |
| 422 cl_paths[arch] = 'cl.exe' |
| 423 return cl_paths |
| 424 vs = GetVSVersion(generator_flags) |
| 425 cl_paths = {} |
| 426 for arch in archs: |
| 427 # Extract environment variables for subprocesses. |
| 428 args = vs.SetupScript(arch) |
| 429 args.extend(('&&', 'set')) |
| 430 popen = subprocess.Popen( |
| 431 args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| 432 variables, _ = popen.communicate() |
| 433 env = _ExtractImportantEnvironment(variables) |
| 434 env_block = _FormatAsEnvironmentBlock(env) |
| 435 f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb') |
| 436 f.write(env_block) |
| 437 f.close() |
| 438 |
| 439 # Find cl.exe location for this architecture. |
| 440 args = vs.SetupScript(arch) |
| 441 args.extend(('&&', |
| 442 'for', '%i', 'in', '(cl.exe)', 'do', '@echo', 'LOC:%~$PATH:i')) |
| 443 popen = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE) |
| 444 output, _ = popen.communicate() |
| 445 cl_paths[arch] = _ExtractCLPath(output) |
| 446 return cl_paths |
| 447 |
| 448 def OpenOutput(path, mode='w'): |
| 449 """Open |path| for writing, creating directories if necessary.""" |
| 450 try: |
| 451 os.makedirs(os.path.dirname(path)) |
| 452 except OSError: |
| 453 pass |
| 454 return open(path, mode) |
| 455 |
| 456 vs_version = None |
| 457 def GetVSVersion(generator_flags): |
| 458 global vs_version |
| 459 if not vs_version: |
| 460 vs_version = SelectVisualStudioVersion( |
| 461 generator_flags.get('msvs_version', 'auto')) |
| 462 return vs_version |
| 463 |
| 464 def _ExtractImportantEnvironment(output_of_set): |
| 465 """Extracts environment variables required for the toolchain to run from |
| 466 a textual dump output by the cmd.exe 'set' command.""" |
| 467 envvars_to_save = ( |
| 468 'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. |
| 469 'include', |
| 470 'lib', |
| 471 'libpath', |
| 472 'path', |
| 473 'pathext', |
| 474 'systemroot', |
| 475 'temp', |
| 476 'tmp', |
| 477 ) |
| 478 env = {} |
| 479 for line in output_of_set.splitlines(): |
| 480 for envvar in envvars_to_save: |
| 481 if re.match(envvar + '=', line.lower()): |
| 482 var, setting = line.split('=', 1) |
| 483 if envvar == 'path': |
| 484 # Our own rules (for running gyp-win-tool) and other actions in |
| 485 # Chromium rely on python being in the path. Add the path to this |
| 486 # python here so that if it's not in the path when ninja is run |
| 487 # later, python will still be found. |
| 488 setting = os.path.dirname(sys.executable) + os.pathsep + setting |
| 489 env[var.upper()] = setting |
| 490 break |
| 491 for required in ('SYSTEMROOT', 'TEMP', 'TMP'): |
| 492 if required not in env: |
| 493 raise Exception('Environment variable "%s" ' |
| 494 'required to be set to valid path' % required) |
| 495 return env |
| 496 |
| 497 def _FormatAsEnvironmentBlock(envvar_dict): |
| 498 """Format as an 'environment block' directly suitable for CreateProcess. |
| 499 Briefly this is a list of key=value\0, terminated by an additional \0. See |
| 500 CreateProcess documentation for more details.""" |
| 501 block = '' |
| 502 nul = '\0' |
| 503 for key, value in envvar_dict.iteritems(): |
| 504 block += key + '=' + value + nul |
| 505 block += nul |
| 506 return block |
| 507 |
| 508 |
| 509 def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags): |
| 510 """It's not sufficient to have the absolute path to the compiler, linker, |
| 511 etc. on Windows, as those tools rely on .dlls being in the PATH. We also |
| 512 need to support both x86 and x64 compilers within the same build (to support |
| 513 msvs_target_platform hackery). Different architectures require a different |
| 514 compiler binary, and different supporting environment variables (INCLUDE, |
| 515 LIB, LIBPATH). So, we extract the environment here, wrap all invocations |
| 516 of compiler tools (cl, link, lib, rc, midl, etc.) via win_tool.py which |
| 517 sets up the environment, and then we do not prefix the compiler with |
| 518 an absolute path, instead preferring something like "cl.exe" in the rule |
| 519 which will then run whichever the environment setup has put in the path. |
| 520 When the following procedure to generate environment files does not |
| 521 meet your requirement (e.g. for custom toolchains), you can pass |
| 522 "-G ninja_use_custom_environment_files" to the gyp to suppress file |
| 523 generation and use custom environment files prepared by yourself.""" |
| 524 archs = ('x86', 'x64') |
| 525 if generator_flags.get('ninja_use_custom_environment_files', 0): |
| 526 cl_paths = {} |
| 527 for arch in archs: |
| 528 cl_paths[arch] = 'cl.exe' |
| 529 return cl_paths |
| 530 vs = GetVSVersion(generator_flags) |
| 531 cl_paths = {} |
| 532 for arch in archs: |
| 533 # Extract environment variables for subprocesses. |
| 534 args = vs.SetupScript(arch) |
| 535 args.extend(('&&', 'set')) |
| 536 popen = subprocess.Popen( |
| 537 args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| 538 variables, _ = popen.communicate() |
| 539 env = _ExtractImportantEnvironment(variables) |
| 540 env_block = _FormatAsEnvironmentBlock(env) |
| 541 f = OpenOutput(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb'
) |
| 542 f.write(env_block) |
| 543 f.close() |
| 544 |
| 545 # Find cl.exe location for this architecture. |
| 546 args = vs.SetupScript(arch) |
| 547 args.extend(('&&', |
| 548 'for', '%i', 'in', '(cl.exe)', 'do', '@echo', 'LOC:%~$PATH:i')) |
| 549 popen = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE) |
| 550 output, _ = popen.communicate() |
| 551 cl_paths[arch] = _ExtractCLPath(output) |
| 552 return cl_paths |
| 553 |
| 554 def _ExtractCLPath(output_of_where): |
| 555 """Gets the path to cl.exe based on the output of calling the environment |
| 556 setup batch file, followed by the equivalent of `where`.""" |
| 557 # Take the first line, as that's the first found in the PATH. |
| 558 for line in output_of_where.strip().splitlines(): |
| 559 if line.startswith('LOC:'): |
| 560 return line[len('LOC:'):].strip() |
| 561 |
| 562 #print SelectVisualStudioVersion().DefaultToolset() |
| 563 #GenerateEnvironmentFiles("D:\\src\\src1\\src\\out\\gn\\eraseme", {}) |
| 564 #print '"', GetVSVersion({}).Path(), '"' |
| 565 print '"', GetVSVersion({}).sdk_based, '"' |
| 566 |
| 567 #------------------------------------------------------------------------------- |
| 568 |
| 569 version_info = { |
| 570 '2010': { |
| 571 'includes': [ |
| 572 'VC\\atlmfc\\include', |
| 573 ], |
| 574 }, |
| 575 } |
OLD | NEW |