Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .github/workflows/build-python-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- run: python --version
- name: Install build deps
# patchelf is used by android/build.sh (3.12 path) to set SONAME
# on libpython3.X.so, which CPython's Makefile rule otherwise
# skips when LDLIBRARY==INSTSONAME (the Android case).
run: sudo apt-get update && sudo apt-get install -y patchelf
- working-directory: android
shell: bash
run: |
Expand Down
24 changes: 5 additions & 19 deletions android/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ if [ $version_int -le 312 ]; then
patches+=" soname"
fi
if [ $version_int -eq 312 ]; then
patches+=" bldlibrary grp"
# soname_linktime: makes CPython's Makefile rule emit -Wl,-soname even
# when INSTSONAME == LDLIBRARY (the Android case), so the shipped
# libpython3.X.so carries DT_SONAME. 3.13+ already gets this from its official
# Android tooling; this 3.12-only patch matches that behavior at link time.
patches+=" soname_linktime bldlibrary grp"
fi
for name in $patches; do
patch_file="$script_dir/patches/$name.patch"
Expand Down Expand Up @@ -140,24 +144,6 @@ if [ $version_int -le 312 ]; then
make -j $CPU_COUNT
make install prefix=$PREFIX

# CPython's Makefile rule for libpython skips `-Wl,-soname` when
# INSTSONAME == LDLIBRARY, which is the case on Android (both are
# `libpython3.X.so`). The shipped libpython3.X.so therefore has no
# DT_SONAME, so consumer wheels record whichever name the linker
# was asked for in DT_NEEDED — e.g. a `-lpython3` resolved via a
# `libpython3.so` shim writes `libpython3.so` instead of the right
# `libpython3.X.so`. Patching the SONAME in here makes consumer
# DT_NEEDED entries correct regardless of how the link was reached.
# 3.13+ uses CPython's official Android tooling, which sets SONAME
# natively, so this branch only needs the post-install fix.
if command -v patchelf >/dev/null 2>&1; then
patchelf --set-soname "libpython$version_short.so" \
"$PREFIX/lib/libpython$version_short.so"
else
echo "WARNING: patchelf not installed; libpython$version_short.so will lack SONAME." >&2
echo " Consumer wheels may end up with the wrong DT_NEEDED entry." >&2
fi

echo ">>> Replacing host platform"
sed -i -e "s/_PYTHON_HOST_PLATFORM=.*/_PYTHON_HOST_PLATFORM=android-$api_level-$abi/" $PREFIX/lib/python$version_short/config-$version_short/Makefile
else
Expand Down
25 changes: 25 additions & 0 deletions android/patches/soname_linktime.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CPython 3.12's libpython link rule only passes -Wl,-soname when
INSTSONAME != LDLIBRARY. On Android both equal "libpython3.X.so", so
the else branch runs and the shipped libpython has no DT_SONAME.
Consumer wheels' DT_NEEDED then records whatever name the linker saw
(e.g. "libpython3.so" via a shim), and the device fails to dlopen at
runtime.

Adding -Wl,-h$(INSTSONAME) to the else branch makes ld stamp the
SONAME during the actual link — same shape of fix as CPython 3.13's
official Android tooling. Avoids needing a post-process patchelf step
(which on NDK r27d interacts badly with llvm-strip and produces a
PT_LOAD whose p_offset and p_vaddr violate the ELF spec's
`p_offset ≡ p_vaddr (mod p_align)` requirement, breaking dlopen on
strict bionic and crashing Py_Initialize on permissive bionic).

--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -819,5 +819,5 @@ libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACE_OBJS)
$(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM); \
$(LN) -f $(INSTSONAME) $@; \
else \
- $(BLDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM); \
+ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM); \
fi

Loading