Skip to content

[bug][macOS] build.mcpp host link 用 Xcode ld 启动即 abort:dyld __ZdaPv — 任何带 build.mcpp 的工程在 macOS 上都无法构建(§9a,未修) #437

Description

@ZheFeng7110

现象

macOS 上,任何依赖带 build.mcpp 的包(包括仓库根自带 build.mcpp 的工程)在 mcpp build 的第一步就失败:

build.mcpp compiling
error: build.mcpp failed to compile (exit 1):
dyld[5701]: Symbol not found: __ZdaPv
  Referenced from: <…> /Applications/Xcode_15.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
  Expected in:     <…> ~/.mcpp/registry/data/xpkgs/xim-x-llvm/22.1.8/lib/libc++.1.0.dylib
clang++: error: unable to execute command: Abort trap: 6
clang++: error: linker command failed due to signal (use -v to see invocation)

被 abort 的是 Apple 自己的 /usr/bin/ld(Xcode 15.4),不是 clang++。__ZdaPvoperator delete[](void*) 的 mangling,dyld 期望它在 llvm 22.1.8 payload 的 libc++ 里,但那份 libc++ 没有。

同一工程的主构建在 macOS 上全绿(27 个模块)—— 只有 build.mcpp 的 host 链接这一步挂。

与已知记录的关系

这正是 .agents/docs/2026-08-13-build-optimization-status.md §9a / §9a-2 记录的那个已知、至今未修的缺陷:

  • §9a "macOS 上 mcpp 编不了依赖的 build.mcpp 助手" —— 错误签名与上面一字不差;
  • §9a-2 —— 去掉所有 payload libc++ flag 后依旧发生,污染走 DYLD_* 环境、被所有子进程继承,不是链接 flag;bench 团队因此把 macOS 格子直接排除,未修 mcpp 本体。

根因链(基于当前 mcpp 源码)

  1. build_program.cppm:154 把 host helper 的 cfgBypass 设为 CfgBypass::LinuxOnly;
  2. hostflags.cppm:177-185 在 macOS 上 bypassCfg=false → 命中 else if (dm.hasCfg) return out;(:184)返回空 link token —— 没有 -fuse-ld=lld;
  3. clang++(payload)用默认链接器 = Xcode 的 /usr/bin/ld;
  4. Apple 的 ld 自身是 C++ Mach-O、链接了 libc++;dyld 启动它时把它的 libc++ 依赖解析到了 llvm 22.1.8 payload 的 libc++.1.0.dylib(loader 路径被 DYLD_* 污染),而那份 libc++ 缺 __ZdaPvld 启动即 abort。

主构建不受影响的原因:flags.cppm:1059-1063,1085 在 macOS 上刻意用 -fuse-ld=lld(注释原文就是 "Xcode 15.4's ld aborting at launch on macos-14 CI when its libc++ resolution was diverted")。同一环境下 lld 可用而 Xcode ld 不可用,已由 bench "mcpp 那条臂 18 个格子全绿" 佐证。

因此「抬高 mcpp 版本」无法解决:这条路径到 v2026.8.15.3 / HEAD 为止零改动,修复从未进入任何 release。

建议修复方向

对齐主构建的 macOS 链接做法,让 build.mcpp 的 host 链接也走 lld:

  • A(推荐):hostflags.cppm::host_link_tokens 的 trustCfg 分支对 macOS 追加 -fuse-ld=lld(等价 flags.cppm:1085 的做法);
  • post_install.cppm::fixup_clang_cfg 的 macOS 分支把 -fuse-ld=lld 写进 cfg。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions