Repository navigation
Conversation
c2e856d to
d715fa3
Compare
geofft
left a comment
There was a problem hiding this comment.
Unfortunately I think there's a good amount of stuff missing compared to our current implementation, and this is a hairy enough spot that I don't think we should have any regressions in 3.15 compared to what we do on older versions.
On glibc/Linux, we add a DT_NEEDED for bin/python to $ORIGIN/../lib/libpython3.x.so.1.0 (and for lib/libpython3.so to $ORIGIN/libpython3.x.so.1.0) , to avoid issues with LD_LIBRARY_PATH taking precedence. I'm relatively sure this is annoying to do without a separate patchelf step, but maybe it can be done.
We also set an DT_RPATH for bin/python on Linux (required on musl, compatibility on glibc). This is not a DT_RUNPATH, so this needs -Wl,--disable-new-dtags.
I don't see either of those in the Makefile diff, in addition to the other things noted in the comments.
If you really wanted, you could start by upstreaming this gated to macOS only, which might be a little less code to write.
Also speaking of platform support, the dynamic linkers on the BSDs and Solaris works much like glibc, so most of our Linux support should apply there too in the version that gets upstreamed.
In either case, I would error out if --enable-relocatable is passed on another platform.
| Author: Zanie Blue <contact@zanie.dev> | ||
| Date: Fri Nov 21 15:44:42 2025 -0600 | ||
|
|
||
| Set linker arguments when `--enabled-relocatable` is used |
There was a problem hiding this comment.
| Set linker arguments when `--enabled-relocatable` is used | |
| Set linker arguments when `--enable-relocatable` is used |
| -change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \ | ||
| ${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} | ||
|
|
||
| # We also normalize /tools/deps/lib/libz.1.dylib to the system location. |
There was a problem hiding this comment.
How come you didn't need to preserve this?
There was a problem hiding this comment.
This almost certainly needs to be preserved, this fixes up _tkinter, right? That is, you need this to go into the CPython Makefile rule for building shared-library extension modules (... which we might not be using, to make things more exciting).
| @@ -1025,10 +1025,19 @@ libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACE_OBJS) | ||
| fi | ||
|
|
||
| libpython3.so: libpython$(LDVERSION).so |
There was a problem hiding this comment.
You need to patch the libpython$(LDVERSION).so target too. (LINKFORSHARED is only used when building the interpreter.)
| + LINKFORSHARED="-Xlinker -export-dynamic" | ||
| + # Add rpath for relocatable builds | ||
| + if test "x$enable_relocatable" = xyes; then | ||
| + LINKFORSHARED="$LINKFORSHARED -Wl,-rpath=\$ORIGIN/../lib" |
There was a problem hiding this comment.
The rpath here is not escaped correctly resulting in the the RPATH in the binary being set to RIGIN/../lib
This causes among other issues, _tkinter not to be importable.
There was a problem hiding this comment.
| + LINKFORSHARED="$LINKFORSHARED -Wl,-rpath=\$ORIGIN/../lib" | |
| + LINKFORSHARED="$LINKFORSHARED -Wl,-rpath,'\$\$ORIGIN/../lib'" |
| + LINKFORSHARED="-Xlinker -export-dynamic" | ||
| + # Add rpath for relocatable builds | ||
| + if test "x$enable_relocatable" = xyes; then | ||
| + LINKFORSHARED="$LINKFORSHARED -Wl,-rpath=\$ORIGIN/../lib" |
There was a problem hiding this comment.
| + LINKFORSHARED="$LINKFORSHARED -Wl,-rpath=\$ORIGIN/../lib" | |
| + LINKFORSHARED="$LINKFORSHARED -Wl,-rpath,'\$\$ORIGIN/../lib'" |
|
A question that I suspect will get asked when upstreaming this, is what should be done to accommodate third-party libraries such as libtcl, libtk, libz in relocatable builds. With the exception of libtcl/tk these are statically linked but this patch should support cases where these are dynamically linked. Adding a RPATH entry to the extensions with a relative path to I could also see an opportunity to hash the SO name of third-party libraries on Linux to protect against clashes with system libraries. This approach is used by |
d715fa3 to
2df7631
Compare
PBS currently adjusts installed binaries after linking to give them relative library search paths. For Python 3.15 and newer, backport an experimental
--enable-relocatablemode that supplies paths when linking installed interpreters,libpython, and standard-library extensions. Keep these flags out ofLDSHARED, since third-party extensions may use a different layout.Link build-tree and install binaries separately from the same objects. An installed-layout
DT_RPATHin the build-tree interpreter can otherwise select an unrelatedlibpythonbeforeRUNSHARED'sLD_LIBRARY_PATH. When BOLT is enabled, apply the build binaries' profiles to the install variants as well. On glibc,DT_RPATHentries are searched beforeLD_LIBRARY_PATHwhen the requesting object has noDT_RUNPATH; they can also be used for indirect dependencies. On macOS, use an@rpathidentity and relative search paths. For copied interpreters from non-framework shared builds,venvcreates a symlink to the base library directory so the interpreter can findlibpython. The environment still depends on its base installation.PBS retains its explicit relative glibc
libpython3.sodependency, macOS zlib normalization, static-module linking, Python path discovery, and Tcl/Tk data discovery changes. This mode supports the default installation layout on Linux and non-framework macOS. Dependency bundling, data-file relocation, and rewriting shebangs orsysconfigpaths remain separate concerns.Skip Windows build jobs when the selected matrix is empty.
The upstream drafts compare this approach in zanieb/cpython#48 with a
DT_RUNPATHalternative in zanieb/cpython#49.