[Windows] how to prevent the wrong version of zlib1.dll to be used by lib-dynload modules
Hello list, I encountered a problem with the Windows packaging of gPodder[1] using msys2: basic libraries (zlib, openssl) depended upon by python platform-specific modules are loaded preferably : 1. from lib-dynload (where they are not) 2. from the Windows directory (can be any version) 3. from the binary directory, next to gpodder.exe (where they are) So an old zlib1.dll installed by another application in c:\Windows was loaded, incompatible with libpng and gPodder couldn't start. I don't know what's the best approach to solve it: - copy those libraries to lib\pythonxx\lib-dynload (works) - preload them in my main script before they are loaded by the module (works) - patch something in python (dynload_win.c ?) to search first in the executable directory (not tried) Please can you provide me with insight on this? Details in the issue: [1] Thanks, [1] https://github.com/gpodder/gpodder/issues/478
In general, if the dependent DLL is in the same directory as the module loading it (the .pyd or .exe), then it should be loaded first. If it's alongside the .exe, it should be loaded before any of the other search paths. If it's being loaded directly from Python, your best option is to resolve the full path before trying to load it (via ctypes or whatever). I have argued in the past about trying to hack the importer in order to "fix" this (since any fix is highly likely to break currently working install layouts), and this sounds like it is best solved by putting dependencies in an expected location. However, I don't know how much impact the msys2 aspect of this has. You mention "lib\pythonxx\lib-dynload", which is not present in a normal Python install on Windows. So possibly you're already on a non-standard build, which means my advice is pretty useless to you. There are also significant parts of both zlib and openssl available in a normal Python install on Windows, so perhaps you don't need to include alternate copies of those with your package? Are there particular features or APIs missing that you need? Cheers, Steve On 23Jul2018 1531, Eric Le Lay wrote:
Hello list,
I encountered a problem with the Windows packaging of gPodder[1] using msys2:
basic libraries (zlib, openssl) depended upon by python platform-specific modules are loaded preferably : 1. from lib-dynload (where they are not) 2. from the Windows directory (can be any version) 3. from the binary directory, next to gpodder.exe (where they are)
So an old zlib1.dll installed by another application in c:\Windows was loaded, incompatible with libpng and gPodder couldn't start.
I don't know what's the best approach to solve it: - copy those libraries to lib\pythonxx\lib-dynload (works) - preload them in my main script before they are loaded by the module (works) - patch something in python (dynload_win.c ?) to search first in the executable directory (not tried)
Please can you provide me with insight on this?
Details in the issue: [1]
Thanks,
On Mon, Jul 23, 2018, 08:22 Eric Le Lay
Hello list,
I encountered a problem with the Windows packaging of gPodder[1] using msys2:
basic libraries (zlib, openssl) depended upon by python platform-specific modules are loaded preferably : 1. from lib-dynload (where they are not) 2. from the Windows directory (can be any version) 3. from the binary directory, next to gpodder.exe (where they are)
So an old zlib1.dll installed by another application in c:\Windows was loaded, incompatible with libpng and gPodder couldn't start.
I don't know what's the best approach to solve it: - copy those libraries to lib\pythonxx\lib-dynload (works) - preload them in my main script before they are loaded by the module (works) - patch something in python (dynload_win.c ?) to search first in the executable directory (not tried)
The way we avoid these kinds of issues on Linux is to rename included libraries to unique names (e.g. zlib1-aef3742bc3e.dll), and patch the extension modules to look for the new names. There's a script (auditwheel) that does the heavy lifting. On MacOS there's a similar script people use, called "delocate". Unfortunately no one has written a script like this for Windows yet. I think it'd be neat if eventually we could consolidate all this into auditwheel, but there aren't that many people interested in working on it. If you wanted to help, the hardest part is already done: https://github.com/njsmith/machomachomangler/blob/master/README.rst#pe-featu... Alternatively if you just want a hack that works quick, I'd do the preload thing. In general you need to do this anyway, if you don't have all your extension modules in the same directory. (Unfortunately Windows doesn't have the equivalent of RPATH.) -n
Le Mon, 23 Jul 2018 10:47:33 -0700,
Nathaniel Smith
On Mon, Jul 23, 2018, 08:22 Eric Le Lay
wrote: Hello list,
I encountered a problem with the Windows packaging of gPodder[1] using msys2:
basic libraries (zlib, openssl) depended upon by python platform-specific modules are loaded preferably : 1. from lib-dynload (where they are not) 2. from the Windows directory (can be any version) 3. from the binary directory, next to gpodder.exe (where they are)
So an old zlib1.dll installed by another application in c:\Windows was loaded, incompatible with libpng and gPodder couldn't start.
I don't know what's the best approach to solve it: - copy those libraries to lib\pythonxx\lib-dynload (works) - preload them in my main script before they are loaded by the module (works) - patch something in python (dynload_win.c ?) to search first in the executable directory (not tried)
The way we avoid these kinds of issues on Linux is to rename included libraries to unique names (e.g. zlib1-aef3742bc3e.dll), and patch the extension modules to look for the new names. There's a script (auditwheel) that does the heavy lifting. On MacOS there's a similar script people use, called "delocate".
Unfortunately no one has written a script like this for Windows yet. I think it'd be neat if eventually we could consolidate all this into auditwheel, but there aren't that many people interested in working on it. If you wanted to help, the hardest part is already done: https://github.com/njsmith/machomachomangler/blob/master/README.rst#pe-featu...
Alternatively if you just want a hack that works quick, I'd do the preload thing. In general you need to do this anyway, if you don't have all your extension modules in the same directory. (Unfortunately Windows doesn't have the equivalent of RPATH.)
-n
Thanks Steve, Nathaniel, eryk for your detailed answers. I use the mingw64-python3 package in msys2: https://github.com/Alexpux/MINGW-packages/tree/master/mingw-w64-python3 It's not the same as msys2 python3 or Python for Windows. It has quite a few patches. While looking into it, I found a similar issue - on the package https://github.com/Alexpux/MINGW-packages/issues/3381 - on quodlibet (the program I adapted windows packaging from) https://github.com/quodlibet/quodlibet/issues/2817 For the moment I cowardly favor the quick hack of preloading over patching dlls or using application-configuration-files. Regarding auditwheel, isn't it only handling wheel files (*.whl), not basic dll modules like binascii-cpython-36m.dll? Thanks for the link to machomachomangler. -- Eric
On Mon, Jul 23, 2018 at 2:31 PM, Eric Le Lay
I encountered a problem with the Windows packaging of gPodder[1] using msys2:
Are you using regular Windows Python with msys2, or their custom port?
I installed msys2 and used pacman to install Python 3.6. The msys2
environment names libraries with an "msys-" prefix in the "/usr/bin"
directory, such as msys-python3.6m.dll, msys-readline7.dll, and
msys-z.dll (zlib). This is also the application directory of the msys2
build of Python (i.e. "/usr/bin/python.exe"), so it's the first
directory in the default DLL search path (ahead of system directories
and PATH). Unlike Windows Python, msys2 Python does not use the
alternate search path that replaces the application directory with the
DLL directory in the search path.
A way to implement this that allows multiple versions of a DLL to be
loaded in the same process is to use an assembly that includes the DLL
file in its "
MSYS2 has two Python ports, msys2 and mingw-w64. I believe Eric was
referring to the mingw-w64 one?
zlib1.dll in C:\Windows\System32 is a packaging error on the part of
whatever put it there and that is what needs to be fixed here. ISVs
need to stop putting anything in that directory as it leads to the
worst form of DLL-hell. You should try to remove that file (back it up
as something may break) and just move on with your work in my opinion.
On Tue, Jul 24, 2018 at 8:15 AM, eryk sun
On Mon, Jul 23, 2018 at 2:31 PM, Eric Le Lay
wrote: I encountered a problem with the Windows packaging of gPodder[1] using msys2:
Are you using regular Windows Python with msys2, or their custom port?
I installed msys2 and used pacman to install Python 3.6. The msys2 environment names libraries with an "msys-" prefix in the "/usr/bin" directory, such as msys-python3.6m.dll, msys-readline7.dll, and msys-z.dll (zlib). This is also the application directory of the msys2 build of Python (i.e. "/usr/bin/python.exe"), so it's the first directory in the default DLL search path (ahead of system directories and PATH). Unlike Windows Python, msys2 Python does not use the alternate search path that replaces the application directory with the DLL directory in the search path.
A way to implement this that allows multiple versions of a DLL to be loaded in the same process is to use an assembly that includes the DLL file in its "
.manifest" file. Add the assembly to the extension module's #2 manifest (typically embedded, but can be " .2"). The system looks for the " " subdirectory in the module directory. In Windows 7+ you can also add a probing path in a config file (i.e. " .config") [1] that extends the SxS search path with up to 9 relative paths, which can be up to two levels above the module directory (i.e. "..\.."). [1]: https://docs.microsoft.com/en-us/windows/desktop/SbsCs/application-configura... _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/mingw.android%40gmail.com
participants (5)
-
Eric Le Lay
-
eryk sun
-
Nathaniel Smith
-
Ray Donnelly
-
Steve Dower