-
-
Notifications
You must be signed in to change notification settings - Fork 12k
BUG: distutils: fix extra DLL loading in certain scenarios #10229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
is this working with freeze? (py2exe, cxfreeze, ..) |
This should reduce some DLL hell scenarios, namely scipy/scipy#8064. partial credits to @carlkl
|
Let's give this a try. Thanks @xoviat . |
|
Hrm... seems this breaks editable installations when using conda (while it fixes the bug mentioned). @isuruf what can we do about this; I think it's an issue with conda? |
|
The point of this is to move the |
|
One possible solution could be to only add the directory to the search path if it isn't empty. |
|
Please do not do this. Importing a specific module should not modify the way that process loads subsequent DLLs. The fix for DLL hell for numpy should not break any other modules. |
|
We already modified PATH so that we could get SciPy out the door. The problem is specifically that if there is an |
|
IIUC, @cgohlke also does this with his wheels. |
|
Actually, I'm not correct. I'm leaning toward reverting this and giving up on the linked issue. |
This goes against the point of the UCRT, the linked issue is that the user has an old version of the UCRT. The UCRT is distributed as part of the OS now, so the correct fix is to run Windows Update AFAICT. |
|
That's what I initially thought, but the C++ runtime is not included in the UCRT, so Windows update won't fix the problem. The current status of SciPy, which is compiled with the officially supported compiler on the latest official Python distribution (not Anaconda) is that it works perfectly when the user hasn't installed a slighly out-of-date C++ runtime required by some other program, but doesn't work when that's not the case, even if the user has all of their Windows updates. If something goes wrong with the gfortran stuff, that's to be expected because it's a hack. But that's not the part we're talking about here. |
|
I know this is not really Anaconda's fault, but this issue irritates me because neither Microsoft nor Python has a standardized solution for a problem that occurs when you follow all of their recommendations. |
|
I don't see how the new library calls are causing issues with other entries in the dll search path, but couldn't we avoid messing with the search path entirely by using LoadLibrary to load the needed DLLs? Once a DLL with a given name has been loaded by a process, subsequent loads should use the version that has already been loaded, even if that version isn't on the search path. |
|
The potential issues with bundling and forcing this to load are:
|
|
It would help if Microsoft would release or allow to release versioned MSVC runtime packages on PyPI, e.g. |
|
Idea: write a simple "hello world" C++ executable and bundle it in the MSVC wheel. Then it's just a program that happens to be in an archive format that others can use. |
|
One further complication, it's unclear what the backcompat guarantees are for the MSVC c++ runtime. Supposedly the MSVC 2017 runtime is backwards compatible with binaries built with MSVC 2015 (see https://stackoverflow.com/a/40896092/1935144), but compatibility across versions hasn't been a guarantee with MSVC in the past and it's unclear the extent to which that'll be true in the future. |
I tried that for a short while with bdist_wininst packages but Microsoft might not like that their license is bypassed in an obvious way. |
|
FTR, I've been thinking about writing an "auditwheel" for windows that would automate much of the packaging of windows wheels. The idea is to use the conda forge to install all of the C libraries and then use It's not an ideal solution, but it's the only sane method I could come up with. |
|
I'm not sure if this is what you mean, but, like auditwheel, you can rename the libraries with unique names. Then use Nathaniel's petool to point the relevant pyd files to the renamed DLLs. That way, there's virtually no risk of a DLL name clash. |
|
Would that work with |
|
Then you're back in the multiple different C++ runtimes world of potential hurt. You'd at least lose out on DLLs being loaded multiple times, also I do not know what would happen if |
|
Yes, I guess a renamed msvcp140.dll would work. Then only numpy would be using that runtime, and it should not affect anything else in the process. What DLL is Python.org Python using? Doesn't it have the same problem? I should say that I'm no expert on DLLs ... |
|
Before messing with msvcp140.dll: has anyone been able to reproduce scipy/scipy#8064? I have not so far. VC140.CRT version 14.0.24210 is the latest version for VS2015 and partially shipped with the official CPython installer. Forcing or suggesting all numpy/scipy users to revert to 14.0.24123 (a RC) is not a good idea IMO. |
|
I'll throw a few dot point comments in. Sorry for not doing nice threading, but I've only just seen this issue (and only because of a direct email - I'm on holiday right now and have been avoiding GitHub notifications like crazy ;) )
So I guess the short answer is that you probably can't win this battle - DLL hell is still not a nice place. Statically linking the C++ dependencies is probably going to be the safest option - adding linker options Building statically for PyPI and dynamically for conda (assuming you're letting Anaconda do the core numpy/scipy builds) is likely the best of both worlds, and then you never have to actually distribute any CRT DLLs. Leave C++ runtime management to the system integrator (Anaconda for conda, the end user for pip) or remove the need for it completely (static linking). |
|
For redistributables like the C++ runtime that don't ship with the OS, I think the only reasonable options are (a) static linking, or (b) mangling the name, using my wacky tool to update the binaries to point to the right name, and then preloading the library with the mangled name using This is assuming that your wheel doesn't have a public C++ ABI that other software outside your wheel might use. This is a very safe assumption for most (all?) Python packages. |
|
IIUC, if we load
|
I can't reproduce it either. Btw, 14.0.24215 is the latest |
That's right, the |
Numpy wheels on Windows were clearing the ctypes path when they loaded the OpenBLAS DLL, leading to failure of DLL loads subsequent to NumPy import because the needed DLLs could not be found. This isn't a straight revert, it restores to the 1.15.x version of the relevant code. Closes numpy#11431.
BUG: Revert #10229 to fix DLL loads on Windows.
Numpy wheels on Windows were clearing the ctypes path when they loaded the OpenBLAS DLL, leading to failure of DLL loads subsequent to NumPy import because the needed DLLs could not be found. This isn't a straight revert, it restores to the 1.15.x version of the relevant code. Closes numpy#11431.
BUG: Revert #10229 to fix DLL loads on Windows.
This should reduce some DLL hell scenarios, namely scipy/scipy#8064.
partial credits to @carlkl