fix(toolchain): the host helper must link the way the main build does (#437) - #442
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #437.
On macOS a project builds and its
build.mcppdoes 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
-fuse-ld=lld, deliberatelybuild.mcpphost link/usr/bin/ldflags.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
ldis itself a C++ Mach-O linked against libc++, and it runs inside theDYLD_*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: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 abuild.mcpp(89, 92, 110, 111, 125, 143, 144, 145, 181, 186, 194).