@@ -164,13 +164,15 @@ CompileFlags compute_flags(const BuildPlan& plan) {
164164
165165#if defined(__APPLE__)
166166 // macOS linking strategy:
167- // - Do NOT pass --sysroot to the linker. The macOS SDK contains .tbd
168- // stubs that lack libc++abi exports, causing undefined symbols for
169- // exception/RTTI infrastructure. Without --sysroot, clang++ driver
170- // uses the system default (/usr/lib/libc++, libc++abi, libSystem)
171- // which works correctly.
172- // - sysroot is still used for compilation (finding system headers).
173- f.ld = std::format (" {}{}{}{}" , full_static, static_stdlib, b_flag, runtime_dirs);
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);
174176#else
175177 // Linux: sysroot must be passed to linker (glibc/musl lives there)
176178 f.ld = std::format (" {}{}{}{}{}" , full_static, static_stdlib, sysroot_flag, b_flag,
0 commit comments