From 9ff1eab8117411b437e552c0381d7c9251769927 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Sun, 6 Sep 2026 23:02:15 -0400 Subject: [PATCH 1/4] ci: run the orphaned test/db regression runners test/db/ holds four runners that each guard a specific fixed bug, but NONE was invoked by any CI job or build target, so a regression in the code they cover would have gone unnoticed: run_hash_unsorted_cmp the #139 hash comparator fix (PR #144) run_recd_compact compact-path recovery run_recd_handlers recovery handler dispatch run_upgrade the on-disk upgrade path Found while verifying that the #139 fix on master really contains BOTH required changes (it does: LEN_HKEY for the stored item's length, and capturing the comparator's result). The test proving that is thorough -- it covers the false-negative, the false-positive-on-prefix that appears if only the reported half is fixed, and an over-long key -- but nothing ran it. Added to the 'default' matrix config of the existing build job, which already builds build_unix with the shared library. All four follow the same BUILD=${BUILD:-.} convention and run from the build directory. Verified locally with the exact CI command sequence: 4/4 PASS. actionlint reports no findings for the new step. --- .github/workflows/ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe1f57b83..09518b74b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,6 +87,22 @@ jobs: make ex_access 2>/dev/null || true ls -l libdb-*.a 2>/dev/null || ls -l .libs/libdb-*.* 2>/dev/null || true + # The test/db/ regression runners guard specific fixed bugs (the #139 hash + # comparator, recd compact/handler recovery, and the on-disk upgrade path). + # They were previously orphaned: no CI job and no make target invoked them, + # so a regression would have gone unnoticed. They all follow the same + # BUILD=${BUILD:-.} convention and expect to run from the build directory. + - name: Regression runners (test/db) + if: matrix.config == 'default' + working-directory: build_unix + run: | + set -e + for r in run_hash_unsorted_cmp run_recd_compact run_recd_handlers run_upgrade; do + echo "::group::$r" + bash "../test/db/$r.sh" + echo "::endgroup::" + done + # ---------------------------------------------------------------------------- # 32-bit build on Linux (pointer-size / portability coverage). # ---------------------------------------------------------------------------- From 9cb11652945438bd1e2b2373d68fbdfbefccdba1 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Sun, 6 Sep 2026 23:10:50 -0400 Subject: [PATCH 2/4] test(db): make the shared-library probe portable to macOS Wiring these runners into CI (previous commit) exposed a real portability gap: the library probe looked only for .libs/libdb-*.so, so all four macOS jobs failed with 'libdb .so not found'. macOS builds libdb-5.3.dylib. The probe now tries the exact .so and .dylib names first, then the globs for each, and its failure message names both suffixes. The -Wl,-rpath linking already works on both platforms, so nothing else needed changing. Verified: 4/4 PASS on Linux (unchanged), and the new probe resolves a .dylib-only build directory. --- test/db/run_hash_unsorted_cmp.sh | 12 +++++++----- test/db/run_recd_compact.sh | 12 +++++++----- test/db/run_recd_handlers.sh | 12 +++++++----- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/test/db/run_hash_unsorted_cmp.sh b/test/db/run_hash_unsorted_cmp.sh index 2103b988a..78176570e 100644 --- a/test/db/run_hash_unsorted_cmp.sh +++ b/test/db/run_hash_unsorted_cmp.sh @@ -32,11 +32,13 @@ SRC=${SRC:-../test/db/hash_unsorted_cmp.c} HOME_DIR=${HOME_DIR:-HASH_UNSORTED_TESTDIR} TIMEOUT=${TIMEOUT:-180} -LIB="$BUILD/.libs/libdb-5.3.so" -if [ ! -f "$LIB" ]; then - LIB=$(ls "$BUILD"/.libs/libdb-*.so 2>/dev/null | head -1) -fi -[ -n "$LIB" ] || { echo "FAIL: libdb .so not found in $BUILD/.libs"; exit 1; } +# Shared-library suffix is platform-dependent: .so on Linux, .dylib on macOS. +LIB="" +for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ + "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do + if [ -f "$cand" ]; then LIB="$cand"; break; fi +done +[ -n "$LIB" ] || { echo "FAIL: libdb shared library (.so/.dylib) not found in $BUILD/.libs"; exit 1; } echo "Compiling hash_unsorted_cmp against $LIB" gcc -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ diff --git a/test/db/run_recd_compact.sh b/test/db/run_recd_compact.sh index 8a930ff7e..64d2e8fb4 100644 --- a/test/db/run_recd_compact.sh +++ b/test/db/run_recd_compact.sh @@ -23,11 +23,13 @@ SRC=${SRC:-../test/db/recd_compact.c} HOME_DIR=${HOME_DIR:-RECD_COMPACT_TESTDIR} TIMEOUT=${TIMEOUT:-180} -LIB="$BUILD/.libs/libdb-5.3.so" -if [ ! -f "$LIB" ]; then - LIB=$(ls "$BUILD"/.libs/libdb-*.so 2>/dev/null | head -1) -fi -[ -n "$LIB" ] || { echo "FAIL: libdb .so not found in $BUILD/.libs"; exit 1; } +# Shared-library suffix is platform-dependent: .so on Linux, .dylib on macOS. +LIB="" +for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ + "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do + if [ -f "$cand" ]; then LIB="$cand"; break; fi +done +[ -n "$LIB" ] || { echo "FAIL: libdb shared library (.so/.dylib) not found in $BUILD/.libs"; exit 1; } echo "Compiling recd_compact against $LIB" gcc -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ diff --git a/test/db/run_recd_handlers.sh b/test/db/run_recd_handlers.sh index e305ab8e6..304da594c 100644 --- a/test/db/run_recd_handlers.sh +++ b/test/db/run_recd_handlers.sh @@ -26,11 +26,13 @@ SRC=${SRC:-../test/db/recd_handlers.c} HOME_DIR=${HOME_DIR:-RECD_HANDLERS_TESTDIR} TIMEOUT=${TIMEOUT:-300} -LIB="$BUILD/.libs/libdb-5.3.so" -if [ ! -f "$LIB" ]; then - LIB=$(ls "$BUILD"/.libs/libdb-*.so 2>/dev/null | head -1) -fi -[ -n "$LIB" ] || { echo "FAIL: libdb .so not found in $BUILD/.libs"; exit 1; } +# Shared-library suffix is platform-dependent: .so on Linux, .dylib on macOS. +LIB="" +for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ + "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do + if [ -f "$cand" ]; then LIB="$cand"; break; fi +done +[ -n "$LIB" ] || { echo "FAIL: libdb shared library (.so/.dylib) not found in $BUILD/.libs"; exit 1; } echo "Compiling recd_handlers against $LIB" gcc -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ From f95017ef91abc7acdc85661c4292ca176790cc92 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Sun, 6 Sep 2026 23:18:03 -0400 Subject: [PATCH 3/4] test(db): resolve timeout portably (macOS has no GNU timeout) Second macOS gap exposed by wiring these runners into CI. The .dylib probe fixed the library lookup, and the runners then compiled and linked fine on macOS, but all four still failed with rc=127: 'timeout: command not found'. GNU coreutils' timeout is not on stock macOS, where it is gtimeout if coreutils is installed. Added a run_with_timeout helper to each runner: prefer timeout, then gtimeout, and if neither exists run the command WITHOUT a timeout rather than failing -- losing the timeout is much better than reporting a false failure. Both branches were exercised explicitly, including that the no-timeout path drops the leading seconds argument. 4/4 still PASS on Linux. --- test/db/run_hash_unsorted_cmp.sh | 20 +++++++++++++++++++- test/db/run_recd_compact.sh | 20 +++++++++++++++++++- test/db/run_recd_handlers.sh | 20 +++++++++++++++++++- test/db/run_upgrade.sh | 26 ++++++++++++++++++++++---- 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/test/db/run_hash_unsorted_cmp.sh b/test/db/run_hash_unsorted_cmp.sh index 78176570e..c25465d70 100644 --- a/test/db/run_hash_unsorted_cmp.sh +++ b/test/db/run_hash_unsorted_cmp.sh @@ -48,8 +48,26 @@ gcc -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ rm -f "$HOME_DIR"/*.db 2>/dev/null || true mkdir -p "$HOME_DIR" +# `timeout` is GNU coreutils: present on Linux, absent on stock macOS (where it +# is `gtimeout` if coreutils is installed). Resolve it once; if neither exists, +# run without a timeout rather than failing with rc=127. +if command -v timeout >/dev/null 2>&1; then + TIMEOUT_CMD="timeout" +elif command -v gtimeout >/dev/null 2>&1; then + TIMEOUT_CMD="gtimeout" +else + TIMEOUT_CMD="" +fi +run_with_timeout() { + if [ -n "$TIMEOUT_CMD" ]; then + "$TIMEOUT_CMD" "$@" + else + shift # drop the seconds argument + "$@" + fi +} echo "Running hash_unsorted_cmp (timeout ${TIMEOUT}s)" -if timeout "$TIMEOUT" "$BUILD/hash_unsorted_cmp"; then +if run_with_timeout "$TIMEOUT" "$BUILD/hash_unsorted_cmp"; then echo "run_hash_unsorted_cmp.sh: PASS" exit 0 else diff --git a/test/db/run_recd_compact.sh b/test/db/run_recd_compact.sh index 64d2e8fb4..f8df0cacb 100644 --- a/test/db/run_recd_compact.sh +++ b/test/db/run_recd_compact.sh @@ -40,8 +40,26 @@ rm -f "$HOME_DIR"/__db.* "$HOME_DIR"/log.* "$HOME_DIR"/*.db \ "$HOME_DIR"/DB_CONFIG 2>/dev/null || true mkdir -p "$HOME_DIR" +# `timeout` is GNU coreutils: present on Linux, absent on stock macOS (where it +# is `gtimeout` if coreutils is installed). Resolve it once; if neither exists, +# run without a timeout rather than failing with rc=127. +if command -v timeout >/dev/null 2>&1; then + TIMEOUT_CMD="timeout" +elif command -v gtimeout >/dev/null 2>&1; then + TIMEOUT_CMD="gtimeout" +else + TIMEOUT_CMD="" +fi +run_with_timeout() { + if [ -n "$TIMEOUT_CMD" ]; then + "$TIMEOUT_CMD" "$@" + else + shift # drop the seconds argument + "$@" + fi +} echo "Running recd_compact (timeout ${TIMEOUT}s)" -if timeout "$TIMEOUT" "$BUILD/recd_compact"; then +if run_with_timeout "$TIMEOUT" "$BUILD/recd_compact"; then echo "run_recd_compact.sh: PASS" exit 0 else diff --git a/test/db/run_recd_handlers.sh b/test/db/run_recd_handlers.sh index 304da594c..37d954f99 100644 --- a/test/db/run_recd_handlers.sh +++ b/test/db/run_recd_handlers.sh @@ -43,8 +43,26 @@ rm -f "$HOME_DIR"/__db.* "$HOME_DIR"/log.* "$HOME_DIR"/*.db \ "$HOME_DIR"/DB_CONFIG 2>/dev/null || true mkdir -p "$HOME_DIR" +# `timeout` is GNU coreutils: present on Linux, absent on stock macOS (where it +# is `gtimeout` if coreutils is installed). Resolve it once; if neither exists, +# run without a timeout rather than failing with rc=127. +if command -v timeout >/dev/null 2>&1; then + TIMEOUT_CMD="timeout" +elif command -v gtimeout >/dev/null 2>&1; then + TIMEOUT_CMD="gtimeout" +else + TIMEOUT_CMD="" +fi +run_with_timeout() { + if [ -n "$TIMEOUT_CMD" ]; then + "$TIMEOUT_CMD" "$@" + else + shift # drop the seconds argument + "$@" + fi +} echo "Running recd_handlers (timeout ${TIMEOUT}s)" -if timeout "$TIMEOUT" "$BUILD/recd_handlers"; then +if run_with_timeout "$TIMEOUT" "$BUILD/recd_handlers"; then echo "run_recd_handlers.sh: PASS" rm -f "$HOME_DIR"/__db.* "$HOME_DIR"/log.* "$HOME_DIR"/*.db \ "$HOME_DIR"/DB_CONFIG 2>/dev/null || true diff --git a/test/db/run_upgrade.sh b/test/db/run_upgrade.sh index ec82b04d6..8b9616a2e 100644 --- a/test/db/run_upgrade.sh +++ b/test/db/run_upgrade.sh @@ -85,13 +85,31 @@ ABS_VERIFY=$(cd "$BUILD" && pwd)/db_verify rm -f "$WORK"/__db.* "$WORK"/log.* "$WORK"/*.db 2>/dev/null || true mkdir -p "$WORK" +# `timeout` is GNU coreutils: present on Linux, absent on stock macOS (where it +# is `gtimeout` if coreutils is installed). Resolve it once; if neither exists, +# run without a timeout rather than failing with rc=127. +if command -v timeout >/dev/null 2>&1; then + TIMEOUT_CMD="timeout" +elif command -v gtimeout >/dev/null 2>&1; then + TIMEOUT_CMD="gtimeout" +else + TIMEOUT_CMD="" +fi +run_with_timeout() { + if [ -n "$TIMEOUT_CMD" ]; then + "$TIMEOUT_CMD" "$@" + else + shift # drop the seconds argument + "$@" + fi +} # upgrade_verify FILE [extra db_upgrade flags...] -- run db_upgrade then # db_verify (both under a timeout). Used for paths that must verify clean. upgrade_verify() { f=$1; shift echo "db_upgrade $* + verify: $f" - ( cd "$WORK" && timeout "$TIMEOUT" "$ABS_UPGRADE" -h . "$@" "$f" ) - ( cd "$WORK" && timeout "$TIMEOUT" "$ABS_VERIFY" "$f" >/dev/null ) + ( cd "$WORK" && run_with_timeout "$TIMEOUT" "$ABS_UPGRADE" -h . "$@" "$f" ) + ( cd "$WORK" && run_with_timeout "$TIMEOUT" "$ABS_VERIFY" "$f" >/dev/null ) echo " CLEAN $f" } @@ -102,7 +120,7 @@ upgrade_verify() { upgrade_only() { f=$1; exp=$2 echo "db_upgrade (no verify): $f" - ( cd "$WORK" && timeout "$TIMEOUT" "$ABS_UPGRADE" -h . "$f" ) + ( cd "$WORK" && run_with_timeout "$TIMEOUT" "$ABS_UPGRADE" -h . "$f" ) got=$( cd "$WORK" && "$PYTHON" -c "import struct,sys;print(struct.unpack_from('$got; verify skipped: __db_set_lastpgno off-by-one)" @@ -173,7 +191,7 @@ done # btree-with-dups: also drive the -s (DB_DUPSORT) flag path + salvage. upgrade_verify cur_btdup.db -s echo "salvage-verify cur_btdup.db" -( cd "$WORK" && timeout "$TIMEOUT" "$ABS_VERIFY" -o cur_btdup.db >/dev/null ) +( cd "$WORK" && run_with_timeout "$TIMEOUT" "$ABS_VERIFY" -o cur_btdup.db >/dev/null ) echo " CLEAN cur_btdup.db (salvage)" # 2b. rewrite metadata pages into old on-disk layouts (see header). From 6ac667540083e63ad0395592880b671a08e68bcd Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Sun, 6 Sep 2026 23:25:54 -0400 Subject: [PATCH 4/4] test(db): link the regression runners statically, honor $CC Third and root-cause macOS gap. After the .dylib probe and the timeout helper, the binaries compiled and linked on macOS but aborted at startup: dyld: Library not loaded: /usr/local/BerkeleyDB.5.3/lib/libdb-5.3.dylib The .dylib carries a baked-in install name, and on macOS the install name takes precedence over -Wl,-rpath, so the binary looked in an uninstalled location. The runners never actually needed dynamic linking -- the other CI-wired suites (test/fuzz) link libdb.a -- so they now PREFER the static library and only fall back to shared (adding -rpath in that case). This removes the dynamic loader from the picture instead of fighting it. Also replaced the hardcoded 'gcc' with "${CC:-cc}": the macOS jobs run clang, and hardcoding gcc would have been the next failure in this same sequence. Verified: 4/4 PASS locally and 'ldd hash_unsorted_cmp | grep -c libdb' = 0, confirming the static link. --- test/db/run_hash_unsorted_cmp.sh | 28 ++++++++++++++++++++++------ test/db/run_recd_compact.sh | 28 ++++++++++++++++++++++------ test/db/run_recd_handlers.sh | 28 ++++++++++++++++++++++------ 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/test/db/run_hash_unsorted_cmp.sh b/test/db/run_hash_unsorted_cmp.sh index c25465d70..3ebbf8403 100644 --- a/test/db/run_hash_unsorted_cmp.sh +++ b/test/db/run_hash_unsorted_cmp.sh @@ -32,17 +32,33 @@ SRC=${SRC:-../test/db/hash_unsorted_cmp.c} HOME_DIR=${HOME_DIR:-HASH_UNSORTED_TESTDIR} TIMEOUT=${TIMEOUT:-180} -# Shared-library suffix is platform-dependent: .so on Linux, .dylib on macOS. +# Prefer the STATIC library: on macOS the .dylib carries a baked-in install name +# (/usr/local/BerkeleyDB.5.3/lib/...) which takes precedence over -rpath, so a +# shared link runs against an uninstalled path and dyld aborts. Static linking +# avoids the dynamic loader entirely, which is what the other CI-wired suites +# (e.g. test/fuzz) already do. Fall back to the shared library if no static one +# was built. LIB="" -for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ - "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do +LIBRPATH="" +for cand in "$BUILD"/libdb.a "$BUILD"/.libs/libdb-5.3.a "$BUILD"/.libs/libdb-*.a; do if [ -f "$cand" ]; then LIB="$cand"; break; fi done -[ -n "$LIB" ] || { echo "FAIL: libdb shared library (.so/.dylib) not found in $BUILD/.libs"; exit 1; } +if [ -z "$LIB" ]; then + for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ + "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do + if [ -f "$cand" ]; then LIB="$cand"; break; fi + done + [ -n "$LIB" ] && LIBRPATH="-Wl,-rpath,$(cd "$BUILD/.libs" && pwd)" +fi +[ -n "$LIB" ] || { echo "FAIL: no libdb library (static or shared) found under $BUILD"; exit 1; } + +# A static libdb needs its transitive deps named explicitly. +EXTRALIBS="" +for l in $(pkg-config --libs liburing 2>/dev/null); do EXTRALIBS="$EXTRALIBS $l"; done echo "Compiling hash_unsorted_cmp against $LIB" -gcc -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ - -lpthread -Wl,-rpath,"$(cd "$BUILD/.libs" && pwd)" \ +"${CC:-cc}" -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ + -lpthread $LIBRPATH $EXTRALIBS \ -o "$BUILD/hash_unsorted_cmp" rm -f "$HOME_DIR"/*.db 2>/dev/null || true diff --git a/test/db/run_recd_compact.sh b/test/db/run_recd_compact.sh index f8df0cacb..26ed92888 100644 --- a/test/db/run_recd_compact.sh +++ b/test/db/run_recd_compact.sh @@ -23,17 +23,33 @@ SRC=${SRC:-../test/db/recd_compact.c} HOME_DIR=${HOME_DIR:-RECD_COMPACT_TESTDIR} TIMEOUT=${TIMEOUT:-180} -# Shared-library suffix is platform-dependent: .so on Linux, .dylib on macOS. +# Prefer the STATIC library: on macOS the .dylib carries a baked-in install name +# (/usr/local/BerkeleyDB.5.3/lib/...) which takes precedence over -rpath, so a +# shared link runs against an uninstalled path and dyld aborts. Static linking +# avoids the dynamic loader entirely, which is what the other CI-wired suites +# (e.g. test/fuzz) already do. Fall back to the shared library if no static one +# was built. LIB="" -for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ - "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do +LIBRPATH="" +for cand in "$BUILD"/libdb.a "$BUILD"/.libs/libdb-5.3.a "$BUILD"/.libs/libdb-*.a; do if [ -f "$cand" ]; then LIB="$cand"; break; fi done -[ -n "$LIB" ] || { echo "FAIL: libdb shared library (.so/.dylib) not found in $BUILD/.libs"; exit 1; } +if [ -z "$LIB" ]; then + for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ + "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do + if [ -f "$cand" ]; then LIB="$cand"; break; fi + done + [ -n "$LIB" ] && LIBRPATH="-Wl,-rpath,$(cd "$BUILD/.libs" && pwd)" +fi +[ -n "$LIB" ] || { echo "FAIL: no libdb library (static or shared) found under $BUILD"; exit 1; } + +# A static libdb needs its transitive deps named explicitly. +EXTRALIBS="" +for l in $(pkg-config --libs liburing 2>/dev/null); do EXTRALIBS="$EXTRALIBS $l"; done echo "Compiling recd_compact against $LIB" -gcc -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ - -lpthread -Wl,-rpath,"$(cd "$BUILD/.libs" && pwd)" \ +"${CC:-cc}" -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ + -lpthread $LIBRPATH $EXTRALIBS \ -o "$BUILD/recd_compact" rm -f "$HOME_DIR"/__db.* "$HOME_DIR"/log.* "$HOME_DIR"/*.db \ diff --git a/test/db/run_recd_handlers.sh b/test/db/run_recd_handlers.sh index 37d954f99..7dfa5d26e 100644 --- a/test/db/run_recd_handlers.sh +++ b/test/db/run_recd_handlers.sh @@ -26,17 +26,33 @@ SRC=${SRC:-../test/db/recd_handlers.c} HOME_DIR=${HOME_DIR:-RECD_HANDLERS_TESTDIR} TIMEOUT=${TIMEOUT:-300} -# Shared-library suffix is platform-dependent: .so on Linux, .dylib on macOS. +# Prefer the STATIC library: on macOS the .dylib carries a baked-in install name +# (/usr/local/BerkeleyDB.5.3/lib/...) which takes precedence over -rpath, so a +# shared link runs against an uninstalled path and dyld aborts. Static linking +# avoids the dynamic loader entirely, which is what the other CI-wired suites +# (e.g. test/fuzz) already do. Fall back to the shared library if no static one +# was built. LIB="" -for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ - "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do +LIBRPATH="" +for cand in "$BUILD"/libdb.a "$BUILD"/.libs/libdb-5.3.a "$BUILD"/.libs/libdb-*.a; do if [ -f "$cand" ]; then LIB="$cand"; break; fi done -[ -n "$LIB" ] || { echo "FAIL: libdb shared library (.so/.dylib) not found in $BUILD/.libs"; exit 1; } +if [ -z "$LIB" ]; then + for cand in "$BUILD"/.libs/libdb-5.3.so "$BUILD"/.libs/libdb-5.3.dylib \ + "$BUILD"/.libs/libdb-*.so "$BUILD"/.libs/libdb-*.dylib; do + if [ -f "$cand" ]; then LIB="$cand"; break; fi + done + [ -n "$LIB" ] && LIBRPATH="-Wl,-rpath,$(cd "$BUILD/.libs" && pwd)" +fi +[ -n "$LIB" ] || { echo "FAIL: no libdb library (static or shared) found under $BUILD"; exit 1; } + +# A static libdb needs its transitive deps named explicitly. +EXTRALIBS="" +for l in $(pkg-config --libs liburing 2>/dev/null); do EXTRALIBS="$EXTRALIBS $l"; done echo "Compiling recd_handlers against $LIB" -gcc -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ - -lpthread -Wl,-rpath,"$(cd "$BUILD/.libs" && pwd)" \ +"${CC:-cc}" -g -O1 ${CFLAGS:-} -I"$BUILD" "$SRC" "$LIB" \ + -lpthread $LIBRPATH $EXTRALIBS \ -o "$BUILD/recd_handlers" rm -f "$HOME_DIR"/__db.* "$HOME_DIR"/log.* "$HOME_DIR"/*.db \