Skip to content

Set rpath on our shared libraries, and use ORIGIN-relative dependencies for libtcl and libtk #742

@geofft

Description

@geofft

As a result of #619 I added a DT_RPATH to bin/python3 to support third-party wheels that (incorrectly) link libpython3.x.so.1.0 and expect to be able to find it. The symbols come from bin/python3, we just needed libraries to be able to not fail when resolving dependencies by filename. In other words, we weren't actually using the DT_RPATH ourselves. By the same logic, I didn't add an rpath to libpython3.x.so.1.0 itself, because it didn't need to load any other libraries.

In #676 I added two more shared libraries, libtcl8.6.so and libtk8.6.so. On Linux these are referenced with an unqualified name in _tkinter, and so they only work because of the DT_RPATH on bin/python3. That is a bug, both because we shouldn't be relying on the bin/python rpath ourselves (so we have the option to remove it later), and because it means that embedders linking libpython3 won't be able to load _tkinter properly without setting an rpath of their own. (On macOS, these are referenced through an rpath in _tkinter, so I think this works properly for embedders.)

Also, pyinstaller/pyinstaller#9204 requests that we make ldd .../_tkinter.cpython-xxx.so report the path of libtcl and libtk properly.

I think I want to make the following changes:

  • Set DT_RPATH on all of our shared libraries, for consistency. Probably including libpython3.so (the ABI3 interface).
  • On glibc, use ${ORIGIN}-relative DT_NEEDED entries for the dependenci from tkinter to libtcl and libtk, so that it can still find them if the embedder is using DT_RUNPATH, which suppresses DT_RPATH.
  • Add validation tests that we have rpaths on all dynamic objects and${ORIGIN}-relative DT_NEEDED entries on glibc except for things that are provided by the OS.
  • Analogously on macOS, ensure we have relative LC_LOAD_DYLIB commands for everything not provided by the OS. (This can be @executable_path-relative, @loader_path-relative, or @rpath-relative if we also have an LC_RPATH that is executable- or loader-relative. Note that rpaths work a little differently with macOS dyld - they're not used by default, they're only used for things that are specifically loaded from @rpath/something.dylib.)
  • Add integration tests for embedders, including an embedder that uses DT_RUNPATH.
  • Add a specific regression test for ldd _tkinter for PyInstaller.

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