1515"""
1616from __future__ import annotations
1717
18+ import importlib .util
1819import os
1920import shutil
2021import subprocess
3132# delvewheel invocation
3233# ---------------------------------------------------------------------------
3334
35+ def _ensure_delvewheel () -> None :
36+ """Install delvewheel into the active cibuildwheel venv when missing."""
37+ if importlib .util .find_spec ("delvewheel" ) is not None :
38+ return
39+
40+ print ("[repair] delvewheel not found in build venv; installing..." )
41+ result = subprocess .run (
42+ [sys .executable , "-m" , "pip" , "install" , "delvewheel" ],
43+ check = False ,
44+ )
45+ if result .returncode != 0 or importlib .util .find_spec ("delvewheel" ) is None :
46+ print ("[repair] ERROR: failed to install delvewheel" , file = sys .stderr )
47+ raise SystemExit (1 )
48+
49+
3450def _delvewheel_cmd (* args : str ) -> list [str ]:
3551 """Invoke delvewheel via the active Python (Scripts/ may be off PATH)."""
3652 return [sys .executable , "-m" , "delvewheel" , * args ]
@@ -122,6 +138,61 @@ def _find_omp_dll_via_vswhere(vswhere: Path) -> Path | None:
122138 print (f"[repair] Found DLL under VS install root: { matches [0 ]} " )
123139 return matches [0 ]
124140
141+ redist_match = _find_omp_dll_via_redist (install_root )
142+ if redist_match :
143+ return redist_match
144+
145+ return None
146+
147+
148+ def _find_omp_dll_via_redist (install_root : Path | None = None ) -> Path | None :
149+ """Search VC Redist trees where MSVC ships libomp140 for /openmp:llvm."""
150+ roots : list [Path ] = []
151+ if install_root is not None and install_root .is_dir ():
152+ roots .append (install_root )
153+ roots .extend (
154+ [
155+ Path ("C:/Program Files/Microsoft Visual Studio/2022/Enterprise" ),
156+ Path ("C:/Program Files/Microsoft Visual Studio/2022/Community" ),
157+ Path ("C:/Program Files/Microsoft Visual Studio/2022/Professional" ),
158+ ]
159+ )
160+
161+ seen : set [Path ] = set ()
162+ for root in roots :
163+ try :
164+ resolved = root .resolve ()
165+ except OSError :
166+ continue
167+ if resolved in seen or not resolved .is_dir ():
168+ continue
169+ seen .add (resolved )
170+
171+ for name in _MSVC_OMP_DLL_NAMES :
172+ for pattern in (
173+ f"VC/Redist/MSVC/*/x64/Microsoft.VC*.OpenMP.LLVM/{ name } " ,
174+ f"VC/Redist/MSVC/*/debug_nonredist/x64/Microsoft.VC*.OpenMP.LLVM/{ name } " ,
175+ ):
176+ matches = sorted (resolved .glob (pattern ))
177+ if matches :
178+ print (f"[repair] Found DLL via VS redist: { matches [0 ]} " )
179+ return matches [0 ]
180+
181+ return None
182+
183+
184+ def _find_omp_dll_from_env () -> Path | None :
185+ """Use LIBOMP_DLL_DIR when CI has already resolved the OpenMP runtime."""
186+ env_dir = os .environ .get ("LIBOMP_DLL_DIR" , "" ).strip ()
187+ if not env_dir :
188+ return None
189+
190+ directory = Path (env_dir )
191+ for name in _MSVC_OMP_DLL_NAMES :
192+ candidate = directory / name
193+ if candidate .is_file ():
194+ print (f"[repair] Found DLL via LIBOMP_DLL_DIR: { candidate } " )
195+ return candidate
125196 return None
126197
127198
@@ -143,6 +214,10 @@ def _find_omp_dll_fallback() -> Path | None:
143214
144215
145216def find_omp_dll () -> Path | None :
217+ dll = _find_omp_dll_from_env ()
218+ if dll :
219+ return dll
220+
146221 vswhere = _find_vswhere ()
147222 if vswhere :
148223 print (f"[repair] Using vswhere: { vswhere } " )
@@ -152,6 +227,11 @@ def find_omp_dll() -> Path | None:
152227 print ("[repair] vswhere did not find libomp140*.dll; trying fallback paths..." )
153228 else :
154229 print ("[repair] vswhere.exe not found; trying fallback paths..." )
230+
231+ dll = _find_omp_dll_via_redist ()
232+ if dll :
233+ return dll
234+
155235 return _find_omp_dll_fallback ()
156236
157237
@@ -178,6 +258,8 @@ def main() -> int:
178258 print ("Usage: repair_windows_wheel.py <dest_dir> <wheel>" , file = sys .stderr )
179259 return 2
180260
261+ _ensure_delvewheel ()
262+
181263 dest = Path (sys .argv [1 ]).resolve ()
182264 wheel = Path (sys .argv [2 ]).resolve ()
183265 dest .mkdir (parents = True , exist_ok = True )
0 commit comments