diff options
Diffstat (limited to 'Lib/distutils')
-rw-r--r-- | Lib/distutils/_msvccompiler.py | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py index 30b3b47..84b4ef5 100644 --- a/Lib/distutils/_msvccompiler.py +++ b/Lib/distutils/_msvccompiler.py @@ -56,43 +56,43 @@ def _find_vc2015(): return best_version, best_dir def _find_vc2017(): - import _distutils_findvs - import threading + """Returns "15, path" based on the result of invoking vswhere.exe + If no install is found, returns "None, None" - best_version = 0, # tuple for full version comparisons - best_dir = None + The version is returned to avoid unnecessarily changing the function + result. It may be ignored when the path is not None. + + If vswhere.exe is not available, by definition, VS 2017 is not + installed. + """ + import json + + root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles") + if not root: + return None, None - # We need to call findall() on its own thread because it will - # initialize COM. - all_packages = [] - def _getall(): - all_packages.extend(_distutils_findvs.findall()) - t = threading.Thread(target=_getall) - t.start() - t.join() - - for name, version_str, path, packages in all_packages: - if 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' in packages: - vc_dir = os.path.join(path, 'VC', 'Auxiliary', 'Build') - if not os.path.isdir(vc_dir): - continue - try: - version = tuple(int(i) for i in version_str.split('.')) - except (ValueError, TypeError): - continue - if version > best_version: - best_version, best_dir = version, vc_dir try: - best_version = best_version[0] - except IndexError: - best_version = None - return best_version, best_dir + path = subprocess.check_output([ + os.path.join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), + "-latest", + "-prerelease", + "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", + "-property", "installationPath", + ], encoding="mbcs", errors="strict").strip() + except (subprocess.CalledProcessError, OSError, UnicodeDecodeError): + return None, None + + path = os.path.join(path, "VC", "Auxiliary", "Build") + if os.path.isdir(path): + return 15, path + + return None, None def _find_vcvarsall(plat_spec): - best_version, best_dir = _find_vc2017() + _, best_dir = _find_vc2017() vcruntime = None vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86' - if best_version: + if best_dir: vcredist = os.path.join(best_dir, "..", "..", "redist", "MSVC", "**", "Microsoft.VC141.CRT", "vcruntime140.dll") try: @@ -101,13 +101,13 @@ def _find_vcvarsall(plat_spec): except (ImportError, OSError, LookupError): vcruntime = None - if not best_version: + if not best_dir: best_version, best_dir = _find_vc2015() if best_version: vcruntime = os.path.join(best_dir, 'redist', vcruntime_plat, "Microsoft.VC140.CRT", "vcruntime140.dll") - if not best_version: + if not best_dir: log.debug("No suitable Visual C++ version found") return None, None |