Skip to content

NIF build fails on macOS when LDFLAGS is set in environment (e.g. Homebrew PostgreSQL) #6

@rapind

Description

@rapind

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions