Skip to content

Commit df67537

Browse files
committed
fix(bench): macOS must not be handed the payload's libc++ — Apple's ld links against libc++ too
上一版给 clang 加 `-L<registry>/lib -Wl,-rpath,...` 之后,macOS 上 cmake / bazel / 参照 mcpp 依旧全挂,而日志终于说清了是谁在挂: dyld: Symbol not found: __ZdaPv Referenced from: /Applications/Xcode_15.4.app/.../usr/bin/ld Expected in: .../registry/.../lib/libc++.1.0.dylib **是 Apple 自己的 `ld` 被解析到了载荷的 libc++ 上**,还没开始链接就 abort 了。 把 registry 的 lib 目录摆到平台工具链够得着的地方,就是在给系统里塞第二份 libc++,而 `ld` 自己就链 libc++。 判据在同一次运行里:**被测的 mcpp 那条臂 18 个格子全绿** —— 同一台 runner、同一个 载荷。也就是说 mcpp 在 macOS 上根本不发这些 flag。载荷里的 clang 自己知道它的 libc++ 在哪,`-isysroot` 也由 cmake 自己补。 所以 macOS 上不发 libc++ 相关的任何 payload flag。同样的隐患也存在于 `hermetic_payload.cmake` 的 Clang 分支(此前 macOS 的 projects 臂本来就没跑通, 所以没暴露),一并加上 `AND NOT APPLE`。
1 parent 4284eb0 commit df67537

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

bench/projects/common/cmake/hermetic_payload.cmake

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,12 @@ function(bench_hermetic_payload)
117117
string(APPEND ld " --sysroot=${sysroot}")
118118
endif()
119119

120-
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
120+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
121+
# NOT APPLE for the reason bench/src/toolchain.cppm spells out: adding the
122+
# registry's lib directory on macOS makes Apple's own `ld` resolve against
123+
# the payload's libc++ and abort with `Symbol not found: __ZdaPv` before it
124+
# links anything. The payload clang finds its own libc++, and cmake supplies
125+
# -isysroot itself.
121126
# Clang's payload is shaped differently and `--sysroot` is NOT the
122127
# equivalent: mcpp drives clang with an explicit include chain instead
123128
# (verified against a real mcpp build command). Passing gcc's --sysroot to

bench/src/toolchain.cppm

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,27 @@ inline PayloadFlags payload_flags(std::string_view compiler) {
170170
return f;
171171
}
172172

173-
// clang: an explicit libc++ chain rather than --sysroot, which is what mcpp
174-
// itself drives clang with. Handing clang gcc's sysroot is the mirror of the
175-
// bug above — one arm on the payload libc, the other on the host's.
173+
// ⚠️ macOS GETS NOTHING, AND THAT IS THE CORRECT ANSWER.
174+
//
175+
// Pointing `-L`/`-rpath` at the registry's lib directory puts a second
176+
// libc++ where the platform toolchain can find it, and Apple's own linker
177+
// links against libc++ — so `ld` itself was resolved against the payload's
178+
// copy and died before it linked anything:
179+
//
180+
// dyld: Symbol not found: __ZdaPv
181+
// Referenced from: /Applications/Xcode_*.app/.../usr/bin/ld
182+
// Expected in: …/registry/…/lib/libc++.1.0.dylib
183+
//
184+
// cmake, bazel and the reference mcpp all failed identically while the mcpp
185+
// UNDER TEST passed on the same runner — which is the proof that mcpp does
186+
// not pass these flags on macOS either. The payload clang already knows
187+
// where its own libc++ is, and cmake supplies `-isysroot` itself.
188+
if (platform::OS_NAME == "macos") return f;
189+
190+
// clang elsewhere: an explicit libc++ chain rather than --sysroot, which is
191+
// what mcpp itself drives clang with. Handing clang gcc's sysroot is the
192+
// mirror of the gcc branch's bug — one arm on the payload libc, the other
193+
// on the host's.
176194
const std::string ver{on_windows() ? kLlvmWindows : kLlvm};
177195
const auto root = xpkgs / "xim-x-llvm" / ver;
178196
if (std::filesystem::is_directory(root / "include" / "c++" / "v1", ec)) {

0 commit comments

Comments
 (0)