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