Skip to content

fix(toolchain): the host helper must link the way the main build does (#437) - #442

Merged
Sunrisepeak merged 3 commits into
mainfrom
fix/host-helper-links-like-the-main-build
Aug 16, 2026
Merged

fix(toolchain): the host helper must link the way the main build does (#437)#442
Sunrisepeak merged 3 commits into
mainfrom
fix/host-helper-links-like-the-main-build

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

Closes #437.

On macOS a project builds and its build.mcpp does not — same toolchain, same environment, two link paths disagreeing. That is the part that makes it a bug rather than an environment quirk: mcpp on llvm builds the whole project and cannot build its own helper.

Root cause

linker outcome
main build -fuse-ld=lld, deliberately fine
build.mcpp host link trust-cfg branch returns no link tokens → Xcode /usr/bin/ld aborts

flags.cppm's macOS branch already says why, in its own words: "Xcode 15.4's ld aborting at launch on macos-14 CI when its libc++ resolution was diverted".

Apple's ld is itself a C++ Mach-O linked against libc++, and it runs inside the DYLD_* the payload toolchain sets up — so dyld resolves its libc++ to the payload's copy, which lacks __ZdaPv (operator delete[]), and it aborts before linking anything:

dyld: Symbol not found: __ZdaPv
  Referenced from: .../XcodeDefault.xctoolchain/usr/bin/ld
  Expected in:     .../xim-x-llvm/22.1.8/lib/libc++.1.0.dylib

Fix

The cfg picks runtimes; it has never picked a linker. So trusting it is right and incomplete — keep trusting it, and still name the linker on macOS. lld ships with the very toolchain doing the compile, so it cannot be diverted to a libc++ it was not built against.

Same shape as the rest of this round

One rule with two implementations, one of which knows something the other does not — exactly like the three duplicated spellings in the architecture review's §1 and doctor's fourth copy of the payload layout in §3b.

Docs

.agents/docs/2026-08-13-build-optimization-status.md §9a/§9a-2 recorded the symptom and stopped at "not guessing further, cannot reproduce on Linux". New §9a-3 carries the root-cause chain and the fix; the architecture review picks it up as §3e.

Also in this PR: §1 of the architecture review is corrected — its first draft invented gcc@system (see #441, closed).

Testing

No unit test, deliberately: the decision sits inside if constexpr (is_macos) and compiles out on the platform CI would run one on, so the test could not fail. The gate is the macOS e2e suite, where 11 tests carry a build.mcpp (89, 92, 110, 111, 125, 143, 144, 145, 181, 186, 194).

The first draft read `is_system_toolchain()` being gated on `Family::Msvc`
as an asymmetry and proposed supporting `gcc@system`. That is backwards.
xlings is a user-space OS and mcpp is built on it to keep host dependence to
a minimum: a toolchain comes from a payload, which is what makes "the
manifest says 14.44.35207" true on every machine rather than on the one that
happened to have it. `msvc@system` is a Windows concession — Visual Studio is
often already installed and cannot always be redistributed — not a general
capability with three families missing.

`gcc@system` was never a feature or a request. I invented it, and after being
corrected on the direction I wrote an explicit rejection for the spelling I
had invented, which is scope grown out of my own mistake. That PR (#441) is
closed.

Its message was also factually wrong: it claimed "only msvc@system exists",
while prepare.cppm:1376 keeps a deliberate bare-`system` escape hatch for the
PATH compiler. The one place host dependence IS offered is spelled with no
family at all — recorded here so the next review does not read it as a
missing capability either.

What survives is the finding that never depended on any of that: one platform
exception spread across 26 branches (13 in lifecycle.cppm, 13 in
prepare.cppm, zero for gcc/llvm/mingw), three duplicated spellings of the
same layout rule, and a resolution comment claiming 4 steps for a chain with
9 inputs. The remedy is to resolve Origin ONCE and dispatch on it — contain
the exception, do not spread or generalise it.
…#437)

On macOS a project builds and its `build.mcpp` does not — same toolchain,
same environment, two link paths disagreeing.

The main build deliberately forces `-fuse-ld=lld` there, and flags.cppm says
why in its own words: "Xcode 15.4's ld aborting at launch on macos-14 CI when
its libc++ resolution was diverted". The host helper takes the trust-cfg
branch in hostflags.cppm, which returns NO link tokens, so clang++ falls back
to Xcode's /usr/bin/ld. That binary is itself a C++ Mach-O linked against
libc++, running inside the DYLD_* the payload toolchain sets up, so dyld
resolves ITS libc++ to the payload's copy — which lacks __ZdaPv, and ld
aborts before linking anything.

The cfg picks runtimes; it has never picked a linker. So trusting it is right
and incomplete, and the fix is to keep trusting it while still naming the
linker on macOS. lld ships with the very toolchain doing the compile, so it
cannot be diverted to a libc++ it was not built against.

This is the same shape as the rest of this round: one rule with two
implementations, one of which knows something the other does not — like the
three duplicated spellings in the review's §1 and doctor's fourth copy of the
payload layout in §3b.

Root cause and reasoning recorded in
.agents/docs/2026-08-13-build-optimization-status.md §9a-3, which previously
stopped at "not guessing further, cannot reproduce on Linux"; the review doc
picks it up as §3e.

No unit test: the decision is inside `if constexpr (is_macos)` and compiles
out on the platform CI would run one on, so the test could not fail. The gate
is the macOS e2e suite, where 11 tests carry a build.mcpp.
The four open items all move a spec/schema layer or cross repositories, and
none of them belongs in a release window. Each is written up to the point
where it can be started directly.
@Sunrisepeak
Sunrisepeak merged commit ffb011d into main Aug 16, 2026
19 checks passed
@Sunrisepeak
Sunrisepeak deleted the fix/host-helper-links-like-the-main-build branch August 16, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants