"Fossies" - the Fresh Open Source Software Archive

Member "node-v12.18.4-win-x86/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py" (18 Feb 2020, 17888 Bytes) of package /windows/www/node-v12.18.4-win-x86.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 # Copyright (c) 2013 Google Inc. 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 """Handle version information related to Visual Stuio."""
    6 
    7 import errno
    8 import os
    9 import re
   10 import subprocess
   11 import sys
   12 import gyp
   13 import glob
   14 
   15 PY3 = bytes != str
   16 
   17 
   18 class VisualStudioVersion(object):
   19   """Information regarding a version of Visual Studio."""
   20 
   21   def __init__(self, short_name, description,
   22                solution_version, project_version, flat_sln, uses_vcxproj,
   23                path, sdk_based, default_toolset=None):
   24     self.short_name = short_name
   25     self.description = description
   26     self.solution_version = solution_version
   27     self.project_version = project_version
   28     self.flat_sln = flat_sln
   29     self.uses_vcxproj = uses_vcxproj
   30     self.path = path
   31     self.sdk_based = sdk_based
   32     self.default_toolset = default_toolset
   33 
   34   def ShortName(self):
   35     return self.short_name
   36 
   37   def Description(self):
   38     """Get the full description of the version."""
   39     return self.description
   40 
   41   def SolutionVersion(self):
   42     """Get the version number of the sln files."""
   43     return self.solution_version
   44 
   45   def ProjectVersion(self):
   46     """Get the version number of the vcproj or vcxproj files."""
   47     return self.project_version
   48 
   49   def FlatSolution(self):
   50     return self.flat_sln
   51 
   52   def UsesVcxproj(self):
   53     """Returns true if this version uses a vcxproj file."""
   54     return self.uses_vcxproj
   55 
   56   def ProjectExtension(self):
   57     """Returns the file extension for the project."""
   58     return self.uses_vcxproj and '.vcxproj' or '.vcproj'
   59 
   60   def Path(self):
   61     """Returns the path to Visual Studio installation."""
   62     return self.path
   63 
   64   def ToolPath(self, tool):
   65     """Returns the path to a given compiler tool. """
   66     return os.path.normpath(os.path.join(self.path, "VC/bin", tool))
   67 
   68   def DefaultToolset(self):
   69     """Returns the msbuild toolset version that will be used in the absence
   70     of a user override."""
   71     return self.default_toolset
   72 
   73   def SetupScript(self, target_arch):
   74     """Returns a command (with arguments) to be used to set up the
   75     environment."""
   76     # Check if we are running in the SDK command line environment and use
   77     # the setup script from the SDK if so. |target_arch| should be either
   78     # 'x86' or 'x64'.
   79     assert target_arch in ('x86', 'x64')
   80     sdk_dir = os.environ.get('WindowsSDKDir')
   81     if self.sdk_based and sdk_dir:
   82       return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')),
   83               '/' + target_arch]
   84     else:
   85       # We don't use VC/vcvarsall.bat for x86 because vcvarsall calls
   86       # vcvars32, which it can only find if VS??COMNTOOLS is set, which it
   87       # isn't always.
   88       if target_arch == 'x86':
   89         if self.short_name >= '2013' and self.short_name[-1] != 'e' and (
   90             os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or
   91             os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'):
   92           # VS2013 and later, non-Express have a x64-x86 cross that we want
   93           # to prefer.
   94           return [os.path.normpath(
   95              os.path.join(self.path, 'VC/vcvarsall.bat')), 'amd64_x86']
   96         # Otherwise, the standard x86 compiler.
   97         return [os.path.normpath(
   98           os.path.join(self.path, 'Common7/Tools/vsvars32.bat'))]
   99       else:
  100         assert target_arch == 'x64'
  101         arg = 'x86_amd64'
  102         # Use the 64-on-64 compiler if we're not using an express
  103         # edition and we're running on a 64bit OS.
  104         if self.short_name[-1] != 'e' and (
  105             os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or
  106             os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'):
  107           arg = 'amd64'
  108         return [os.path.normpath(
  109             os.path.join(self.path, 'VC/vcvarsall.bat')), arg]
  110 
  111 
  112 def _RegistryQueryBase(sysdir, key, value):
  113   """Use reg.exe to read a particular key.
  114 
  115   While ideally we might use the win32 module, we would like gyp to be
  116   python neutral, so for instance cygwin python lacks this module.
  117 
  118   Arguments:
  119     sysdir: The system subdirectory to attempt to launch reg.exe from.
  120     key: The registry key to read from.
  121     value: The particular value to read.
  122   Return:
  123     stdout from reg.exe, or None for failure.
  124   """
  125   # Skip if not on Windows or Python Win32 setup issue
  126   if sys.platform not in ('win32', 'cygwin'):
  127     return None
  128   # Setup params to pass to and attempt to launch reg.exe
  129   cmd = [os.path.join(os.environ.get('WINDIR', ''), sysdir, 'reg.exe'),
  130          'query', key]
  131   if value:
  132     cmd.extend(['/v', value])
  133   p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  134   # Obtain the stdout from reg.exe, reading to the end so p.returncode is valid
  135   # Note that the error text may be in [1] in some cases
  136   text = p.communicate()[0]
  137   if PY3:
  138     text = text.decode('utf-8')
  139   # Check return code from reg.exe; officially 0==success and 1==error
  140   if p.returncode:
  141     return None
  142   return text
  143 
  144 
  145 def _RegistryQuery(key, value=None):
  146   r"""Use reg.exe to read a particular key through _RegistryQueryBase.
  147 
  148   First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If
  149   that fails, it falls back to System32.  Sysnative is available on Vista and
  150   up and available on Windows Server 2003 and XP through KB patch 942589. Note
  151   that Sysnative will always fail if using 64-bit python due to it being a
  152   virtual directory and System32 will work correctly in the first place.
  153 
  154   KB 942589 - http://support.microsoft.com/kb/942589/en-us.
  155 
  156   Arguments:
  157     key: The registry key.
  158     value: The particular registry value to read (optional).
  159   Return:
  160     stdout from reg.exe, or None for failure.
  161   """
  162   text = None
  163   try:
  164     text = _RegistryQueryBase('Sysnative', key, value)
  165   except OSError as e:
  166     if e.errno == errno.ENOENT:
  167       text = _RegistryQueryBase('System32', key, value)
  168     else:
  169       raise
  170   return text
  171 
  172 
  173 def _RegistryGetValueUsingWinReg(key, value):
  174   """Use the _winreg module to obtain the value of a registry key.
  175 
  176   Args:
  177     key: The registry key.
  178     value: The particular registry value to read.
  179   Return:
  180     contents of the registry key's value, or None on failure.  Throws
  181     ImportError if _winreg is unavailable.
  182   """
  183   try:
  184       # Python 2
  185       from _winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx
  186   except ImportError:
  187       # Python 3
  188       from winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx
  189 
  190   try:
  191     root, subkey = key.split('\\', 1)
  192     assert root == 'HKLM'  # Only need HKLM for now.
  193     with OpenKey(HKEY_LOCAL_MACHINE, subkey) as hkey:
  194       return QueryValueEx(hkey, value)[0]
  195   except WindowsError:
  196     return None
  197 
  198 
  199 def _RegistryGetValue(key, value):
  200   """Use _winreg or reg.exe to obtain the value of a registry key.
  201 
  202   Using _winreg is preferable because it solves an issue on some corporate
  203   environments where access to reg.exe is locked down. However, we still need
  204   to fallback to reg.exe for the case where the _winreg module is not available
  205   (for example in cygwin python).
  206 
  207   Args:
  208     key: The registry key.
  209     value: The particular registry value to read.
  210   Return:
  211     contents of the registry key's value, or None on failure.
  212   """
  213   try:
  214     return _RegistryGetValueUsingWinReg(key, value)
  215   except ImportError:
  216     pass
  217 
  218   # Fallback to reg.exe if we fail to import _winreg.
  219   text = _RegistryQuery(key, value)
  220   if not text:
  221     return None
  222   # Extract value.
  223   match = re.search(r'REG_\w+\s+([^\r]+)\r\n', text)
  224   if not match:
  225     return None
  226   return match.group(1)
  227 
  228 
  229 def _CreateVersion(name, path, sdk_based=False):
  230   """Sets up MSVS project generation.
  231 
  232   Setup is based off the GYP_MSVS_VERSION environment variable or whatever is
  233   autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is
  234   passed in that doesn't match a value in versions python will throw a error.
  235   """
  236   if path:
  237     path = os.path.normpath(path)
  238   versions = {
  239       '2015': VisualStudioVersion('2015',
  240                                   'Visual Studio 2015',
  241                                   solution_version='12.00',
  242                                   project_version='14.0',
  243                                   flat_sln=False,
  244                                   uses_vcxproj=True,
  245                                   path=path,
  246                                   sdk_based=sdk_based,
  247                                   default_toolset='v140'),
  248       '2013': VisualStudioVersion('2013',
  249                                   'Visual Studio 2013',
  250                                   solution_version='13.00',
  251                                   project_version='12.0',
  252                                   flat_sln=False,
  253                                   uses_vcxproj=True,
  254                                   path=path,
  255                                   sdk_based=sdk_based,
  256                                   default_toolset='v120'),
  257       '2013e': VisualStudioVersion('2013e',
  258                                    'Visual Studio 2013',
  259                                    solution_version='13.00',
  260                                    project_version='12.0',
  261                                    flat_sln=True,
  262                                    uses_vcxproj=True,
  263                                    path=path,
  264                                    sdk_based=sdk_based,
  265                                    default_toolset='v120'),
  266       '2012': VisualStudioVersion('2012',
  267                                   'Visual Studio 2012',
  268                                   solution_version='12.00',
  269                                   project_version='4.0',
  270                                   flat_sln=False,
  271                                   uses_vcxproj=True,
  272                                   path=path,
  273                                   sdk_based=sdk_based,
  274                                   default_toolset='v110'),
  275       '2012e': VisualStudioVersion('2012e',
  276                                    'Visual Studio 2012',
  277                                    solution_version='12.00',
  278                                    project_version='4.0',
  279                                    flat_sln=True,
  280                                    uses_vcxproj=True,
  281                                    path=path,
  282                                    sdk_based=sdk_based,
  283                                    default_toolset='v110'),
  284       '2010': VisualStudioVersion('2010',
  285                                   'Visual Studio 2010',
  286                                   solution_version='11.00',
  287                                   project_version='4.0',
  288                                   flat_sln=False,
  289                                   uses_vcxproj=True,
  290                                   path=path,
  291                                   sdk_based=sdk_based),
  292       '2010e': VisualStudioVersion('2010e',
  293                                    'Visual C++ Express 2010',
  294                                    solution_version='11.00',
  295                                    project_version='4.0',
  296                                    flat_sln=True,
  297                                    uses_vcxproj=True,
  298                                    path=path,
  299                                    sdk_based=sdk_based),
  300       '2008': VisualStudioVersion('2008',
  301                                   'Visual Studio 2008',
  302                                   solution_version='10.00',
  303                                   project_version='9.00',
  304                                   flat_sln=False,
  305                                   uses_vcxproj=False,
  306                                   path=path,
  307                                   sdk_based=sdk_based),
  308       '2008e': VisualStudioVersion('2008e',
  309                                    'Visual Studio 2008',
  310                                    solution_version='10.00',
  311                                    project_version='9.00',
  312                                    flat_sln=True,
  313                                    uses_vcxproj=False,
  314                                    path=path,
  315                                    sdk_based=sdk_based),
  316       '2005': VisualStudioVersion('2005',
  317                                   'Visual Studio 2005',
  318                                   solution_version='9.00',
  319                                   project_version='8.00',
  320                                   flat_sln=False,
  321                                   uses_vcxproj=False,
  322                                   path=path,
  323                                   sdk_based=sdk_based),
  324       '2005e': VisualStudioVersion('2005e',
  325                                    'Visual Studio 2005',
  326                                    solution_version='9.00',
  327                                    project_version='8.00',
  328                                    flat_sln=True,
  329                                    uses_vcxproj=False,
  330                                    path=path,
  331                                    sdk_based=sdk_based),
  332   }
  333   return versions[str(name)]
  334 
  335 
  336 def _ConvertToCygpath(path):
  337   """Convert to cygwin path if we are using cygwin."""
  338   if sys.platform == 'cygwin':
  339     p = subprocess.Popen(['cygpath', path], stdout=subprocess.PIPE)
  340     path = p.communicate()[0].strip()
  341     if PY3:
  342       path = path.decode('utf-8')
  343   return path
  344 
  345 
  346 def _DetectVisualStudioVersions(versions_to_check, force_express):
  347   """Collect the list of installed visual studio versions.
  348 
  349   Returns:
  350     A list of visual studio versions installed in descending order of
  351     usage preference.
  352     Base this on the registry and a quick check if devenv.exe exists.
  353     Only versions 8-10 are considered.
  354     Possibilities are:
  355       2005(e) - Visual Studio 2005 (8)
  356       2008(e) - Visual Studio 2008 (9)
  357       2010(e) - Visual Studio 2010 (10)
  358       2012(e) - Visual Studio 2012 (11)
  359       2013(e) - Visual Studio 2013 (12)
  360       2015    - Visual Studio 2015 (14)
  361     Where (e) is e for express editions of MSVS and blank otherwise.
  362   """
  363   version_to_year = {
  364       '8.0': '2005',
  365       '9.0': '2008',
  366       '10.0': '2010',
  367       '11.0': '2012',
  368       '12.0': '2013',
  369       '14.0': '2015',
  370   }
  371   versions = []
  372   for version in versions_to_check:
  373     # Old method of searching for which VS version is installed
  374     # We don't use the 2010-encouraged-way because we also want to get the
  375     # path to the binaries, which it doesn't offer.
  376     keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version,
  377             r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version,
  378             r'HKLM\Software\Microsoft\VCExpress\%s' % version,
  379             r'HKLM\Software\Wow6432Node\Microsoft\VCExpress\%s' % version]
  380     for index in range(len(keys)):
  381       path = _RegistryGetValue(keys[index], 'InstallDir')
  382       if not path:
  383         continue
  384       path = _ConvertToCygpath(path)
  385       # Check for full.
  386       full_path = os.path.join(path, 'devenv.exe')
  387       express_path = os.path.join(path, '*express.exe')
  388       if not force_express and os.path.exists(full_path):
  389         # Add this one.
  390         versions.append(_CreateVersion(version_to_year[version],
  391             os.path.join(path, '..', '..')))
  392       # Check for express.
  393       elif glob.glob(express_path):
  394         # Add this one.
  395         versions.append(_CreateVersion(version_to_year[version] + 'e',
  396             os.path.join(path, '..', '..')))
  397 
  398     # The old method above does not work when only SDK is installed.
  399     keys = [r'HKLM\Software\Microsoft\VisualStudio\SxS\VC7',
  400             r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7']
  401     for index in range(len(keys)):
  402       path = _RegistryGetValue(keys[index], version)
  403       if not path:
  404         continue
  405       path = _ConvertToCygpath(path)
  406       if version != '14.0':  # There is no Express edition for 2015.
  407         versions.append(_CreateVersion(version_to_year[version] + 'e',
  408             os.path.join(path, '..'), sdk_based=True))
  409 
  410   return versions
  411 
  412 
  413 def SelectVisualStudioVersion(version='auto', allow_fallback=True):
  414   """Select which version of Visual Studio projects to generate.
  415 
  416   Arguments:
  417     version: Hook to allow caller to force a particular version (vs auto).
  418   Returns:
  419     An object representing a visual studio project format version.
  420   """
  421   # In auto mode, check environment variable for override.
  422   if version == 'auto':
  423     version = os.environ.get('GYP_MSVS_VERSION', 'auto')
  424   version_map = {
  425     'auto': ('14.0', '12.0', '10.0', '9.0', '8.0', '11.0'),
  426     '2005': ('8.0',),
  427     '2005e': ('8.0',),
  428     '2008': ('9.0',),
  429     '2008e': ('9.0',),
  430     '2010': ('10.0',),
  431     '2010e': ('10.0',),
  432     '2012': ('11.0',),
  433     '2012e': ('11.0',),
  434     '2013': ('12.0',),
  435     '2013e': ('12.0',),
  436     '2015': ('14.0',),
  437   }
  438   override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH')
  439   if override_path:
  440     msvs_version = os.environ.get('GYP_MSVS_VERSION')
  441     if not msvs_version:
  442       raise ValueError('GYP_MSVS_OVERRIDE_PATH requires GYP_MSVS_VERSION to be '
  443                        'set to a particular version (e.g. 2010e).')
  444     return _CreateVersion(msvs_version, override_path, sdk_based=True)
  445   version = str(version)
  446   versions = _DetectVisualStudioVersions(version_map[version], 'e' in version)
  447   if not versions:
  448     if not allow_fallback:
  449       raise ValueError('Could not locate Visual Studio installation.')
  450     if version == 'auto':
  451       # Default to 2005 if we couldn't find anything
  452       return _CreateVersion('2005', None)
  453     else:
  454       return _CreateVersion(version, None)
  455   return versions[0]