Skip to content

Commit 2485b51

Browse files
committed
feat(dispatcher): auto-reconstruct MSVC build environment for cl.exe
- dynamically derives MSVC include/lib paths from cl.exe location - discovers latest Windows SDK (ucrt, um, shared) and injects headers/libs - eliminates dependency on vcvarsall.bat / Developer Command Prompt - enables native compilation from arbitrary shells and subprocesses - applies env only to compiler subprocess (no global pollution) - adds debug visibility for derived INCLUDE/LIB paths Implementation: - infer MSVC root via cl.exe path traversal - resolve SDK include/lib directories from Windows Kits - construct minimal compile env (INCLUDE, LIB) - pass env to subprocess.run() for isolated execution This allows omnipkg to compile C extensions in fully unmanaged environments (daemon workers, CI, user shells) without requiring pre-configured toolchains. Modified: • src/omnipkg/dispatcher.py (+40/-1 lines) [gitship-generated]
1 parent a55037e commit 2485b51

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

src/omnipkg/dispatcher.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,47 @@ def _maybe_install_c_dispatcher():
460460
if debug:
461461
print(f"[C-INSTALL] compiling: {compiler_cmd}", file=sys.stderr)
462462

463+
# Build env with MSVC include/lib paths when cl.exe is the compiler.
464+
# This reconstructs what vcvarsall.bat does, so the user doesn't need
465+
# a Developer Command Prompt — cl.exe works from any shell.
466+
compile_env = os.environ.copy()
467+
if sys.platform == "win32" and "cl" in (compiler or "").lower():
468+
try:
469+
cl_path = Path(compiler)
470+
# cl.exe lives at: .../MSVC/<ver>/bin/HostX64/x64/cl.exe
471+
msvc_root = cl_path.parent.parent.parent.parent
472+
msvc_include = str(msvc_root / "include")
473+
msvc_lib = str(msvc_root / "lib" / "x64")
474+
sdk_includes, sdk_libs = [], []
475+
sdk_base = Path(r"C:\Program Files (x86)\Windows Kits")
476+
if not sdk_base.exists():
477+
sdk_base = Path(r"C:\Program Files\Windows Kits")
478+
if sdk_base.exists():
479+
inc_base = sdk_base / "include"
480+
lib_base = sdk_base / "lib"
481+
sdk_versions = sorted(inc_base.iterdir(), reverse=True)
482+
if sdk_versions:
483+
sdk_ver = sdk_versions[0]
484+
for sub in ("ucrt", "um", "shared"):
485+
p = sdk_ver / sub
486+
if p.exists():
487+
sdk_includes.append(str(p))
488+
lib_ver = lib_base / sdk_ver.name
489+
for sub in ("ucrt/x64", "um/x64"):
490+
p = lib_ver / sub.replace("/", os.sep)
491+
if p.exists():
492+
sdk_libs.append(str(p))
493+
compile_env["INCLUDE"] = os.pathsep.join([msvc_include] + sdk_includes)
494+
compile_env["LIB"] = os.pathsep.join([msvc_lib] + sdk_libs)
495+
if debug:
496+
print(f"[C-INSTALL] MSVC INCLUDE={compile_env['INCLUDE']}", file=sys.stderr)
497+
print(f"[C-INSTALL] MSVC LIB={compile_env['LIB']}", file=sys.stderr)
498+
except Exception as e:
499+
if debug:
500+
print(f"[C-INSTALL] could not derive MSVC env: {e}", file=sys.stderr)
501+
463502
try:
464-
r = subprocess.run(compiler_cmd, capture_output=True, timeout=15)
503+
r = subprocess.run(compiler_cmd, capture_output=True, timeout=15, env=compile_env)
465504
if debug:
466505
print(f"[C-INSTALL] compiler returncode={r.returncode}", file=sys.stderr)
467506
if r.stdout:

0 commit comments

Comments
 (0)