You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
macOS source installs are broken: make install looks for pg_durable.so, cargo-pgrx produces pg_durable.dylib
Summary
On macOS, make package && make install fails. The packaging step succeeds and
writes pg_durable.dylib; the install step looks for pg_durable.so, does not
find it, and exits with a message telling you to run make package first —
which you just did.
This is currently invisible because every CI job in the repository runs on
Linux, and it becomes user-visible the moment we publish to PGXN (#344), where pgxn install pg_durable runs make and make install on the user's machine.
macOS users have no other install path: the .deb packages are Debian-only and
the GHCR image is linux/amd64.
Why the suffix differs
PostgreSQL 16 changed the module suffix on macOS from .so to .dylib:
meson.build — dlsuffix = '.dylib' in the host_system == 'darwin' branch
cargo-pgrx follows suit. From cargo-pgrx/src/command/install.rs:189-192 at the
pinned version =0.16.1:
// Since Postgres 16, the shared library extension on macOS is `dylib`, not `so`.let so_suffix = ifcfg!(target_os = "macos") && pg_config.major_version().unwrap() < 16{".so"}else{
std::env::consts::DLL_SUFFIX};
pg_durable supports only PostgreSQL 17 and 18 (Makefile:148), so on macOS the
packaged library is alwayspg_durable.dylib. There is no supported
configuration where macOS produces .so.
Renaming to .so is not a valid workaround
pg_durable.control:6 declares:
module_pathname = 'pg_durable'
That is a bare name with no suffix, so PostgreSQL appends its own compiled-in DLSUFFIX at load time — see expand_dynamic_library_name() in src/backend/utils/fmgr/dfmgr.c.
On macOS with PG 16+ that resolves to pg_durable.dylib. A file installed as pg_durable.so would not be found by CREATE EXTENSION. The installed file
must be named .dylib on macOS.
Work items
1. Derive the suffix in the Makefile
Add a variable and use it at all four hardcoded sites:
Makefile:194 matters independently: the audit at Makefile:193-201 fails the
build when the packaged tree contains a file the install recipe does not handle,
so a .dylib would trip it even after Makefile:179 is fixed.
Two implementation notes:
pg_config has no --dlsuffix option, so uname -s is the practical source.
This matches cargo-pgrx, which keys off cfg!(target_os) — the host, not
anything reported by pg_config.
Make PG_DLSUFFIX overridable (?= or a conditional assignment) so tests can
force the Darwin naming on a Linux runner.
Consider having uninstall remove both suffixes. It already tolerates a
partial install; a machine installed before this fix would otherwise keep an
orphaned file.
2. Fix scripts/test-make-install.sh
The contract test is Linux-only in two separate ways.
GNU stat. Lines 133-135 use stat -c %a, which BSD/macOS stat does not
accept — it needs stat -f %Lp. Add a small portable helper, e.g.:
file_mode() {
stat -c %a "$1"2>/dev/null || stat -f %Lp "$1"
}
Hardcoded .so. Line 76 has the fake cargo write the packaged library as pg_durable.so, and lines 129 and 155 assert .so paths. These need to follow
the same suffix rule as the Makefile.
Coverage. Since we cannot count on a macOS runner for every PR, add a case
that runs the install/uninstall contract with PG_DLSUFFIX=.dylib forced, so
Linux CI actually exercises the macOS naming.
The script is #!/usr/bin/env bash and uses ${!var} indirect expansion at line
100. That is supported by the bash 3.2 that ships with macOS, so no change is
needed there — but avoid mapfile/readarray if you extend it.
3. Add a macOS CI job
All 16 runs-on: entries across the seven workflow files are ubuntu-latest.
Nothing has ever compiled this extension on macOS, so the packaging fix is
unverified until a macos-latest job in ci.yml does at least:
cargo pgrx init for PG 17 (and 18 if it installs cleanly)
make package
make install DESTDIR=<staging> and assert pg_durable.dylib lands in $(pg_config --pkglibdir)
make uninstall and assert the tree is clean
scripts/test-make-install.sh
Ideally also make installcheck, though that is a larger lift.
4. Developer helper scripts (lower priority)
Not on the PGXN install path, but wrong on a Mac dev box:
scripts/package-deb.sh:36 is Debian-specific and should keep .so.
What is already in place
.cargo/config.toml already sets -C link-arg=-undefined -C link-arg=dynamic_lookup
for both aarch64-apple-darwin and x86_64-apple-darwin, which is the link
configuration pgrx requires on Darwin. The link step looks prepared; it has
simply never been run.
reqwest is pinned to native-tls, which resolves to Security.framework on
Apple targets rather than OpenSSL, so no OpenSSL build dependency is expected.
Unverified.
Unknowns to settle while implementing
These cannot be answered without a Mac, and they are the reason this needs
someone with a laptop rather than a blind patch:
Does cargo pgrx package complete at all on macOS, on both aarch64 and x86_64? Nothing in CI has ever tried.
Does make installcheck (pg_regress via PGXS) work on macOS?
Homebrew PostgreSQL vs a pgrx-managed PostgreSQL — which pg_config should
the macOS install instructions point at?
If (1) turns out to be broken for reasons beyond the suffix, that is worth
splitting into its own issue; this one should stay scoped to packaging and
installation.
Acceptance criteria
On macOS with PostgreSQL 17 or 18, make package && make install installs pg_durable.dylib into pg_config --pkglibdir along with the control and SQL
files, and CREATE EXTENSION pg_durable loads it.
make uninstall removes exactly what install placed and stays idempotent.
Linux behaviour is unchanged: still pg_durable.so.
scripts/test-make-install.sh passes on both platforms and exercises both
suffixes on Linux CI.
A macos-latest job runs the above and is green.
README / USER_GUIDE state which platforms are supported for source installs.
Out of scope
Windows.
Publishing macOS binaries. PGXN carries the source distribution; this is about
making a source install work, not about shipping artifacts.
Related
Add PGXN distribution metadata #344 — PGXN distribution metadata. Makes source install the advertised path,
so this should land before the first PGXN upload.
TODO.md:21 — "figure out process to build/release the extension for linux,
windows and macos, with instructions for installation".
Evidence gathered against microsoft/pg_durable at commit 146b41b
(waldemort/pgxn-distribution), pgrx v0.16.1, and PostgreSQL branches REL_15_STABLE through REL_18_STABLE.
macOS source installs are broken:
make installlooks forpg_durable.so, cargo-pgrx producespg_durable.dylibSummary
On macOS,
make package && make installfails. The packaging step succeeds andwrites
pg_durable.dylib; the install step looks forpg_durable.so, does notfind it, and exits with a message telling you to run
make packagefirst —which you just did.
This is currently invisible because every CI job in the repository runs on
Linux, and it becomes user-visible the moment we publish to PGXN (#344), where
pgxn install pg_durablerunsmakeandmake installon the user's machine.macOS users have no other install path: the
.debpackages are Debian-only andthe GHCR image is
linux/amd64.Why the suffix differs
PostgreSQL 16 changed the module suffix on macOS from
.soto.dylib:src/template/darwin:30—DLSUFFIX=".dylib"(absent inREL_15_STABLE)meson.build—dlsuffix = '.dylib'in thehost_system == 'darwin'branchcargo-pgrx follows suit. From
cargo-pgrx/src/command/install.rs:189-192at thepinned version
=0.16.1:pg_durablesupports only PostgreSQL 17 and 18 (Makefile:148), so on macOS thepackaged library is always
pg_durable.dylib. There is no supportedconfiguration where macOS produces
.so.Renaming to
.sois not a valid workaroundpg_durable.control:6declares:That is a bare name with no suffix, so PostgreSQL appends its own compiled-in
DLSUFFIXat load time — seeexpand_dynamic_library_name()insrc/backend/utils/fmgr/dfmgr.c.On macOS with PG 16+ that resolves to
pg_durable.dylib. A file installed aspg_durable.sowould not be found byCREATE EXTENSION. The installed filemust be named
.dylibon macOS.Work items
1. Derive the suffix in the Makefile
Add a variable and use it at all four hardcoded sites:
Makefile:179PACKAGE_LIBRARY = $(PGRX_PACKAGE_DIR)$(PG_PKGLIBDIR)/pg_durable.soinstallMakefile:194! -path "./$(PG_PKGLIBDIR_REL)/pg_durable.so"Makefile:203install -m 0755 "$$package_library" "$(DESTDIR)$(PG_PKGLIBDIR)/pg_durable.so"Makefile:212library="$(DESTDIR)$(PG_PKGLIBDIR)/pg_durable.so"uninstalltargetMakefile:194matters independently: the audit atMakefile:193-201fails thebuild when the packaged tree contains a file the install recipe does not handle,
so a
.dylibwould trip it even afterMakefile:179is fixed.Two implementation notes:
pg_confighas no--dlsuffixoption, souname -sis the practical source.This matches cargo-pgrx, which keys off
cfg!(target_os)— the host, notanything reported by
pg_config.PG_DLSUFFIXoverridable (?=or a conditional assignment) so tests canforce the Darwin naming on a Linux runner.
uninstallremove both suffixes. It already tolerates apartial install; a machine installed before this fix would otherwise keep an
orphaned file.
2. Fix
scripts/test-make-install.shThe contract test is Linux-only in two separate ways.
GNU
stat. Lines 133-135 usestat -c %a, which BSD/macOSstatdoes notaccept — it needs
stat -f %Lp. Add a small portable helper, e.g.:Hardcoded
.so. Line 76 has the fakecargowrite the packaged library aspg_durable.so, and lines 129 and 155 assert.sopaths. These need to followthe same suffix rule as the Makefile.
Coverage. Since we cannot count on a macOS runner for every PR, add a case
that runs the install/uninstall contract with
PG_DLSUFFIX=.dylibforced, soLinux CI actually exercises the macOS naming.
The script is
#!/usr/bin/env bashand uses${!var}indirect expansion at line100. That is supported by the bash 3.2 that ships with macOS, so no change is
needed there — but avoid
mapfile/readarrayif you extend it.3. Add a macOS CI job
All 16
runs-on:entries across the seven workflow files areubuntu-latest.Nothing has ever compiled this extension on macOS, so the packaging fix is
unverified until a
macos-latestjob inci.ymldoes at least:cargo pgrx initfor PG 17 (and 18 if it installs cleanly)make packagemake install DESTDIR=<staging>and assertpg_durable.dyliblands in$(pg_config --pkglibdir)make uninstalland assert the tree is cleanscripts/test-make-install.shIdeally also
make installcheck, though that is a larger lift.4. Developer helper scripts (lower priority)
Not on the PGXN install path, but wrong on a Mac dev box:
scripts/pg-start.sh:68—[ -f "$PKGLIBDIR/pg_durable.so" ]presence checkscripts/test-coverage.sh:160-162— globspgrx-install/lib/postgresql/pg_durable.soscripts/package-deb.sh:36is Debian-specific and should keep.so.What is already in place
.cargo/config.tomlalready sets-C link-arg=-undefined -C link-arg=dynamic_lookupfor both
aarch64-apple-darwinandx86_64-apple-darwin, which is the linkconfiguration pgrx requires on Darwin. The link step looks prepared; it has
simply never been run.
reqwestis pinned tonative-tls, which resolves to Security.framework onApple targets rather than OpenSSL, so no OpenSSL build dependency is expected.
Unverified.
Unknowns to settle while implementing
These cannot be answered without a Mac, and they are the reason this needs
someone with a laptop rather than a blind patch:
cargo pgrx packagecomplete at all on macOS, on bothaarch64andx86_64? Nothing in CI has ever tried.make installcheck(pg_regress via PGXS) work on macOS?pg_configshouldthe macOS install instructions point at?
If (1) turns out to be broken for reasons beyond the suffix, that is worth
splitting into its own issue; this one should stay scoped to packaging and
installation.
Acceptance criteria
make package && make installinstallspg_durable.dylibintopg_config --pkglibdiralong with the control and SQLfiles, and
CREATE EXTENSION pg_durableloads it.make uninstallremoves exactly whatinstallplaced and stays idempotent.pg_durable.so.scripts/test-make-install.shpasses on both platforms and exercises bothsuffixes on Linux CI.
macos-latestjob runs the above and is green.Out of scope
making a source install work, not about shipping artifacts.
Related
so this should land before the first PGXN upload.
TODO.md:21— "figure out process to build/release the extension for linux,windows and macos, with instructions for installation".
Evidence gathered against
microsoft/pg_durableat commit146b41b(
waldemort/pgxn-distribution), pgrxv0.16.1, and PostgreSQL branchesREL_15_STABLEthroughREL_18_STABLE.