Skip to content

Commit 4b79ef4

Browse files
committed
build(bootstrap): probe vcvarsall environment
1 parent 524e792 commit 4b79ef4

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

bootstrap.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ def __init__(self, cmd_line_args=None):
197197
self.options.refresh_all = self.cmd_line_args.get("refresh_all", False)
198198
self.prompted_options = set()
199199
self.compiler_info = {}
200+
self.env = None
200201

201202
def prompt_string(self, prompt, default):
202203
"""
@@ -419,7 +420,7 @@ def run_cmd(self, cmd, cwd=None):
419420
print(f"{color}{cwd}> {cmd_str}{reset}")
420421
else:
421422
print(f"{color}{cwd}> {cmd}{reset}")
422-
r = subprocess.run(cmd, shell=isinstance(cmd, str), check=True, cwd=cwd)
423+
r = subprocess.run(cmd, shell=isinstance(cmd, str), check=True, cwd=cwd, env=self.env)
423424
if r.returncode != 0:
424425
raise RuntimeError(f"Command '{cmd}' failed with return code {r.returncode}.")
425426

@@ -668,6 +669,8 @@ def is_non_empty_dir(self, path):
668669

669670
@lru_cache(maxsize=1)
670671
def get_vs_install_locations(self):
672+
if not self.is_windows():
673+
return []
671674
p = os.environ.get('ProgramFiles(x86)', r"C:\Program Files (x86)")
672675
path_vswhere = os.path.join(p,
673676
"Microsoft Visual Studio", "Installer", "vswhere.exe")
@@ -684,6 +687,8 @@ def get_vs_install_locations(self):
684687
return [inst.get("installationPath") for inst in info]
685688

686689
def find_vs_tool(self, tool):
690+
if not self.is_windows():
691+
return None
687692
vs_tools = ["cmake", "ninja", "git", "python"]
688693
if tool not in vs_tools:
689694
return None
@@ -923,6 +928,61 @@ def probe_compilers(self):
923928
print(f"Default C++ compiler: {self.compiler_info.get('CMAKE_CXX_COMPILER_ID', 'unknown')} ({self.compiler_info.get('CMAKE_CXX_COMPILER', 'unknown')})")
924929
print(f"Default C++ build system: {self.compiler_info.get('CMAKE_GENERATOR', 'unknown')}")
925930

931+
@lru_cache(maxsize=1)
932+
def probe_msvc_dev_env(self):
933+
if not self.is_windows():
934+
return
935+
print("Probing MSVC development environment variables...")
936+
vs_roots = self.get_vs_install_locations()
937+
vcvarsall_path = None
938+
for vs_root in vs_roots or []:
939+
vcvarsall_path_candidate = os.path.join(vs_root, "VC", "Auxiliary", "Build", "vcvarsall.bat")
940+
if os.path.exists(vcvarsall_path_candidate):
941+
vcvarsall_path = vcvarsall_path_candidate
942+
print(f"Found vcvarsall.bat at {vcvarsall_path}.")
943+
break
944+
if not vcvarsall_path:
945+
print("No vcvarsall.bat found. MSVC development environment variables will not be set.")
946+
return
947+
# Run it with x64 argument and VSCMD_DEBUG=2 set and get the output
948+
cmd = [vcvarsall_path, "x64"]
949+
env = os.environ.copy()
950+
env["VSCMD_DEBUG"] = "2"
951+
result = subprocess.run(cmd, env=env, text=True, capture_output=True, shell=True)
952+
# print the output
953+
if result.returncode != 0:
954+
raise RuntimeError(f"vcvarsall.bat failed:\n{result.stdout}\n{result.stderr}")
955+
956+
# Get the lines in the output between the two lines that among other things say
957+
post_env = {}
958+
in_post_init_header = False
959+
for line in result.stdout.splitlines():
960+
contains_post_init_header = "--------------------- VS Developer Command Prompt Environment [post-init] ---------------------" in line
961+
if contains_post_init_header:
962+
if in_post_init_header:
963+
break
964+
in_post_init_header = True
965+
continue
966+
if not in_post_init_header:
967+
continue
968+
if '=' in line:
969+
key, value = line.split('=', 1)
970+
post_env[key.strip()] = value.strip()
971+
if not in_post_init_header or not post_env:
972+
print("No post-init environment variables found in vcvarsall.bat output.")
973+
return
974+
975+
# Populate the environment with anything that changed, and later use it
976+
# for any other commands.
977+
self.env = os.environ.copy()
978+
for key, value in post_env.items():
979+
if key not in self.env:
980+
print(f"* Inserting {key}={value}")
981+
elif value != self.env[key]:
982+
print(f"* Updating {key}={value}")
983+
self.env[key] = value
984+
print("MSVC development environment variables extracted successfully.")
985+
926986

927987
@lru_cache(maxsize=1)
928988
def is_homebrew_clang(self):
@@ -2255,6 +2315,7 @@ def generate_run_configs(self):
22552315

22562316
def install_all(self):
22572317
self.check_compilers()
2318+
self.probe_msvc_dev_env()
22582319
self.check_tools()
22592320
self.setup_mrdocs_src_dir()
22602321
self.setup_third_party_dir()

0 commit comments

Comments
 (0)