Skip to content

🐛 Statically link libc++ on macOS for LLVM 22+ - #57

Merged
kammce merged 1 commit into
mainfrom
macos-static-libcxx
Oct 12, 2026
Merged

kammce merged 1 commit into
mainfrom
macos-static-libcxx

Conversation

@kammce

@kammce kammce commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Upstream libc++ headers expect a libc++ library of the same version, but Apple's system libc++ lags behind upstream:

  • macOS 26: LLVM 23 programs fail to link (Undefined symbols: vtable for std::__bad_variant_access_with_msg).
  • macOS 14/15: the recipe linked the bundled libc++ dylib instead, but LLVM's ASan runtime links the system libc++, so ASan tests loaded two libc++ copies and aborted at exit (bad-free in std::locale::~locale).

For LLVM 22+, this links the package's libc++.a and libc++abi.a statically on every macOS version, so every program uses the libc++ that matches its headers. It also exposes libc++ to link-time analysis. -Wl,-no_exported_symbols is also needed: without it, dyld merges the executable's weak libc++ symbols with the system libc++ that ASan loads, and the same locale bad-free comes back (reproduced with scatter_span's tests). LLVM 20/21 keep using the system libc++.

demos/libcxx-runtime is built and run under ASan on native LLVM 22+ CI jobs. It throws bad_variant_access and exercises locales, and it aborts without -no_exported_symbols.

Tested locally on macOS 27: the demo and scatter_span's ASan tests pass, and binaries have no libc++ dylib dependency.

Verified in CI with LLVM 23 on macOS 15, 26 and 27: the toolchain builds and the libc++ runtime check passes on all three.

Upstream libc++ headers expect a libc++ library of the same version, but
Apple's system libc++ lags behind: LLVM 23 programs fail to link on macOS
26 (missing vtable for std::__bad_variant_access_with_msg). Linking the
bundled libc++ dynamically instead put two libc++ copies in any ASan
process, since the ASan runtime uses the system libc++.

For LLVM 22+, link the package's libc++.a and libc++abi.a statically on
every macOS version, with -Wl,-no_exported_symbols so dyld doesn't merge
the executable's weak libc++ symbols with the system copy.

Add demos/libcxx-runtime, which CI builds and runs under ASan on native
builds, to catch both failures.
@kammce
kammce force-pushed the macos-static-libcxx branch from f976ee7 to 3c6737e Compare October 12, 2026 02:08
@kammce
kammce marked this pull request as ready for review October 12, 2026 02:08
@kammce
kammce merged commit b2401d6 into main Oct 12, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant