Commit 3f9a369
authored
fix: remove subos sysroot override, use payload paths for toolchain sysroot (#62)
* fix: remove subos sysroot override, use payload paths for toolchain sysroot (#62)
Remove M5.5 logic that forced tc->sysroot to mcpp's xlings subos
(~/.mcpp/registry/subos/default). The subos created by `xlings self init`
lacks linux kernel headers (linux/limits.h, asm/, asm-generic/), causing
std module precompilation to fail on user machines.
Root cause: commit 063fb6f changed MCPP_HOME to ~/.mcpp/, where the
subos exists but is incomplete. M5.5 only checked exists(usr/include)
and overwrote the toolchain's correct sysroot. CI never caught this
because its subos is fully populated by `xlings self install`.
Design principle: mcpp uses xlings only as a package index + download
tool. Sysroot comes from the toolchain payload itself, not from subos.
Changes:
- cli.cppm: delete M5.5 subos sysroot override entirely
- probe.cppm: parse clang++.cfg --sysroot= when -print-sysroot fails
(Clang doesn't support -print-sysroot), so tc->sysroot reflects the
payload's actual configuration
- stdmod.cppm: generalize --no-default-config from macOS-only to all
Clang toolchains with a cfg file (cfg paths become stale after mcpp
copies the payload to its sandbox)
- flags.cppm: sync the same --no-default-config logic for regular
compilation flags
* fix: GCC sysroot fallback — remap stale build-time path to registry
GCC bakes the build-time sysroot into the binary via --with-sysroot.
For xlings-built GCC this is a path like <buildhost>/.xlings/subos/default
that doesn't exist on the user's machine. When -print-sysroot returns
such a non-existent path ending in subos/default, remap it to the
equivalent sysroot relative to the compiler's own xpkgs directory.
This is payload-derived (from the compiler binary's location in the
registry), not a config-level dependency on subos.
* fix: add target-specific libc++ include path for --no-default-config
When bypassing clang++.cfg with --no-default-config, we must provide
both libc++ include paths that the cfg originally supplied:
-isystem <llvmRoot>/include/c++/v1
-isystem <llvmRoot>/include/<triple>/c++/v1
The target-specific path contains __config_site which is required by
__config. Without it, std module precompilation fails with
'__config_site' file not found.
* fix: restrict --no-default-config to macOS only
On Linux, clang++.cfg contains essential linker flags (-fuse-ld=lld,
--rtlib=compiler-rt, --unwindlib=libunwind). Using --no-default-config
strips these, causing "cannot find crtbeginS.o" link failures because
clang falls back to system GNU ld looking for GCC runtime objects.
On Linux, let the cfg apply normally. The cfg's --sysroot points to
the xlings subos which is valid and complete. Pass --sysroot explicitly
only when needed (to override a stale cfg value), leveraging the fact
that command-line --sysroot takes precedence over the cfg's value.
Keep --no-default-config for macOS only, where the cfg-baked paths
genuinely become stale (pointing to CommandLineTools SDK when Xcode
SDK is active).
* feat: payload-first sysroot — assemble compile env from xpkgs payloads
Replace --sysroot dependency on xlings subos with fine-grained -isystem
paths derived from sibling xpkgs payloads (glibc, linux-headers).
Phase 2: PayloadPaths model
- Add PayloadPaths struct to Toolchain model (glibcInclude, glibcLib,
linuxInclude)
- probe_payload_paths() finds sibling glibc and linux-headers xpkgs
via find_sibling_package() which searches across all index prefixes
- Falls back to host /usr/include for linux kernel headers if no
xpkg found
Phase 3: Payload-first flags
- flags.cppm: use -isystem for glibc + linux-headers instead of
--sysroot; Clang with cfg uses --no-default-config + explicit flags
including -fuse-ld=lld, --rtlib=compiler-rt, --unwindlib=libunwind
- stdmod.cppm: unified Clang cfg bypass on all platforms for std
module precompile (no linker needed, so --no-default-config is safe)
Phase 4: Clang cfg fixup
- fixup_clang_cfg() rewrites clang++.cfg paths after payload copy,
similar to fixup_gcc_specs() for GCC
- Called during `mcpp toolchain install llvm`
Phase 5: Sysroot dependency auto-install
- Toolchain install ensures glibc and linux-headers xpkgs are
installed before the main toolchain package
* fix: GCC needs --sysroot for include-fixed, supplement with -isystem
GCC's include-fixed directory contains stdlib.h wrappers that use
#include_next to find the sysroot's stdlib.h. This mechanism only
works with --sysroot, not standalone -isystem paths.
Fix: for GCC, keep --sysroot from probe_sysroot() and supplement
with -isystem for linux kernel headers from payload when the probed
sysroot is missing them. For Clang, continue using --no-default-config
+ explicit -isystem (Clang doesn't have include-fixed).
* fix: add -nostdinc++ -stdlib=libc++ for Clang --no-default-config
When bypassing clang++.cfg, the cfg's -nostdinc++ and -stdlib=libc++
flags are also stripped. Without -nostdinc++, Clang may find host
libstdc++ headers before the payload's libc++ headers. Without
-stdlib=libc++, Clang defaults to libstdc++ runtime.
Also remove the /usr/include fallback for linux-headers — mixing
host headers with xpkg glibc causes bits/wordsize.h conflicts.
* feat: ensure sysroot complete by symlinking from payload xpkgs
When GCC's probed sysroot (subos/default) is missing linux kernel
headers or glibc headers, symlink them from the payload xpkgs:
- linux/, asm/, asm-generic/ ← scode-x-linux-headers xpkg
- features.h, bits/, etc. ← xim-x-glibc xpkg
This makes mcpp self-sufficient: it uses subos/default as a sysroot
directory for GCC's include-fixed mechanism, but actively populates
it from payload rather than depending on xlings init completeness.
Principle: subos is just a directory layout that mcpp manages.
Content comes from xpkgs payloads. Clang doesn't use subos at all
(--no-default-config + explicit -isystem from payload).
* fix: include MSVC effective triple in fingerprint (Windows)
Clang on Windows auto-detects the MSVC version at compile time and
embeds it in module AST files (e.g. x86_64-pc-windows-msvc19.44.35227).
But -dumpmachine returns just x86_64-pc-windows-msvc (no version).
When MSVC updates a patch version (35226 → 35227), the fingerprint
didn't change, so mcpp reused cached std.pcm compiled for the old
version → "AST file was compiled for different target" error.
Fix: probe clang's -print-effective-triple which includes the MSVC
version, and append to driverIdent for fingerprint computation.
Also: ensure sysroot complete by symlinking linux kernel headers
from payload xpkgs into the GCC sysroot directory.
* feat: add is_msvc_target() predicate + ci-fresh-install workflow
Refactor:
- Extract is_msvc_target() to model.cppm alongside is_musl_target()
- Replace 3 scattered tc.targetTriple.find("msvc") checks in
clang.cppm, detect.cppm, provider.cppm
CI:
- Add ci-fresh-install.yml: validates first-time user install flow
on all platforms (Linux, macOS, Windows) with zero cache.
- Tests: xlings install mcpp → self-host build → mcpp new → mcpp run
- Tests: import std with both GCC and LLVM (Linux), LLVM (macOS),
LLVM+MSVC STL (Windows)
- Catches issues that cached CI misses: incomplete sysroot, stale
cfg paths, missing xpkg dependencies
* fix: ci-fresh-install — correct asset names + MCPP_VENDORED_XLINGS
- macOS tarball: macos-aarch64 → macosx-arm64 (matches release assets)
- Windows: use explicit extract dir name
- All steps: export MCPP_VENDORED_XLINGS so freshly-built mcpp
uses the installed xlings binary for package operations
- Use MCPP_BOOTSTRAP for bootstrap mcpp, MCPP for freshly-built
- Set MCPP_HOME explicitly for consistent sandbox location
* fix: ci-fresh-install — simulate real user, no extra config
Strip all env overrides, self-host builds, and MCPP_VENDORED_XLINGS.
Simulate exactly what a real user does:
1. Install xlings
2. xlings install mcpp -y
3. mcpp new hello && cd hello && mcpp run
* fix: ci-fresh-install Windows — use pwsh for native path handling
Git Bash on Windows mangles GITHUB_PATH entries. Switch to pwsh
which handles Windows paths natively.
* fix: ci-fresh-install — workflow_dispatch only
This CI tests xlings-distributed mcpp (not the PR's code), so it
will fail until fixes are released to the xlings mcpp package.
Change to manual trigger only — run after a release to verify the
real end-to-end user experience.
* fix: ci-fresh-install — build PR's mcpp then test fresh user flow
Restore PR trigger. Flow:
1. Bootstrap xlings + old mcpp via xlings install
2. Build THIS PR's mcpp from source (self-host)
3. Use freshly-built mcpp to simulate fresh user: new → run
4. Linux: test both GCC (default) and LLVM toolchains
5. macOS: test LLVM (default)
6. Windows: test LLVM + MSVC STL
* ci: retrigger after clearing Windows cache
* fix: ci-fresh-install — simplify, use GITHUB_PATH only
- Remove all extra env vars (MCPP_VENDORED_XLINGS, XLINGS_BIN)
- Just add xlings bin to GITHUB_PATH, everything else works
- Windows: set PATH inline in bootstrap step so xlings install mcpp
can find xlings immediately
* fix: ci-fresh-install — no $MCPP var, just PATH; add mirror for LLVM
- Remove $MCPP variable, put freshly-built mcpp dir on PATH instead
- All steps just use `mcpp` command directly
- Linux LLVM step: add `mcpp self config --mirror GLOBAL` before
toolchain install (CI runners are outside CN)
- Windows: use pwsh throughout for native path handling
* fix: ci-fresh-install — test released mcpp, not freshly-built
Use xlings-installed mcpp directly to test:
1. mcpp build (self-host compile)
2. mcpp new hello → mcpp run (default toolchain)
3. Linux: install LLVM → mcpp new → mcpp run (continue-on-error
since released mcpp may not have latest fixes yet)
No extra env vars, no $MCPP variable — just mcpp on PATH via xlings.
* chore: move ci-fresh-install to separate PR
The fresh-install CI workflow tests the released mcpp binary via
xlings, not this PR's code. Move it to its own branch/PR to keep
this PR focused on the sysroot fix.
* ci: multi-toolchain coverage on Linux, remove continue-on-error tests
Linux CI now tests all 3 toolchains with freshly-built mcpp:
- GCC 16.1.0: mcpp new → build → run
- musl-gcc 15.1.0: mcpp new → build → run
- LLVM 20.1.7: install + mcpp new → build → run
Remove continue-on-error "Fresh user experience" tests from all
3 CI workflows — moved to separate ci-fresh-install.yml (PR #63).
Those tests validate the xlings-distributed mcpp binary, not the
PR's code, so they don't belong in the main CI gate.
* fix: actually update ci.yml (previous edit didn't take effect)1 parent 0e67801 commit 3f9a369
14 files changed
Lines changed: 1141 additions & 95 deletions
File tree
- .agents/docs
- .github/workflows
- src
- build
- toolchain
Lines changed: 370 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
0 commit comments