Skip to content

Commit f487838

Browse files
committed
fix: macOS link uses system libc++ (not xlings LLVM's)
xlings LLVM's libc++.dylib doesn't pull in libc++abi, causing undefined exception/RTTI symbols. Solution: don't pass -L<llvm>/lib to the linker on macOS — let clang++ link against system libc++ (/usr/lib/libc++.dylib) which correctly includes libc++abi. Compile still uses LLVM 20 headers (ABI-compatible with system libc++).
1 parent 579815b commit f487838

1 file changed

Lines changed: 9 additions & 10 deletions

File tree

src/build/flags.cppm

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,16 @@ CompileFlags compute_flags(const BuildPlan& plan) {
164164

165165
#if defined(__APPLE__)
166166
// macOS linking strategy:
167-
// 1. Do NOT pass --sysroot to the linker. The macOS SDK .tbd stubs
168-
// lack libc++abi exports → undefined symbols. Without sysroot,
169-
// clang++ links against /usr/lib system libraries correctly.
170-
// 2. Explicitly pass -lc++ because xlings LLVM's clang++.cfg uses
171-
// -nostdinc++ which also suppresses the implicit stdlib linkage.
172-
// sysroot is still passed for compilation (finding system headers).
173-
std::string stdlib_link = isClang ? " -lc++" : "";
174-
f.ld = std::format("{}{}{}{}{}", full_static, static_stdlib, b_flag,
175-
runtime_dirs, stdlib_link);
167+
// - No --sysroot: SDK .tbd stubs miss libc++abi exports.
168+
// - No -L<llvm>/lib: xlings LLVM's libc++.dylib doesn't pull in
169+
// libc++abi. System /usr/lib/libc++ does (and is ABI-compatible
170+
// with LLVM 20 headers since macOS ships a recent libc++).
171+
// - No -rpath for LLVM lib: binary should use system libc++ at runtime.
172+
// - Explicit -lc++: clang++.cfg's -nostdinc++ suppresses implicit linkage.
173+
// Result: compile with LLVM headers, link with system libc++ + libc++abi.
174+
f.ld = std::format("{}{}{} -lc++", full_static, static_stdlib, b_flag);
176175
#else
177-
// Linux: sysroot must be passed to linker (glibc/musl lives there)
176+
// Linux: sysroot + runtime dirs needed (glibc/libc++ live in sandbox)
178177
f.ld = std::format("{}{}{}{}{}", full_static, static_stdlib, sysroot_flag, b_flag,
179178
runtime_dirs);
180179
#endif

0 commit comments

Comments
 (0)