Skip to content

Commit 890f8be

Browse files
Fix shader-coverage demo launch on Windows (#11625)
## Motivation `run_coverage.py` in both shader-coverage demos fails on Windows because the demo `.exe` lives in `build/examples/<target>/<config>/` but the Slang runtime DLLs (`slang.dll`, etc.) live in `build/<config>/bin/`. The Windows loader only searches the exe's own directory, so the process aborts immediately with `STATUS_DLL_NOT_FOUND` (0xC0000135). ## Changes Prepend the runtime DLL directory to the child process `PATH` before launching the demo binary. The directory is derived from the already-known binary path and handles both CMake generator layouts: ```python _WIN_CONFIGS = {"Release", "Debug", "RelWithDebInfo"} demo_env = os.environ.copy() if platform.system() == "Windows" and len(binary.parents) >= 4: config = (binary.parent.name if binary.parent.name in _WIN_CONFIGS else binary.parents[2].name) dll_dir = binary.parents[3] / config / "bin" demo_env["PATH"] = str(dll_dir) + os.pathsep + demo_env.get("PATH", "") result = subprocess.run(binary_cmd, env=demo_env) ``` - **Multi-config** (Ninja Multi-Config / Visual Studio): exe at `<build>/examples/<target>/<config>/<exe>` — config = `binary.parent.name`. - **Single-config** (plain Ninja / Makefiles): exe at `<build>/<config>/examples/<target>/<exe>` — config = `binary.parents[2].name`. - In both cases `binary.parents[3]` is the build root and the DLL directory is `<build-root>/<config>/bin/`. - No change on POSIX — `rpath` handles DLL resolution there. Both `examples/shader-coverage-bvh-traversal/run_coverage.py` and `examples/shader-coverage-image-pipeline/run_coverage.py` receive the same fix. Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
1 parent 5353bc5 commit 890f8be

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

examples/shader-coverage-bvh-traversal/run_coverage.py

100644100755
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ def _candidate_paths(slang_root: Path) -> list:
6969
# Windows .exe variants (multi-config)
7070
*(slang_root / "build" / "examples" / _TARGET / config / (_TARGET + ".exe")
7171
for config in ("Release", "Debug", "RelWithDebInfo")),
72+
# Windows .exe variants (single-config)
73+
*(slang_root / "build" / config / "examples" / _TARGET / (_TARGET + ".exe")
74+
for config in ("Release", "Debug", "RelWithDebInfo")),
7275
]
7376

7477

@@ -184,7 +187,21 @@ def main(argv=None):
184187
binary_cmd = [str(binary), f"--mode={mode}",
185188
f"--output-dir={output_dir}", *demo_args]
186189
print(f"[1/3] running demo: {' '.join(str(a) for a in binary_cmd)}")
187-
result = subprocess.run(binary_cmd)
190+
# On Windows the runtime DLLs (slang.dll etc.) live in
191+
# <build-root>/<config>/bin/, not next to the demo exe. Prepend that
192+
# directory to PATH so the loader finds them (otherwise STATUS_DLL_NOT_FOUND).
193+
# Multi-config layout: exe at <build>/examples/<target>/<config>/<exe>
194+
# Single-config layout: exe at <build>/<config>/examples/<target>/<exe>
195+
# In both cases binary.parents[3] is the build root and the config name
196+
# sits one level above the exe (multi) or two levels above (single).
197+
_WIN_CONFIGS = {"Release", "Debug", "RelWithDebInfo"}
198+
demo_env = os.environ.copy()
199+
if platform.system() == "Windows" and len(binary.parents) >= 4:
200+
config = (binary.parent.name if binary.parent.name in _WIN_CONFIGS
201+
else binary.parents[2].name)
202+
dll_dir = binary.parents[3] / config / "bin"
203+
demo_env["PATH"] = str(dll_dir) + os.pathsep + demo_env.get("PATH", "")
204+
result = subprocess.run(binary_cmd, env=demo_env)
188205
if result.returncode != 0:
189206
sys.exit(f"error: demo exited with code {result.returncode}")
190207

examples/shader-coverage-image-pipeline/run_coverage.py

100644100755
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ def _candidate_paths(slang_root: Path) -> list:
6969
# Windows .exe variants (multi-config)
7070
*(slang_root / "build" / "examples" / _TARGET / config / (_TARGET + ".exe")
7171
for config in ("Release", "Debug", "RelWithDebInfo")),
72+
# Windows .exe variants (single-config)
73+
*(slang_root / "build" / config / "examples" / _TARGET / (_TARGET + ".exe")
74+
for config in ("Release", "Debug", "RelWithDebInfo")),
7275
]
7376

7477

@@ -193,7 +196,21 @@ def main(argv=None):
193196
binary_cmd = [str(binary), f"--mode={mode}",
194197
f"--output-dir={output_dir}", *demo_args]
195198
print(f"[1/2] running demo: {' '.join(str(a) for a in binary_cmd)}")
196-
result = subprocess.run(binary_cmd)
199+
# On Windows the runtime DLLs (slang.dll etc.) live in
200+
# <build-root>/<config>/bin/, not next to the demo exe. Prepend that
201+
# directory to PATH so the loader finds them (otherwise STATUS_DLL_NOT_FOUND).
202+
# Multi-config layout: exe at <build>/examples/<target>/<config>/<exe>
203+
# Single-config layout: exe at <build>/<config>/examples/<target>/<exe>
204+
# In both cases binary.parents[3] is the build root and the config name
205+
# sits one level above the exe (multi) or two levels above (single).
206+
_WIN_CONFIGS = {"Release", "Debug", "RelWithDebInfo"}
207+
demo_env = os.environ.copy()
208+
if platform.system() == "Windows" and len(binary.parents) >= 4:
209+
config = (binary.parent.name if binary.parent.name in _WIN_CONFIGS
210+
else binary.parents[2].name)
211+
dll_dir = binary.parents[3] / config / "bin"
212+
demo_env["PATH"] = str(dll_dir) + os.pathsep + demo_env.get("PATH", "")
213+
result = subprocess.run(binary_cmd, env=demo_env)
197214
if result.returncode != 0:
198215
sys.exit(f"error: demo exited with code {result.returncode}")
199216

0 commit comments

Comments
 (0)