Skip to content

macos: relocate libpq to @rpath for Homebrew layout portability - #49

Merged
adsharma merged 1 commit into
mainfrom
fix/macos-libpq-rpath-relocation
Aug 9, 2026
Merged

macos: relocate libpq to @rpath for Homebrew layout portability#49
adsharma merged 1 commit into
mainfrom
fix/macos-libpq-rpath-relocation

Conversation

@adsharma

@adsharma adsharma commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #48

Problem

The macOS arm64 libpg_client.lbug_extension 0.19.0 records the absolute install name

/opt/homebrew/opt/libpq/lib/libpq.5.dylib

which is provided only by the keg-only standalone libpq Homebrew formula. Machines that install libpq via brew install postgresql@18 have it at /opt/homebrew/lib/postgresql@18/libpq.5.dylib instead, so dyld cannot resolve the dependency and LOAD EXTENSION fails.

Fix

Adds two scripts mirroring the existing OpenSSL relocation pattern in the ladybug repo (scripts/relocate-macos-openssl.sh / verify-macos-openssl-rpaths.sh):

  • scripts/relocate-macos-libpq.sh — rewrites the libpq install name to @rpath/libpq.5.dylib and adds the common Homebrew locations as LC_RPATH fallbacks (standalone libpq and bundled postgresql@18, on both /opt/homebrew and /usr/local), then ad-hoc re-signs (install_name_tool invalidates the signature).
  • scripts/verify-macos-libpq-rpaths.sh — asserts the @rpath dependency is present, no package-manager-specific absolute libpq path remains, and all rpaths exist.

dyld silently skips LC_RPATH entries pointing at non-existent directories, so the released binary loads in either Homebrew layout. Companion wiring lives in the ladybug repo (build-extensions.yml; PR will be linked) where the official macOS artifacts are built.

Validation

Tested locally with a dylib linked against the standalone libpq formula:

  • relocate rewrites to @rpath/libpq.5.dylib + adds all 6 rpaths; verify passes; relocation is idempotent
  • verify rejects the unpatched binary
  • simulated a postgresql@18-only machine (sole rpath = that layout): the patched binary loads successfully

The pg_client extension is linked in CI against the keg-only standalone
'libpq' Homebrew formula, which records an absolute install name of
/opt/homebrew/opt/libpq/lib/libpq.5.dylib in the released binary. End
users who install libpq via 'brew install postgresql@18' only (the
common layout on Apple Silicon) have libpq at a different path, so
dyld cannot resolve the dependency and the extension fails to load.

Add scripts/relocate-macos-libpq.sh (mirroring the existing
scripts/relocate-macos-openssl.sh pattern) to rewrite the install name
to @rpath/libpq.5.dylib and add the common Homebrew locations as
LC_RPATH fallbacks, plus scripts/verify-macos-libpq-rpaths.sh to
assert the relocation in CI. Fixes #48.
@adsharma
adsharma merged commit 8db5e14 into main Aug 9, 2026
2 checks passed
@adsharma
adsharma deleted the fix/macos-libpq-rpath-relocation branch August 9, 2026 04:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS arm64 pg_client 0.19.0 expects libpq from the standalone Homebrew formula

1 participant