1616import subprocess
1717import sys
1818import tempfile
19+ import json
1920
2021from contextlib import contextmanager
2122
@@ -700,70 +701,62 @@ def FindMSBuildInstallation(msvs_version = 'auto'):
700701
701702
702703def FindVisualStudioInstallation ():
703- """Returns appropriate values for .build_tool and .uses_msbuild fields
704+ """
705+ Returns appropriate values for .build_tool and .uses_msbuild fields
704706 of TestGypBase for Visual Studio.
705707
706708 We use the value specified by GYP_MSVS_VERSION. If not specified, we
707- search %PATH% and %PATHEXT% for a devenv.{exe,bat,...} executable.
708- Failing that, we search for likely deployment paths.
709+ search for likely deployment paths.
709710 """
710711 override_build_tool = os .environ .get ('GYP_BUILD_TOOL' )
711712 if override_build_tool :
712713 return override_build_tool , True , override_build_tool
713714
714- possible_roots = ['%s:\\ Program Files%s' % (chr (drive ), suffix )
715- for drive in range (ord ('C' ), ord ('Z' ) + 1 )
716- for suffix in ['' , ' (x86)' ]]
717- possible_paths = {
718- '2017' : r'Microsoft Visual Studio\2017' ,
719- '2015' : r'Microsoft Visual Studio 14.0\Common7\IDE\devenv.com' ,
720- '2013' : r'Microsoft Visual Studio 12.0\Common7\IDE\devenv.com' ,
721- '2012' : r'Microsoft Visual Studio 11.0\Common7\IDE\devenv.com' ,
722- '2010' : r'Microsoft Visual Studio 10.0\Common7\IDE\devenv.com' ,
723- '2008' : r'Microsoft Visual Studio 9.0\Common7\IDE\devenv.com' ,
724- '2005' : r'Microsoft Visual Studio 8\Common7\IDE\devenv.com' }
725-
726- possible_roots = [ConvertToCygpath (r ) for r in possible_roots ]
727-
728715 msvs_version = 'auto'
729716 for flag in (f for f in sys .argv if f .startswith ('msvs_version=' )):
730717 msvs_version = flag .split ('=' )[- 1 ]
731718 msvs_version = os .environ .get ('GYP_MSVS_VERSION' , msvs_version )
732719
733- if msvs_version in [ '2017' , 'auto' ] :
720+ if msvs_version == 'auto' or msvs_version >= '2017' :
734721 msbuild_exes = []
735722 try :
736- path = possible_paths ['2017' ]
737- for r in possible_roots :
738- build_tool = os .path .join (r , path )
739- if os .path .exists (build_tool ):
740- break ;
741- else :
742- build_tool = None
743- if not build_tool :
744- args1 = ['reg' , 'query' ,
745- 'HKLM\Software\Microsoft\VisualStudio\SxS\VS7' ,
746- '/v' , '15.0' , '/reg:32' ]
747- build_tool = subprocess .check_output (args1 ).decode (
748- 'utf-8' , 'ignore' ).strip ().split (b'\r \n ' ).pop ().split (b' ' ).pop ()
749- build_tool = build_tool .decode ('utf-8' )
750- if build_tool :
723+ args1 = [
724+ r'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' ,
725+ '-latest' , '-products' , '*' , '-prerelease' , '-format' , 'json' ,
726+ '-requires' , 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' ,
727+ ]
728+ vswhere_json = subprocess .check_output (args1 )
729+ top_vs_info = json .loads (vswhere_json )[0 ]
730+ if top_vs_info :
731+ inst_path = top_vs_info ['installationPath' ]
751732 args2 = ['cmd.exe' , '/d' , '/c' ,
752- 'cd' , '/d' , build_tool ,
753- '&' , 'dir' , '/b' , '/s' , 'msbuild.exe' ]
733+ 'cd' , '/d' , inst_path ,
734+ '&' , 'dir' , '/b' , '/s' , 'msbuild.exe' ]
754735 msbuild_exes = subprocess .check_output (args2 ).strip ().split (b'\r \n ' )
755736 msbuild_exes = [m .decode ('utf-8' ) for m in msbuild_exes ]
756737 if len (msbuild_exes ):
757- msbuild_Path = os .path .join (build_tool , msbuild_exes [0 ])
758- if os .path .exists (msbuild_Path ):
759- os .environ ['GYP_MSVS_VERSION' ] = '2017'
760- os .environ ['GYP_BUILD_TOOL' ] = msbuild_Path
761- return msbuild_Path , True , msbuild_Path
762- except Exception as e :
738+ msbuild_path = msbuild_exes [0 ]
739+ os .environ ['GYP_MSVS_VERSION' ] = top_vs_info ['catalog' ]['productLineVersion' ]
740+ os .environ ['GYP_BUILD_TOOL' ] = msbuild_path
741+ return msbuild_path , True , msbuild_path
742+ except :
763743 pass
764744
745+ possible_roots = ['%s:\\ Program Files%s' % (chr (drive ), suffix )
746+ for drive in range (ord ('C' ), ord ('Z' ) + 1 )
747+ for suffix in ['' , ' (x86)' ]]
748+ possible_paths = {
749+ '2015' : r'Microsoft Visual Studio 14.0\Common7\IDE\devenv.com' ,
750+ '2013' : r'Microsoft Visual Studio 12.0\Common7\IDE\devenv.com' ,
751+ '2012' : r'Microsoft Visual Studio 11.0\Common7\IDE\devenv.com' ,
752+ '2010' : r'Microsoft Visual Studio 10.0\Common7\IDE\devenv.com' ,
753+ '2008' : r'Microsoft Visual Studio 9.0\Common7\IDE\devenv.com' ,
754+ '2005' : r'Microsoft Visual Studio 8\Common7\IDE\devenv.com' }
755+
756+ possible_roots = [ConvertToCygpath (r ) for r in possible_roots ]
757+
758+ # Check that the path to the specified GYP_MSVS_VERSION exists.
765759 if msvs_version in possible_paths :
766- # Check that the path to the specified GYP_MSVS_VERSION exists.
767760 path = possible_paths [msvs_version ]
768761 for r in possible_roots :
769762 build_tool = os .path .join (r , path )
@@ -774,19 +767,10 @@ def FindVisualStudioInstallation():
774767 else :
775768 print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" '
776769 'but corresponding "%s" was not found.' % (msvs_version , path ))
777- # Neither GYP_MSVS_VERSION nor the path help us out. Iterate through
778- # the choices looking for a match.
779- for version in sorted (possible_paths , reverse = True ):
780- path = possible_paths [version ]
781- for r in possible_roots :
782- build_tool = os .path .join (r , path )
783- if os .path .exists (build_tool ):
784- uses_msbuild = msvs_version >= '2010'
785- msbuild_path = FindMSBuildInstallation (msvs_version )
786- return build_tool , uses_msbuild , msbuild_path
787- print ('Error: could not find devenv' )
770+ print ('Error: could not find MSVS version %s' % msvs_version )
788771 sys .exit (1 )
789772
773+
790774class TestGypOnMSToolchain (TestGypBase ):
791775 """
792776 Common subclass for testing generators that target the Microsoft Visual
@@ -914,7 +898,7 @@ def build(self, gyp_file, target=None, rebuild=False, clean=False, **kw):
914898 Runs a Visual Studio build using the configuration generated
915899 from the specified gyp_file.
916900 """
917- if '15.0' in self .build_tool :
901+ if '15.0' in self .build_tool or 'Current' in self . build_tool :
918902 configuration = '/p:Configuration=' + (
919903 self .configuration or self .configuration_buildname ())
920904 build = '/t'
0 commit comments