Skip to content

Commit c31149f

Browse files
committed
bpo-30389 Adds detection of VS 2017
1 parent ad0ffa0 commit c31149f

10 files changed

Lines changed: 1190 additions & 28 deletions

Lib/distutils/_msvccompiler.py

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717
import shutil
1818
import stat
1919
import subprocess
20+
import winreg
2021

2122
from distutils.errors import DistutilsExecError, DistutilsPlatformError, \
2223
CompileError, LibError, LinkError
2324
from distutils.ccompiler import CCompiler, gen_lib_options
2425
from distutils import log
2526
from distutils.util import get_platform
2627

27-
import winreg
2828
from itertools import count
2929

30-
def _find_vcvarsall(plat_spec):
30+
def _find_vc2015():
3131
try:
3232
key = winreg.OpenKeyEx(
3333
winreg.HKEY_LOCAL_MACHINE,
@@ -38,9 +38,9 @@ def _find_vcvarsall(plat_spec):
3838
log.debug("Visual C++ is not registered")
3939
return None, None
4040

41+
best_version = 0
42+
best_dir = None
4143
with key:
42-
best_version = 0
43-
best_dir = None
4444
for i in count():
4545
try:
4646
v, vc_dir, vt = winreg.EnumValue(key, i)
@@ -53,25 +53,52 @@ def _find_vcvarsall(plat_spec):
5353
continue
5454
if version >= 14 and version > best_version:
5555
best_version, best_dir = version, vc_dir
56-
if not best_version:
57-
log.debug("No suitable Visual C++ version found")
58-
return None, None
59-
60-
vcvarsall = os.path.join(best_dir, "vcvarsall.bat")
61-
if not os.path.isfile(vcvarsall):
62-
log.debug("%s cannot be found", vcvarsall)
63-
return None, None
64-
65-
vcruntime = None
66-
vcruntime_spec = _VCVARS_PLAT_TO_VCRUNTIME_REDIST.get(plat_spec)
67-
if vcruntime_spec:
68-
vcruntime = os.path.join(best_dir,
69-
vcruntime_spec.format(best_version))
70-
if not os.path.isfile(vcruntime):
71-
log.debug("%s cannot be found", vcruntime)
72-
vcruntime = None
73-
74-
return vcvarsall, vcruntime
56+
return best_version, best_dir
57+
58+
def _find_vc2017():
59+
import _findvs
60+
best_version = 0, # tuple for full version comparisons
61+
best_dir = None
62+
for name, version_str, path, packages in _findvs.findall():
63+
if 'Microsoft.VisualCpp.Tools.Core' in packages:
64+
vc_dir = os.path.join(path, 'VC', 'Auxiliary', 'Build')
65+
if not os.path.isdir(vc_dir):
66+
continue
67+
try:
68+
version = tuple(int(i) for i in version_str.partition('.'))
69+
except (ValueError, TypeError):
70+
continue
71+
if version > best_version:
72+
best_version, best_dir = version, vc_dir
73+
try:
74+
best_version = best_version[0]
75+
except IndexError:
76+
best_version = None
77+
return best_version, best_dir
78+
79+
def _find_vcvarsall(plat_spec):
80+
best_version, best_dir = _find_vc2017()
81+
if not best_version:
82+
best_version, best_dir = _find_vc2015()
83+
if not best_version:
84+
log.debug("No suitable Visual C++ version found")
85+
return None, None
86+
87+
vcvarsall = os.path.join(best_dir, "vcvarsall.bat")
88+
if not os.path.isfile(vcvarsall):
89+
log.debug("%s cannot be found", vcvarsall)
90+
return None, None
91+
92+
vcruntime = None
93+
vcruntime_spec = _VCVARS_PLAT_TO_VCRUNTIME_REDIST.get(plat_spec)
94+
if vcruntime_spec:
95+
vcruntime = os.path.join(best_dir,
96+
vcruntime_spec.format(best_version))
97+
if not os.path.isfile(vcruntime):
98+
log.debug("%s cannot be found", vcruntime)
99+
vcruntime = None
100+
101+
return vcvarsall, vcruntime
75102

76103
def _get_vc_env(plat_spec):
77104
if os.getenv("DISTUTILS_USE_SDK"):

0 commit comments

Comments
 (0)