Skip to content

FYI - python-build-standalone now builds dynamic Tkinter/Tcl/Tk #3155

@geofft

Description

@geofft

Hi! In today's release (20250808) of python-build-standalone we've split out _tkinter, libtcl, and libtk into their own dynamic libraries (astral-sh/python-build-standalone#676). This should address issues like #2540 where tkinter didn't work right. I'm opening this mostly because we're now generating three new .so files and I don't know if you need to adjust something on your end to pick them up. But also, if you see any issues with the new setup, please let me know, either here or by opening an issue in python-build-standalone.

Details on the implementation, if it's helpful:

  • _tkinter is now a separate extension module and no longer statically linked into bin/python and libpython (so any user code using _tkinter will need to bundle the dynamic library and unpack it at runtime)
  • There are separate libtcl8.6.so and libtk8.6.so (or .dylib) libraries inside our lib directory.
  • On Linux, bin/python3 has a DT_RPATH pointing it at the lib directory, so import _tkinter finds our copies of libtcl and libtk. Users of libpython3.x.so will need to set up rpaths or something on their own. (If it's helpful can add an rpath to libpython3.x.so, or tweak the DT_NEEDED in _tkinter to use $ORIGIN/../../libtcl8.6.so etc. (though that trick would only work for gllibc, not musl).
  • On macOS, lib/python3.x/lib-dynload/_tkinter.cpython-3x-darwin.so has an LC_RPATH pointing at @loader_path/../../, and the install name of libtcl and the LC_LOAD_DYLIB entry in _tkinter is @rpath/libtcl8.6.so.dylib, and the same for libtk. So if you maintain the lib/ directory structure you shouldn't need to fiddle with library paths on your own.
  • libX11 and friends are now statically linked into libtk on Linux. At some point I might make these dynamic libraries and/or attempt to look for the system version.

Also, speaking of changes to dynamic libraries, as of a few months ago, our Linux builds statically link libpython into the interpreter, so you no longer need lib/libpython3.x.so.1 to run bin/python. We still ship libpython for the sake of people embedding Python into a larger program. At some point I want to split this out but I haven't yet figured out how to coordinate that transition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions