Skip to content

Commit 26aa674

Browse files
committed
fix: detect preview versions of msvs
fixes #268 - add the '-prerelease' flag to the vswhere subcommand, - give 'no vs found' error if the command returns empty string, - catch vswhere returning multiple installations, - in-case of failure, report vswhere command line, placing any arguments that contain spaces in quotes
1 parent 4c280e2 commit 26aa674

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

cpython-windows/build.py

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -224,35 +224,63 @@ def find_vswhere():
224224

225225

226226
def find_vs_path(path, msvc_version):
227+
"""
228+
Attempts to find 'path' by invoking vswhere to identify where the
229+
given msvc_version is installed.
230+
231+
vswhere is akin to things like 'pkg-config', it's an executable
232+
that can be invoked to retrieve parameters of visual studio code
233+
installations on the host machine.
234+
"""
227235
vswhere = find_vswhere()
228236

237+
# vswhere uses a math-like range expression for specifying the
238+
# major release numbers.
239+
# 16 = Visual Studio 2019,
240+
# 17 = Visual Studio 2022,
229241
if msvc_version == "2019":
230242
version = "[16,17)"
231243
elif msvc_version == "2022":
232244
version = "[17,18)"
233245
else:
234246
raise ValueError(f"unsupported Visual Studio version: {msvc_version}")
235247

236-
p = subprocess.check_output(
237-
[
238-
str(vswhere),
239-
# Visual Studio 2019.
240-
"-version",
241-
version,
242-
"-property",
243-
"installationPath",
244-
"-products",
245-
"*",
246-
]
247-
)
248+
# Assemble the command line into an argv list for a subprocess
249+
# call, so if the command fails we can tell the user what command
250+
# we tried and enable them to potentially investigate further.
251+
cmdline = [
252+
str(vswhere),
253+
"-version",
254+
version,
255+
"-property",
256+
"installationPath",
257+
"-prerelease",
258+
"-products",
259+
"*",
260+
]
261+
p = subprocess.check_output(cmdline)
262+
if not p:
263+
# add quotes around any of the terms with spaces in them, so that
264+
# the user can copy-and-paste the command.
265+
cmdline = ['"%s"' % term if " " in term else term for term in cmdline]
266+
print("could not find visual studio (using '%s')" % cmdline)
267+
sys.exit(1)
248268

249269
# Strictly speaking the output may not be UTF-8.
250-
p = pathlib.Path(p.strip().decode("utf-8"))
251-
252-
p = p / path
270+
p = p.strip().decode("utf-8")
271+
272+
# vswhere can potentially report multiple installed versions,
273+
# one per line. The above 'strip' will have removed any
274+
# trailing newlines, so if there is still a newline, there
275+
# is more than one option.
276+
if "\n" in p: # more than one line
277+
print("found multiple matching instances of visual studio %s:" % msvc_version)
278+
print(p)
279+
sys.exit(1)
253280

281+
p = pathlib.Path(p, path)
254282
if not p.exists():
255-
print("%s does not exist" % p)
283+
print("%s does not exist for vs%s" % (p, msvc_version))
256284
sys.exit(1)
257285

258286
return p

0 commit comments

Comments
 (0)