Skip to content

Commit f8d71bf

Browse files
committed
feat: enhance GDBM and Python build scripts for compatibility
- Updated build_gdbm.sh to include --enable-libgdbm-compat, allowing Python's _dbm module to build against GDBM. - Modified build_python_py2.sh and build_python.sh to specify --with-dbmliborder=gdbm:ndbm, ensuring proper library order during Python builds. - Enhanced rpath-patcher.sh to cover all ELF files, improving the handling of shared libraries and maintaining install relocatability.
1 parent 11fc1a6 commit f8d71bf

4 files changed

Lines changed: 31 additions & 8 deletions

File tree

common/build/deplib/build_gdbm.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,10 @@ wget https://ftp.gnu.org/gnu/gdbm/gdbm-${GDBM_VERSION}.tar.gz
88
tar -xzf gdbm-${GDBM_VERSION}.tar.gz && cd gdbm-${GDBM_VERSION}
99

1010
export CFLAGS="${CFLAGS} -fPIC"
11-
./configure --prefix=/opt/shared_libraries
11+
# --enable-libgdbm-compat exposes gdbm-ndbm.h and libgdbm_compat.so so
12+
# Python's _dbm module (driven by --with-dbmliborder=gdbm:ndbm) can build
13+
# against gdbm. Without it _dbm shows up in the "failed" list at the end
14+
# of `make` — `dbm.gnu` still works (that uses _gdbm), but `dbm.ndbm` and
15+
# the plain `dbm` dispatch path both need this.
16+
./configure --prefix=/opt/shared_libraries --enable-libgdbm-compat
1217
make -j $(nproc) && make install

common/build/deplib/build_python.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@ export LOCAL_INCLUDES="${LOCAL_INCLUDES} -I/opt/shared_libraries/include/" # som
2121

2222
export CFLAGS="${CFLAGS} ${LOCAL_INCLUDES}"
2323
export CPPFLAGS="${CPPFLAGS} ${LOCAL_INCLUDES}"
24-
export LDFLAGS="${LDFLAGS} -L/opt/shared_libraries/lib -lffi"
24+
# Bake an absolute rpath to /opt/shared_libraries/lib into every C extension
25+
# linked during this build. --with-openssl-rpath=auto only handles OpenSSL;
26+
# other extensions (_curses→libtinfo, _sqlite3→libsqlite3, readline→libreadline,
27+
# _ctypes→libffi, …) have no CPython-level flag to set their rpath, so
28+
# without this the build's own `sysconfig --generate-posix-vars` import test
29+
# fails with "Error loading shared library libtinfo.so.6: No such file".
30+
# rpath-patcher.sh rewrites this to $ORIGIN-relative after packing, so the
31+
# final image stays relocatable.
32+
export LDFLAGS="${LDFLAGS} -L/opt/shared_libraries/lib -lffi -Wl,-rpath,/opt/shared_libraries/lib"
2533

2634
# Free-threaded build (PEP 703 / "no-GIL"), added in Python 3.13. Enabled
2735
# per-Dockerfile with `ENV DISABLE_GIL=1` in the python_builder stage. The
@@ -37,6 +45,7 @@ fi
3745
./configure --build="$gnuArch" --enable-loadable-sqlite-extensions \
3846
--enable-optimizations --enable-option-checking=fatal --enable-shared \
3947
--with-lto --with-system-expat --without-ensurepip \
48+
--with-dbmliborder=gdbm:ndbm \
4049
--prefix="$INSTALL_PREFIX" --with-openssl-rpath=auto \
4150
--with-openssl=/opt/shared_libraries \
4251
$CONFIGURE_EXTRA

common/build/deplib/build_python_py2.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export LDFLAGS="${LDFLAGS} -L/opt/shared_libraries/lib -Wl,-rpath,/opt/shared_li
5454
--enable-option-checking=fatal \
5555
--enable-shared \
5656
--enable-unicode=ucs4 \
57+
--with-dbmliborder=gdbm:ndbm \
5758
--prefix="$INSTALL_PREFIX"
5859

5960
make -j $(nproc)

common/build/wrappers/rpath-patcher.sh

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,21 @@ patch_elf_rpath() {
4545
shared_lib_dir=/opt/python/shared_libraries/lib
4646
python_lib_dir=/opt/python/lib
4747

48-
# Cover both `bin/` binaries (python*-real, pip*-real, pure C helpers
49-
# like python-config) and `lib-dynload/` C extensions (_ssl.so,
50-
# _hashlib.so, _ctypes.so, …). lib-dynload/*.so isn't marked
51-
# executable, so drop the -executable filter and let the ELF-magic
52-
# grep do the filtering instead.
48+
# Cover every ELF we ship:
49+
# * `bin/*` python*-real, pip*-real, python-config, …
50+
# * `*/lib-dynload/*` C extensions (_ssl, _curses, _ctypes, …)
51+
# * `*.so` / `*.so.*` libpython3.N.so.1.0 and any other shared libs
52+
# (libpython picks up the LDFLAGS rpath too, so
53+
# we rewrite it here to keep the install
54+
# relocatable).
55+
# Name-based pre-filter avoids running `file` on thousands of .py files
56+
# under lib/python*/; the ELF-magic grep still filters anything that
57+
# slips through.
5358
find /opt/python -type f \
54-
\( -path "*/bin/*" -o -path "*/lib-dynload/*" \) \
59+
\( -path "*/bin/*" \
60+
-o -path "*/lib-dynload/*" \
61+
-o -name "*.so" \
62+
-o -name "*.so.*" \) \
5563
-exec file {} \; \
5664
| grep 'ELF' | grep 'dynamically linked' | cut -d: -f1 \
5765
| while read -r elf_file; do

0 commit comments

Comments
 (0)