Skip to content

Commit 88a7e4f

Browse files
committed
gh-104612: Fix libpython3.so stable ABI on Linux using patchelf
The previous implementation of libpython3.so created an empty wrapper library that recorded libpython3.X.so in DT_NEEDED but did not properly re-export symbols. The program with proper Py_LIMITED_API defined cannot actually linked with libpython3.so (-lpython3), and it makes the stable API pointless. And libpython3.so cannot simply be a symbolic link to the libpython3.X.so, since due to the SONAME contains the minor version, error will still be reported during the runtime with a different pythons so version. This fix uses patchelf on Linux to copy the versioned library and set its SONAME to libpython3.so, ensuring binaries get the correct DT_NEEDED entry for stable ABI compatibility. - Add PATCHELF variable detection in configure.ac (Linux only) - Require patchelf on Linux, error if not found - Update libpython3.so target to use patchelf when available - Fall back to original behavior on non-Linux platforms A program linked with the newly patched libpython3.so and stable API, can run with the previous empty wrapper libpython3.so.
1 parent 6181b69 commit 88a7e4f

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

Makefile.pre.in

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ SHELL= /bin/sh -e
6767
# Use this to make a link between python$(VERSION) and python in $(BINDIR)
6868
LN= @LN@
6969

70+
# patchelf is used on Linux to set SONAME of libpython3.so for stable ABI
71+
PATCHELF= @PATCHELF@
72+
7073
# Portable install script (configure doesn't always guess right)
7174
INSTALL= @INSTALL@
7275
INSTALL_PROGRAM=@INSTALL_PROGRAM@
@@ -1026,7 +1029,11 @@ libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACE_OBJS)
10261029
fi
10271030

10281031
libpython3.so: libpython$(LDVERSION).so
1029-
$(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^
1032+
if test -n "$(PATCHELF)"; then \
1033+
cp $^ $@ && $(PATCHELF) --set-soname $@ $@; \
1034+
else \
1035+
$(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^; \
1036+
fi
10301037

10311038
libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
10321039
$(CC) -dynamiclib $(PY_CORE_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACE_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \

configure

Lines changed: 54 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,17 @@ if test -z "$LN" ; then
17191719
esac
17201720
fi
17211721

1722+
# patchelf is required on Linux to set the SONAME of libpython3.so for stable ABI support
1723+
AC_SUBST([PATCHELF])
1724+
case $ac_sys_system in
1725+
Linux*)
1726+
AC_CHECK_PROG([PATCHELF], [patchelf], [patchelf], [])
1727+
if test -z "$PATCHELF"; then
1728+
AC_MSG_ERROR([patchelf is required on Linux for stable ABI support. Please install patchelf.])
1729+
fi
1730+
;;
1731+
esac
1732+
17221733
# For calculating the .so ABI tag.
17231734
AC_SUBST([ABIFLAGS])
17241735
AC_SUBST([ABI_THREAD])

0 commit comments

Comments
 (0)