Library versioning
Jean Abou Samra
jean at abou-samra.fr
Sat Mar 4 09:52:04 GMT 2023
Hi,
I'm a bit confused regarding how wheels of libraries linking to Qt5 should be built. Specifically, I am interested in [python-poppler-qt5](https://github.com/frescobaldi/python-poppler-qt5). The binding is built (with sip) on top of PyQt5, therefore I suppose it must link into Qt5 and PyQt5 libraries. This means that if I advise people to do "pip install python-poppler-qt5", it will download python-poppler-qt5 wheels built for one exact version of PyQt5, and other versions will not work due to ABI incompatibility. Right?
So, how should this be done? Should the project specify a requirement "PyQt5 == specific-version"? Also, what ABI compatibility guarantees are provided on PyQt5? (I know Qt5 is guaranteed ABI-compatible within a minor release series.)
As advised on [https://discuss.python.org/t/packaging-a-c-extension-with-a-dependency-on-another-c-extension/24462/2](https://discuss.python.org/t/packaging-a-c-extension-with-a-dependency-on-another-c-extension/24462/2), I looked briefly at how QScintilla does this, but I'm a bit confused. The project page says it's statically linked, yet on my system:
```
$ ldd Qsci.abi3.so
ldd: attention : vous n'avez pas la permission d'exécution pour `./Qsci.abi3.so'
linux-vdso.so.1 (0x00007fff737e7000)
libQt5PrintSupport.so.5 => /lib64/libQt5PrintSupport.so.5 (0x00007f941df7e000)
libQt5Widgets.so.5 => /lib64/libQt5Widgets.so.5 (0x00007f941d200000)
libQt5Gui.so.5 => /lib64/libQt5Gui.so.5 (0x00007f941ca00000)
libQt5Core.so.5 => /lib64/libQt5Core.so.5 (0x00007f941c400000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f941c000000)
libm.so.6 => /lib64/libm.so.6 (0x00007f941d920000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f941df5c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f941be23000)
libGL.so.1 => /lib64/libGL.so.1 (0x00007f941d179000)
libpng16.so.16 => /lib64/libpng16.so.16 (0x00007f941df22000)
libz.so.1 => /lib64/libz.so.1 (0x00007f941df08000)
libharfbuzz.so.0 => /lib64/libharfbuzz.so.0 (0x00007f941d08d000)
libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f941c323000)
libdouble-conversion.so.3 => /lib64/libdouble-conversion.so.3 (0x00007f941d078000)
libicui18n.so.71 => /lib64/libicui18n.so.71 (0x00007f941ba00000)
libicuuc.so.71 => /lib64/libicuuc.so.71 (0x00007f941b803000)
libpcre2-16.so.0 => /lib64/libpcre2-16.so.0 (0x00007f941c972000)
libzstd.so.1 => /lib64/libzstd.so.1 (0x00007f941c26e000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f941b6c2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f941e01a000)
libGLX.so.0 => /lib64/libGLX.so.0 (0x00007f941d046000)
libX11.so.6 => /lib64/libX11.so.6 (0x00007f941b57b000)
libXext.so.6 => /lib64/libXext.so.6 (0x00007f941c259000)
libGLdispatch.so.0 => /lib64/libGLdispatch.so.0 (0x00007f941bd6a000)
libfreetype.so.6 => /lib64/libfreetype.so.6 (0x00007f941b4ad000)
libgraphite2.so.3 => /lib64/libgraphite2.so.3 (0x00007f941c237000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f941d916000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f941bd36000)
liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f941b48a000)
libicudata.so.71 => /lib64/libicudata.so.71 (0x00007f9419600000)
libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007f941b3ed000)
libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f941b3c2000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f941b3af000)
libbrotlidec.so.1 => /lib64/libbrotlidec.so.1 (0x00007f941b3a2000)
libXau.so.6 => /lib64/libXau.so.6 (0x00007f941d910000)
libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f941b37f000)
```
which looks like it links dynamically to several Qt5 libraries, though not to PyQt5's `*.abi3.so` libraries (is that what is meant by "statically linked"?).
If I try to import it, I get
```
$ python
Python 3.11.2 (main, Feb 8 2023, 00:00:00) [GCC 12.2.1 20221121 (Red Hat 12.2.1-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt5.Qsci
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /home/jean/.local/lib/python3.11/site-packages/PyQt5/Qsci.abi3.so: undefined symbol: _ZdlPvm, version Qt_5
```
because it's linking to Qt5 libs provided by my system. It works if I install qscintilla in a fresh venv, because pip then installs PyQt5 in the venv, with the latest PyPI version instead of my distro version. But if I downgrade qscintilla, it fails again, which I interpret as qscintilla really being built for one PyQt5 version and not being compatible with the next one. Yet, it seems to use "PyQt5 >= x.y" requirements, not "PyQt5 == x.y". Why?
As you can see, I'm a beginner to this sort of stuff. If the questions seem dumb to you, I appreciate pointers to relevant resources.
Thanks,
Jean
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20230304/a93af2b5/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20230304/a93af2b5/attachment.sig>
More information about the PyQt
mailing list