@@ -146,152 +146,12 @@ def build_wheels(pip):
146146 subprocess .check_call ([pip , "wheel" , spec ])
147147
148148
149- _warned_dlls = []
150-
151-
152- def repair_wheels_windows (output_dir , wheels ):
153- import pefile
154- from machomachomangler .pe import redll
155-
156- def resolve_dll_src (dll ):
157- # search for dependencies in system directories
158- dll_search_paths = [
159- os .environ ["WINDIR" ],
160- join (os .environ ["WINDIR" ], "System32" ),
161- * os .environ ["PATH" ].split (";" ),
162- ]
163- ignored_dlls = [
164- # These DLLs are just provided by Windows.
165- # This list is probably incomplete.
166- r"advapi32\.dll" ,
167- r"advapires32\.dll" ,
168- r"atl.*\.dll" ,
169- r"comctl32\.dll" ,
170- r"comdlg32\.dll" ,
171- r"crtdll\.dll" ,
172- r"gdi32\.dll" ,
173- r"hal.*\.dll" ,
174- r"imm32\.dll" ,
175- r"iphlpapi\.dll" ,
176- r"kernel32\.dll" ,
177- r"kernelbase\.dll" ,
178- r"msvbvm60\.dll" ,
179- r"msvcirt\.dll" ,
180- r"msvcrt?.*\.dll" ,
181- r"netapi32\.dll" ,
182- r"ntdll\.dll" ,
183- r"ole32\.dll" ,
184- r"pdh\.dll" ,
185- r"powrprof\.dll" ,
186- r"psapi\.dll" ,
187- r"rpcrt4\.dll" ,
188- r"sechost\.dll" ,
189- r"shell32\.dll" ,
190- r"shlwapi\.dll" ,
191- r"shscrap\.dll" ,
192- r"ucrtbase\.dll" ,
193- r"user32\.dll" ,
194- r"version\.dll" ,
195- r"winmm\.dll" ,
196- r"ws2_32\.dll" ,
197- # These match DLLs that provide API sets.
198- # See https://learn.microsoft.com/en-us/windows/win32/apiindex/windows-apisets
199- r"api-ms-win-.*\.dll" ,
200- r"ext-ms-win-.*\.dll" ,
201- # These match DLLs that we provide in GraalPy
202- r"python.*\.dll" ,
203- # These are the DLLs typically linked when building with MSVC. See
204- # https://learn.microsoft.com/en-us/cpp/windows/determining-which-dlls-to-redistribute
205- # When these are included, the user should install the latest
206- # redist package from
207- # https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist
208- # However, https://aka.ms/vs/17/redist.txt lists the libraries
209- # which can be included in application distributions.
210- r"concrt.*\.dll" ,
211- r"mfc.*\.dll" ,
212- r"msvcp.*\.dll" ,
213- r"vcamp.*\.dll" ,
214- r"vccorlib.*\.dll" ,
215- r"vcomp.*\.dll" ,
216- r"vcruntime.*\.dll" ,
217- ]
218- if not dll :
219- return
220- if any (re .match (pat , basename (dll ), re .IGNORECASE ) for pat in ignored_dlls ):
221- if dll not in _warned_dlls :
222- print ("Not including" , dll , flush = True )
223- _warned_dlls .append (dll )
224- return
225- if isabs (dll ):
226- return dll
227- for search_path in dll_search_paths :
228- if exists (src := join (search_path , dll )):
229- return src
230-
231- def resolve_dll_target (dll , dependent , checksum ):
232- return join (dirname (dependent ), f"{ checksum } .{ basename (dll )} " )
233-
234- def filehash (files ):
235- sha1 = hashlib .sha1 ()
236- for file in files :
237- with open (file , mode = "rb" ) as f :
238- sha1 .update (f .read ())
239- return sha1 .hexdigest ()[:8 ]
240-
241- for whl in wheels :
242- with TemporaryDirectory () as name :
243- with zipfile .ZipFile (whl ) as f :
244- f .extractall (name )
245-
246- # find all pyd files and recursively copy dependencies
247- dlls = glob (f"{ name } /**/*.pyd" , recursive = True )
248- checksum = filehash (dlls )
249- dependents_to_dependencies = {}
250- while dlls :
251- dll = dlls .pop ()
252- with pefile .PE (dll ) as pe :
253- pe_info = pe .dump_dict ()
254- for syms in pe_info .get ("Imported symbols" , []):
255- for sym in syms :
256- if dep_src := resolve_dll_src (sym .get ("DLL" , b"" ).decode ("utf-8" )):
257- if not exists (dep_tgt := resolve_dll_target (dep_src , dll , checksum )):
258- print ("Including" , dep_src , "as" , dep_tgt , flush = True )
259- shutil .copy (dep_src , dep_tgt )
260- dlls .append (dep_tgt )
261- dependents_to_dependencies .setdefault (dll , []).append (dep_src )
262-
263- for dll , dependencies in dependents_to_dependencies .items ():
264- mapping = {}
265- for dep_src in dependencies :
266- mapping [basename (dep_src ).encode ("utf-8" )] = basename (
267- resolve_dll_target (dep_src , dll , checksum )
268- ).encode ("utf-8" )
269- with open (dll , mode = "rb" ) as f :
270- data = f .read ()
271- print (
272- "Rewriting\n \t " ,
273- "\n \t " .join ([k .decode ("utf-8" ) for k in mapping .keys ()]),
274- "\n \t ->\n \t " ,
275- "\n \t " .join ([v .decode ("utf-8" ) for v in mapping .values ()]),
276- "\n in" ,
277- dll ,
278- )
279- data = redll (data , mapping )
280- with open (dll , mode = "wb" ) as f :
281- f .write (data )
282-
283- os .makedirs (output_dir , exist_ok = True )
284- if exists (whl_tgt := join (output_dir , whl )):
285- os .unlink (whl_tgt )
286- shutil .make_archive (whl_tgt , "zip" , name )
287- os .rename (f"{ whl_tgt } .zip" , whl_tgt )
288-
289-
290149def repair_wheels ():
291150 if sys .platform == "win32" :
292- ensure_installed ("machomachomangler" )
293- ensure_installed ("pefile" )
294- repair_wheels_windows ("wheelhouse" , glob ("*.whl" ))
151+ ensure_installed ("delvewheel" )
152+ subprocess .check_call (
153+ [sys .executable , "-m" , "delvewheel" , "repair" , "-v" , "--exclude" , "python-native.dll" , "-w" , "wheelhouse" , * glob ("*.whl" )]
154+ )
295155 elif sys .platform == "linux" :
296156 ensure_installed ("auditwheel" )
297157 subprocess .check_call (
0 commit comments