fix(build): macOS test binaries link the toolchain's own libc++ (A1) + unpin llvm#202
Merged
Conversation
…oot fix) TestBinary previously linked the SYSTEM -lc++ while compiling against the toolchain's libc++ HEADERS — a header/dylib version split that detonated when libc++ 22 moved string hashing out of line (__hash_memory undefined against Apple's older dylib; every gtest link on macOS+llvm-22.1.8 failed). Tests are host-only by definition, so an rpath into the toolchain registry is acceptable for them in a way it isn't for distributables. ldStdlibTest becomes: -nostdlib++ -L<llvm>/lib -lc++ -lc++abi -Wl,-rpath,<llvm>/lib (when the toolchain ships a libc++ dylib; system -lc++ fallback otherwise). Same-version headers and dylib by construction — future libc++ out-of-lining is self-consistent. Dynamic teardown also dissolves the static-destruction SIGABRT that originally motivated the system-lib exception. Distributables keep the static -load_hidden LLVM libc++. ci-macos returns to latest-first llvm install (the 20.1.7 pin's exit criterion): the job now PROVES each new llvm default self-consistent. New e2e 94_macos_test_stdlib (requires: macos): unordered_map<string> hashing under mcpp test + otool -L asserts no /usr/lib/libc++ reference. Design: .agents/docs/2026-07-08-root-cause-remediation-design.md A1.
libc++.1.dylib reexports its abi; linking libc++abi.dylib explicitly alongside the system abi (loaded transitively via macOS frameworks) doubled the __cxa_* runtime state — every test binary aborted before main (exit 6) on the first macOS CI round.
…); add macOS failure forensics Round 2 proved the abi symbols are NOT reexported by this distribution's libc++.dylib (undefined __cxa_*/operator new at link). Round 1's runtime SIGABRT therefore has a different cause — the new forensics step captures otool -L, LC_RPATHs and a direct binary run on failure so the next round names it.
… crash reports The version-glob pick chose a stale cached 20.1.7 beside the freshly installed 22.1.8 — rounds 1-3 never actually tested the new llvm. Also capture the newest .ips crash report after a direct failing run (the SIGABRT is silent on stderr).
… crash termination Rounds 1-4 never tested llvm 22: mcpp.toml's macos pin kept resolving 20.1.7 (whose lib/ dylibs silently SIGABRT at load — they were never exercised in the static-archive era). Pin the current llvm so mcpp's own macOS build+tests run on it; forensics now parses the .ips crash report (termination + triggered-thread frames) instead of dumping raw JSON.
…sh: dual libc++ states) Crash report named it: exit-time locale::~locale freeing a pointer malloc never allocated — two libc++ copies in one process, from -l resolution mixing the sibling libc++.a into the link. By-path dylib linking removes the ambiguity. Forensics now also counts statically embedded libc++ text symbols (nm) to prove the binary is archive-free.
…distributables Forensics rounds 5-6 closed the dynamic route: this llvm distribution's libc++abi/libunwind dylibs upward-link /usr/lib/libc++, so the system libc++ ALWAYS loads beside the toolchain's — gtest's static initializers then construct a stringstream in one copy and destroy it in the other (BUG_IN_CLIENT_OF_LIBMALLOC_POINTER_BEING_FREED in locale::~locale). Static hidden archives keep exactly one libc++ inside the binary — the shape mcpp's own shipped binaries have used green for months. If the historical gtest exit-teardown SIGABRT resurfaces it will now be caught by this same CI lane with forensics in place.
… dylib self-containment item
… test_smoke (2 passed)
Sunrisepeak
added a commit
that referenced
this pull request
Jul 8, 2026
…(A1), cross gcc16 floor (A2/R5a) (#203) Version bump + remediation-doc live status. Ships on top of the merged PRs #201 (verified gated mirroring) and #202 (static libc++ for test binaries, llvm 22.1.8 green); this branch adds the aarch64 cross floor: <triple>-gcc@16.1.0 (xim entry #344), retiring GCC 15 from the cross path. The manifest instantiation anchor REMAINS for the x86_64 musl release build (musl-gcc 15.1.0) until R5b packages its gcc 16.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root-cause fix for the llvm 22.1.8 __hash_memory link failure. ci-macos in this PR runs with llvm latest (22.1.8) — its e2e suite (incl. new 94_macos_test_stdlib) IS the proof. See
.agents/docs/2026-07-08-root-cause-remediation-design.md§A1.