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
29 changes: 15 additions & 14 deletions packaging/aix/sitecustomize.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
# AIX: preload libc++abi.a so that __xlcxx_personality_v0 is available
# when pydantic_core's libunwind.a(libunwind.so.1) dependency is resolved.
# AIX: best-effort preload of libc++abi.a with RTLD_GLOBAL.
#
# Background:
# pydantic_core is a Rust extension module compiled against AIX's libunwind.a.
# libunwind.so.1 declares __xlcxx_personality_v0 as an undefined symbol,
# expecting the IBM XLC++ C++ ABI runtime (libc++abi.a) to provide it.
# Python is compiled with GCC, so libc++abi.a is not loaded at Python startup.
# Without this preload, "import pydantic" raises:
# ImportError: rtld: 0712-001 Symbol __xlcxx_personality_v0 was referenced
# from module /usr/lib/libunwind.a(libunwind.so.1), but a runtime definition
# of the symbol was not found.
# Some C++ extensions compiled with IBM XLC++ declare __xlcxx_personality_v0
# as an undefined symbol, expecting the IBM XLC++ ABI runtime (libc++abi.a)
# to provide it. Python is compiled with GCC and does not load libc++abi.a
# automatically, so those extensions fail to import without this preload.
#
# Fix: load libc++abi.a with RTLD_GLOBAL before any checks run so the symbol
# is available to all subsequently loaded shared modules.
# pydantic_core previously triggered this via a dependency on the IBM-provided
# /usr/lib/libunwind.a(libunwind.so.1), which needs __xlcxx_personality_v0.
# pydantic_core now uses a bundled libunwind derived from the GCC runtime
# (libgcc_s.a), which has no libc++abi.a dependency, so pydantic_core no
# longer requires this preload. It is kept as a best-effort safety net for
# any other XLC++-compiled extension that might be loaded at runtime.
#
# AIX 7.2 TL5+ / AIX 7.3: /usr/lib/libc++abi.a(libc++abi.so.1) ships with the OS.
# AIX 7.2 TL4 and earlier: this file is absent; the except clause silently continues.
# Outcome: either the load succeeds (libc++abi.a is present, RTLD_GLOBAL makes
# __xlcxx_personality_v0 available to all subsequent modules) or the except
# clause silently continues (file absent — AIX 7.2 TL4 and earlier — and no
# extension that needs it is present, so nothing breaks).
import ctypes as _ctypes

try:
Expand Down
30 changes: 30 additions & 0 deletions packaging/aix/stages/01-native-libs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ READLINE_VERSION="8.2" # yum install readline-devel
SQLITE_VERSION="3.53.0" # built from source (amalgamation)
GDBM_VERSION="1.23" # yum install gdbm-devel
LIBICONV_VERSION="1.17" # yum install libiconv
LIBUNWIND_VERSION="1.0" # derived from /opt/freeware/lib/libgcc_s.a (GCC runtime)

# ─── Helpers ──────────────────────────────────────────────────────────────────

Expand Down Expand Up @@ -521,6 +522,35 @@ done
stage_toolbox_lib libiconv "$LIBICONV_VERSION" \
/opt/freeware/lib/libiconv.a

# ── libunwind (derived from GCC runtime libgcc_s.a) ──────────────────────────
#
# pydantic_core links against libunwind.a(libunwind.so.1). We build this
# archive by extracting the shared object from the GCC runtime libgcc_s.a
# (which contains all _Unwind_* symbols) and re-packaging it under the
# libunwind.so.1 member name that pydantic_core expects.
#
# This avoids the IBM XL C++ Runtime version (/usr/lib/libunwind.a) which
# needs __xlcxx_personality_v0 from libc++abi.a — absent on AIX 7.2 TL2-TL4.
# The GCC-derived version only depends on libc.a, making it fully portable.
Comment thread
pgimalac marked this conversation as resolved.
if lib_done libunwind "$LIBUNWIND_VERSION"; then
log "libunwind ${LIBUNWIND_VERSION} already staged — skipping"
else
log "Staging libunwind ${LIBUNWIND_VERSION} (from libgcc_s.a)"
GCC_LIBGCC_S=/opt/freeware/lib/libgcc_s.a
if [ ! -f "$GCC_LIBGCC_S" ]; then
log "ERROR: $GCC_LIBGCC_S not found — install GCC from the AIX Toolbox"
exit 1
fi
_tmpdir="$BUILD_DIR/build/libunwind-tmp"
rm -rf "$_tmpdir" && mkdir -p "$_tmpdir"
(cd "$_tmpdir" && ar -X64 -x "$GCC_LIBGCC_S" shr.o)
cp "$_tmpdir/shr.o" "$_tmpdir/libunwind.so.1"
ar -X64 -rcs "$EMBEDDED_DESTDIR/lib/libunwind.a" "$_tmpdir/libunwind.so.1"
rm -rf "$_tmpdir"
lib_mark libunwind "$LIBUNWIND_VERSION"
log "libunwind ${LIBUNWIND_VERSION} staged"
fi

# ─── Ensure standard directories exist ────────────────────────────────────────

log "Ensuring standard embedded directories exist"
Expand Down
Loading