<p>Hi,</p>
<p>I'm a bit confused regarding how wheels of libraries linking to Qt5 should be built. Specifically, I am interested in <a href="https://github.com/frescobaldi/python-poppler-qt5">python-poppler-qt5</a>. 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?</p>
<p>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.)</p>
<p>As advised on <a href="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</a>, 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:</p>
<pre><code>$ 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)
</code></pre>
<p>which looks like it links dynamically to several Qt5 libraries, though not to PyQt5's <code>*.abi3.so</code> libraries (is that what is meant by "statically linked"?).</p>
<p>If I try to import it, I get</p>
<pre><code>$ 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
</code></pre>
<p>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?</p>
<p>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.</p>
<p>Thanks,</p>
<p>Jean</p>