Problem
Building jargon fails on macOS (ARM64) when LDFLAGS is already set in the shell environment. A common cause is Homebrew's PostgreSQL, which adds -L/opt/homebrew/opt/postgresql@16/lib to LDFLAGS via shell profile configuration.
The NIF compiles successfully but the final link step fails:
Undefined symbols for architecture arm64:
"_enif_alloc", referenced from:
_argon2_verify_nif in jargon.o
"_enif_free", referenced from:
_argon2_verify_nif in jargon.o
"_enif_get_uint", referenced from:
_argon2_hash_nif in jargon.o
...
ld: symbol(s) not found for architecture arm64
Cause
In c_src/Makefile, line 36 sets the Darwin linker flags with ?=:
ifeq ($(UNAME_SYS), Darwin)
LDFLAGS ?= -flat_namespace -undefined suppress
The ?= operator means "only set if not already defined." When LDFLAGS is already in the environment, the macOS-specific -flat_namespace -undefined suppress flags are never applied. These flags are required on macOS because the enif_* symbols are provided by the BEAM VM at runtime, not at link time.
The build then runs with just -shared (appended on line 56) plus whatever was in the environment, which on macOS causes the linker to treat the unresolved NIF symbols as errors.
Workaround
Prepend the required flags when building:
LDFLAGS="-flat_namespace -undefined suppress $LDFLAGS" gleam test
Suggested fix
Change the Darwin block to unconditionally prepend the required flags rather than using conditional assignment:
ifeq ($(UNAME_SYS), Darwin)
CC ?= cc
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -finline-functions -Wall
LDFLAGS += -flat_namespace -undefined suppress
This ensures the NIF-required flags are always present regardless of what else is in LDFLAGS.
Environment
- macOS 15 (Darwin 24.6.0), Apple Silicon
- Erlang/OTP 28.5
- Homebrew PostgreSQL 16 (
LDFLAGS=-L/opt/homebrew/opt/postgresql@16/lib)
- jargon 1.1.0, argus 1.0.4
Problem
Building jargon fails on macOS (ARM64) when
LDFLAGSis already set in the shell environment. A common cause is Homebrew's PostgreSQL, which adds-L/opt/homebrew/opt/postgresql@16/libtoLDFLAGSvia shell profile configuration.The NIF compiles successfully but the final link step fails:
Cause
In
c_src/Makefile, line 36 sets the Darwin linker flags with?=:The
?=operator means "only set if not already defined." WhenLDFLAGSis already in the environment, the macOS-specific-flat_namespace -undefined suppressflags are never applied. These flags are required on macOS because theenif_*symbols are provided by the BEAM VM at runtime, not at link time.The build then runs with just
-shared(appended on line 56) plus whatever was in the environment, which on macOS causes the linker to treat the unresolved NIF symbols as errors.Workaround
Prepend the required flags when building:
Suggested fix
Change the Darwin block to unconditionally prepend the required flags rather than using conditional assignment:
This ensures the NIF-required flags are always present regardless of what else is in
LDFLAGS.Environment
LDFLAGS=-L/opt/homebrew/opt/postgresql@16/lib)