Build macOS shared modules as dylib rather than bundle

Started by Peter Eisentrautover 1 year ago2 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

won't retrysuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t51402
psql -h localhost -U postgres

Built from patchset v1 (message #1), July 27, 2026 at 09:35 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t51402_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t51402_1 && git checkout t51402_1

Patchset v1 (message #1) is on t51402_1

Jump to latest
#1Peter Eisentraut
peter_e@gmx.net

I'm splitting this out from [0]/messages/by-id/170e7e57-fe43-4e7e-8566-a96fcdf23075@eisentraut.org so that it can be tracked and referenced
separately.

[0]: /messages/by-id/170e7e57-fe43-4e7e-8566-a96fcdf23075@eisentraut.org
/messages/by-id/170e7e57-fe43-4e7e-8566-a96fcdf23075@eisentraut.org

Historically, bundles (ld -bundle) were the only file type that could
be dynamically loaded at run time on macOS (OS X at the time). These
were distinct from dynamic libraries (ld -dynamiclib (although the man
page says -dylib, but that apparently doesn't work)) that you use at
build time (-lfoo). Therefore, that platform had a strict distinction
between shared libraries and shared modules, unlike other platforms.

Over time, macOS gained the ability to dlopen dynamic libraries as
well, so this distinction is obsolete. Also, it appears that the
bundle file type is obsolescent on other Apple platforms. So, to
simplify this, change our shared library makefiles to build the
dynamic library file type for both uses. (There are still some
distinctions between the two in the build system, such as where they
are installed and how the output files are named, but they are now
internally the same file type.) Meson also has the same change
pending in its master branch, so this will eventually become
consistent.

But this change triggers a new variant of this issue:

/messages/by-id/E1o4HOv-001Oyi-5n@gemulon.postgresql.org

With the changed linker options, the symbol search order appears to
be different, and so hash_search() gets found in the OS library first.

(Historical research reveals that this name clash is not accidental.
dynahash.c was explicitly modeled after routines that existed in some
BSD OS, and continue to exist in macOS, but they don't have compatible
signatures.)

To avoid that, I suggest to use some preprocessor defines to rename the
symbols known to clash, in a way that we can continue to use the
existing API names.

I suggest that we consider the dynahash change for PG18. The Meson
change will eventually come our way, and then everything on macOS will
start crashing. So the earlier we fix this the better. Also, we can't
backpatch this because of the ABI change, so once PG18 ships the window
is over.

For the -bundle -> -dynamiclib change, I don't have any particular
urgency right now.

Attachments:

t51402_1
v1-0001-Avoid-symbol-clashes-of-dynahash-with-OS.patchtext/plain; charset=UTF-8; name=v1-0001-Avoid-symbol-clashes-of-dynahash-with-OS.patchDownload+15-1
v1-0002-Build-macOS-shared-modules-as-dylib-rather-than-b.patchtext/plain; charset=UTF-8; name=v1-0002-Build-macOS-shared-modules-as-dylib-rather-than-b.patchDownload+4-10
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#1)
Re: Build macOS shared modules as dylib rather than bundle

Peter Eisentraut <peter@eisentraut.org> writes:

... But this change triggers a new variant of this issue:
/messages/by-id/E1o4HOv-001Oyi-5n@gemulon.postgresql.org
With the changed linker options, the symbol search order appears to
be different, and so hash_search() gets found in the OS library first.

To avoid that, I suggest to use some preprocessor defines to rename the
symbols known to clash, in a way that we can continue to use the
existing API names.

I don't love that solution. If we simply put up with this name
resolution order, we leave ourselves open to being blindsided by
any future libc addition that Apple chooses to make. The recent
strchrnul() kerfuffle is still causing me pain every day, so
maybe this is more front-of-mind than it would be at another time.
But I think it is worth our time to try to find a way to get back
the other resolution order.

I suggest that we consider the dynahash change for PG18. The Meson
change will eventually come our way, and then everything on macOS will
start crashing. So the earlier we fix this the better. Also, we can't
backpatch this because of the ABI change, so once PG18 ships the window
is over.

Arguably, changing library name resolution order is an ABI break
in itself. If we can't fix that, I think we will have to mandate
that this change happens only at a major-release boundary. Which
is going to be no fun for anybody, if meson is going to force it
on us across-the-board at some random time. We should perhaps
push back on the idea that they get to decide when and how that
changes.

regards, tom lane