I recently decided to check out Postgres hacking, and ran into a few issues when trying to build on an ARM Mac. The basic three-step of:

./configure
make
make check

each has a problem that needs to be fixed.

Dodging the ICU

First, when running ./configure, there’s an ICU library issue:

configure: error: ICU library not found

A quick search suggests that we need to set the right PKG_CONFIG_PATH. brew info icu4c offers more information:

For pkg-config to find icu4c@77 you may need to set:
  export PKG_CONFIG_PATH="/opt/homebrew/opt/icu4c@77/lib/pkgconfig"

Doing so successfully runs ./configure.

Make-ing it a little further

Next, when runnning make, there’s an issue with strchrnul on macOS Sequoia when trying to build a recent release like 17.4:

snprintf.c:414:27: error: 'strchrnul' is only available on macOS 15.4 or newer [-Werror,-Wunguarded-availability-new]
  414 |                         const char *next_pct = strchrnul(format + 1, '%');
      |                                                ^~~~~~~~~
snprintf.c:366:14: note: 'strchrnul' has been marked as being introduced in macOS 15.4 here, but the deployment target is macOS 15.0.0
  366 | extern char *strchrnul(const char *s, int c);

Note that this occurs on 15.4 too, even though the error message says strchrnul is available on 15.4 and newer.

This has been fixed on master, so just git pull the latest.

Don’t SIP while you test

Running regression tests with make check gives yet another error:

dyld[65265]: Library not loaded: /usr/local/pgsql/lib/libpq.5.dylib

make check runs tests against a temporary installation, which requires remapping library paths with DYLD_LIBRARY_PATH. However, macOS’s System Integrity Protection (SIP) mechanism prevents DYLD_ and LD_ environment variables from being passed to child processes.

There have been attempts to fix this within Postgres, but no uptake due to the large number of locations where changes have to be made.

The Postgres installation docs note that we can run make installcheck to avoid the temporary installation. However, it’s easier to just turn off SIP.

Naturally, the official instructions for turning off SIP don’t work:

The OS environment does not allow changing security configuration options. Ensure that the system was booted into Recovery OS via the standard user action.

We need to first run csrutil clear, then restart into Recovery Mode again, run csrutil disable, and restart normally.

After that, we successfully run regression tests:

$ make check
...
# All 228 tests passed.