Skip to content

Commit 5aa0a0e

Browse files
committed
Improve solution by using vswhere.exe (I'm sure this works for MSVC 2022 too)
1 parent 7e7fc63 commit 5aa0a0e

File tree

1 file changed

+58
-14
lines changed

1 file changed

+58
-14
lines changed

build.py

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,18 +115,62 @@ def Exit( self ):
115115
'See the YCM docs for details on how to use a custom Clangd.' )
116116

117117

118-
def FindLatestMSVC():
119-
import winreg
120-
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
121-
msvc = None
122-
for i in [17, 16, 15]:
123-
try:
124-
winreg.OpenKey(handle, rf'SOFTWARE\Microsoft\VisualStudio\{i}.0')
125-
msvc = i
126-
break
127-
except FileNotFoundError:
128-
pass
129-
return msvc
118+
def FindLatestMSVC(quiet):
119+
ACCEPTABLE_VERSIONS = [17, 16, 15]
120+
121+
VSWHERE_EXE = os.path.join(os.environ['ProgramFiles(x86)'],
122+
'Microsoft Visual Studio',
123+
'Installer', 'vswhere.exe')
124+
125+
if os.path.exists(VSWHERE_EXE):
126+
if not quiet:
127+
print("Calling vswhere -latest -installationVersion")
128+
latest_full_v = subprocess.check_output(
129+
[VSWHERE_EXE, '-latest', '-property', 'installationVersion']
130+
).strip().decode()
131+
if '.' in latest_full_v:
132+
try:
133+
latest_v = int(latest_full_v.split('.')[0])
134+
except ValueError:
135+
raise ValueError("{latest_full_v=} is not a version number.")
136+
137+
if not quiet:
138+
print(f'vswhere -latest returned version {latest_full_v=}')
139+
140+
if latest_v not in ACCEPTABLE_VERSIONS:
141+
if latest_v > 17:
142+
if not quiet:
143+
print(f'MSVC Version {latest_full_v=} is newer than expected.')
144+
else:
145+
raise ValueError(
146+
f'vswhere returned {latest_full_v=} which is unexpected.'
147+
'Pass --msvc <version> argument.')
148+
return latest_v
149+
else:
150+
if not quiet:
151+
print(f'vswhere returned nothing usable, {latest_full_v=}')
152+
153+
# Fall back to registry parsing, which works at least until MSVC 2019 (16)
154+
# but is likely failing on MSVC 2022 (17)
155+
if not quiet:
156+
print("vswhere method failed, falling back to searching the registry")
157+
158+
import winreg
159+
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
160+
msvc = None
161+
for i in ACCEPTABLE_VERSIONS:
162+
if not quiet:
163+
print('Trying to find '
164+
rf'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\{i}.0')
165+
try:
166+
winreg.OpenKey(handle, rf'SOFTWARE\Microsoft\VisualStudio\{i}.0')
167+
if not quiet:
168+
print(f"Found MSVC version {i}")
169+
msvc = i
170+
break
171+
except FileNotFoundError:
172+
pass
173+
return msvc
130174

131175

132176
def RemoveDirectory( directory ):
@@ -507,9 +551,9 @@ def ParseArguments():
507551
args.enable_debug = True
508552

509553
if OnWindows() and args.msvc is None:
510-
args.msvc = FindLatestMSVC()
554+
args.msvc = FindLatestMSVC(args.quiet)
511555
if args.msvc is None:
512-
raise FileNotFoundError("Could not find a valid MSVC version")
556+
raise FileNotFoundError("Could not find a valid MSVC version.")
513557

514558
if args.core_tests:
515559
os.environ[ 'YCM_TESTRUN' ] = '1'

0 commit comments

Comments
 (0)