Skip to content

Commit 9df432b

Browse files
Technologicatclaude
andcommitted
CI: force MSVC on Windows so .pyd files link to the standard runtime
Root cause of the Phase 7 Windows test failures found via the pefile diagnostic. On GitHub Actions Windows runners, the default PATH has MinGW-w64's gcc.exe but NOT MSVC's cl.exe (MSVC Build Tools are installed but only activated by vcvarsall.bat / a Developer Command Prompt). Meson's auto-detection picks whichever C compiler it finds first on PATH, so the source build in the `test` job was using MinGW-w64 gcc and the resulting .pyd files linked against: - libgcc_s_seh-1.dll (MinGW GCC runtime / SEH unwinding) - libgomp-1.dll (MinGW GCC OpenMP runtime) - libstdc++-6.dll (transitively, if any) These DLLs live in MinGW's bin directory, not on the Python process's DLL search path at test time. So LoadLibrary on infra.pyd (first .pyd to import libgcc_s_seh-1.dll) and simple/expert/lapackdrivers.pyd (first to import libgomp-1.dll) failed with Windows' signature- unhelpful "DLL load failed: The specified module could not be found." Fix: add `ilammy/msvc-dev-cmd@v1` before the install step on Windows. It runs `vcvarsall.bat x64` and exports INCLUDE / LIB / LIBPATH / PATH so that cl.exe is findable; meson's auto-detection then picks MSVC instead of MinGW. MSVC-built .pyd files link against the universal CRT (api-ms-win-crt-*.dll, always available on Windows 10+) and `vcomp140.dll` (the first CI run confirmed via ctypes that this DLL is reachable from a 64-bit Python process), and load cleanly. cibuildwheel already uses MSVC on Windows via its own mechanism (it invokes vcvarsall inside each wheel-build subshell), so the `build-wheels` job was never affected — only the `test` job which does a source editable install. Published wheels were always going to be MSVC-built and load correctly; we just need the source-install test path to match. The diagnostic step is intentionally left in place for one more run so we can confirm the imports table on the next CI run shows only api-ms-win-crt + python313 + vcomp140 (no libgcc/libgomp). Will remove it in a follow-up commit. scipy/numpy use the same ilammy/msvc-dev-cmd approach on their CI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a7f9ba2 commit 9df432b

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ jobs:
6363
if: runner.os == 'macOS'
6464
run: brew install libomp
6565

66+
# Activate the MSVC toolchain on Windows so that meson picks up
67+
# `cl.exe` instead of the runner's default MinGW-w64 gcc. The latter
68+
# links our .pyd files against libgcc_s_seh-1.dll and libgomp-1.dll,
69+
# which are not on the Python process's DLL search path at runtime
70+
# (they live in MinGW's bin directory), resulting in "DLL load
71+
# failed" on import. MSVC-built extensions link only against the
72+
# universal CRT and vcomp140.dll, all of which are always on PATH
73+
# for a 64-bit Python process. scipy/numpy use the same approach on
74+
# their CI.
75+
- uses: ilammy/msvc-dev-cmd@v1
76+
if: runner.os == 'Windows'
77+
6678
- name: Install build and test dependencies
6779
run: pip install meson-python meson ninja Cython numpy scipy pytest
6880

0 commit comments

Comments
 (0)