Skip to content

Commit d7eb25a

Browse files
committed
docs: document PyQt incompatibility
Related to #95.
1 parent 053f62b commit d7eb25a

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

docs/quirks.rst

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,62 @@ is the dominant library on Linux.
224224
Some functionality may behave subtly differently as a result of our choice
225225
to link ``libedit`` by default. (We choose ``libedit`` by default to
226226
avoid GPL licensing requirements of ``readline``.)
227+
228+
.. _quirk_linux_libx11:
229+
230+
Static Linking of ``libX11`` / Incompatibility with PyQt on Linux
231+
=================================================================
232+
233+
The ``_tkinter`` Python extension module in the Python standard library
234+
statically links against ``libX11``, ``libxcb``, and ``libXau`` on Linux.
235+
In addition, the ``_tkinter`` extension module is statically linked into
236+
``libpython`` and isn't a standalone shared library file. This effectively
237+
means that all these X11 libraries are statically linked into the main
238+
Python interpreter.
239+
240+
On typical builds of Python on Linux, ``_tkinter`` will link against
241+
external shared libraries. e.g.::
242+
243+
$ ldd /usr/lib/python3.9/lib-dynload/_tkinter.cpython-39-x86_64-linux-gnu.so
244+
linux-vdso.so.1 (0x00007fff3be9d000)
245+
libBLT.2.5.so.8.6 => /lib/libBLT.2.5.so.8.6 (0x00007fdb6a6f8000)
246+
libtk8.6.so => /lib/x86_64-linux-gnu/libtk8.6.so (0x00007fdb6a584000)
247+
libtcl8.6.so => /lib/x86_64-linux-gnu/libtcl8.6.so (0x00007fdb6a3c1000)
248+
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdb6a1d5000)
249+
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007fdb6a097000)
250+
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdb69f49000)
251+
libXft.so.2 => /lib/x86_64-linux-gnu/libXft.so.2 (0x00007fdb69f2e000)
252+
libfontconfig.so.1 => /lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007fdb69ee6000)
253+
libXss.so.1 => /lib/x86_64-linux-gnu/libXss.so.1 (0x00007fdb69ee1000)
254+
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdb69eda000)
255+
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fdb69ebe000)
256+
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdb69e9c000)
257+
/lib64/ld-linux-x86-64.so.2 (0x00007fdb6a892000)
258+
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fdb69e70000)
259+
libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007fdb69dad000)
260+
libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fdb69da0000)
261+
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fdb69d71000)
262+
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fdb69d68000)
263+
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007fdb69d53000)
264+
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007fdb69d4b000)
265+
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fdb69d43000)
266+
libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x00007fdb69d08000)
267+
libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007fdb69cfa000)
268+
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fdb69ce2000)
269+
libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007fdb69cbd000)
270+
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x00007fdb69cb0000)
271+
272+
The static linking of ``libX11`` and other libraries can cause problems when
273+
3rd party Python extension modules also loading similar libraries are also
274+
loaded into the process. For example, extension modules associated with ``PyQt``
275+
are known to link against a shared ``libX11.so.6``. If multiple versions of
276+
``libX11`` are loaded into the same process, run-time crashes / segfaults can
277+
occur. See e.g. https://github.com/indygreg/python-build-standalone/issues/95.
278+
279+
The conceptual workaround is to not statically link ``libX11`` and similar
280+
libraries into ``libpython``. However, this requires re-linking a custom
281+
``libpython`` without ``_tkinter``. It is possible to do this with the object
282+
files included in the distributions. But there isn't a turnkey way to do this.
283+
And you can't easily remove ``_tkinter`` and its symbols from the pre-built
284+
and ready-to-use Python install included in this project's distribution
285+
artifacts.

0 commit comments

Comments
 (0)