Update the visual studio version checking logic
This PR updates the `_is_vs_2017_or_2019` function to specify the visual studio version based on the contents of the VC folder instead of depending on the parent directories of VC.
This is helpful in cases where `BAZEL_VC` points to a custom location of VC.
Fixes: #11259
Closes #12586.
PiperOrigin-RevId: 344817390
diff --git a/tools/cpp/windows_cc_configure.bzl b/tools/cpp/windows_cc_configure.bzl
index fa7b339..d0c16c4 100644
--- a/tools/cpp/windows_cc_configure.bzl
+++ b/tools/cpp/windows_cc_configure.bzl
@@ -254,14 +254,17 @@
auto_configure_warning_maybe(repository_ctx, "Visual C++ build tools found at %s" % vc_dir)
return vc_dir
-def _is_vs_2017_or_2019(vc_path):
- """Check if the installed VS version is Visual Studio 2017."""
+def _is_vs_2017_or_2019(repository_ctx, vc_path):
+ """Check if the installed VS version is Visual Studio 2017 or 2019."""
- # In VS 2017 and 2019, the location of VC is like:
- # C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\
- # In VS 2015 or older version, it is like:
- # C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\
- return vc_path.find("2017") != -1 or vc_path.find("2019") != -1
+ # The layout of VC folder in VS 2017 and 2019 is different from that in VS 2015 and older versions.
+ # In VS 2017 and 2019, it contains only three directories:
+ # "Auxiliary", "Redist", "Tools"
+
+ vc_2017_or_2019_contents = ["auxiliary", "redist", "tools"]
+ vc_path_contents = [d.basename.lower() for d in repository_ctx.path(vc_path).readdir()]
+ vc_path_contents = sorted(vc_path_contents)
+ return vc_path_contents == vc_2017_or_2019_contents
def _is_msbuildtools(vc_path):
"""Check if the installed VC version is from MSBuildTools."""
@@ -272,7 +275,7 @@
def _find_vcvars_bat_script(repository_ctx, vc_path):
"""Find batch script to set up environment variables for VC. Doesn't %-escape the result."""
- if _is_vs_2017_or_2019(vc_path):
+ if _is_vs_2017_or_2019(repository_ctx, vc_path):
vcvars_script = vc_path + "\\Auxiliary\\Build\\VCVARSALL.BAT"
else:
vcvars_script = vc_path + "\\VCVARSALL.BAT"
@@ -290,7 +293,7 @@
def _is_support_winsdk_selection(repository_ctx, vc_path):
"""Windows SDK selection is supported with VC 2017 / 2019 or with full VS 2015 installation."""
- if _is_vs_2017_or_2019(vc_path):
+ if _is_vs_2017_or_2019(repository_ctx, vc_path):
return True
# By checking the source code of VCVARSALL.BAT in VC 2015, we know that
@@ -316,7 +319,7 @@
dictionary of envvars
"""
env = {}
- if _is_vs_2017_or_2019(vc_path):
+ if _is_vs_2017_or_2019(repository_ctx, vc_path):
lib = msvc_vars_x64["%{msvc_env_lib_x64}"]
full_version = _get_vc_full_version(repository_ctx, vc_path)
tools_path = "%s\\Tools\\MSVC\\%s\\bin\\HostX64\\%s" % (vc_path, full_version, target_arch)
@@ -360,7 +363,7 @@
# Get VC version set by user. Only supports VC 2017 & 2019.
vcvars_ver = ""
- if _is_vs_2017_or_2019(vc_path):
+ if _is_vs_2017_or_2019(repository_ctx, vc_path):
full_version = _get_vc_full_version(repository_ctx, vc_path)
# Because VCVARSALL.BAT is from the latest VC installed, so we check if the latest
@@ -441,7 +444,7 @@
def find_msvc_tool(repository_ctx, vc_path, tool, target_arch = "x64"):
"""Find the exact path of a specific build tool in MSVC. Doesn't %-escape the result."""
tool_path = None
- if _is_vs_2017_or_2019(vc_path) or _is_msbuildtools(vc_path):
+ if _is_vs_2017_or_2019(repository_ctx, vc_path) or _is_msbuildtools(vc_path):
full_version = _get_vc_full_version(repository_ctx, vc_path)
if full_version:
tool_path = "%s\\Tools\\MSVC\\%s\\bin\\HostX64\\%s\\%s" % (vc_path, full_version, target_arch, tool)