Skip to content

Tags: mcpp-community/mcpp

Tags

v0.0.94

Toggle v0.0.94's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(build): feature sources 在 `mcpp test` 下不编译 (0.0.94) (#218)

prepare_build() 把 feature 源集解析(drop + add)整段门在 `!includeDevDeps`,
`mcpp test` 走 includeDevDeps=true → 激活 feature 的 sources 从不被加回构建图。
xpkg 的 `features.X.sources` 只落进 featureSources、从不进 base sources,故
「只在 features 下声明」的包 build 正常、test 必然 undefined reference。

命中 compat.cjson `utils`、compat.eigen `eigen_blas`(dgemm_)、compat.spdlog
`compiled`。eigen_blas 的 dgemm_ 一直被记为「链进 test 二进制是 follow-up」,
定性是错的:不是链接问题,是源集解析问题。

drop 仍只在 build 模式做(test 模式需保留完整源面供 dev-dep 轨 per-test main
检测剪枝,见 e2e 79);add 改为两模式都做 + 去重(gtest 双列 glob 不会进两次)。

回归测试 e2e 100:已验证在未修复的 0.0.92 上以目标错误失败、修复后通过;
e2e 78/79(#168 gtest 回归靶子)与单测 35/35 均通过。

v0.0.93

Toggle v0.0.93's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(toolchain): toolchain × target 命名统一 — 二轴身份模型 (0.0.93) (#217)

toolchain = family@version (gcc|llvm|msvc) × target = arch-os[-env] triple;
musl/mingw/cross 不再是工具链名字,全部旧拼写永久兼容(compat.cppm);
canonical x86_64-windows-gnu;--target 封闭词汇表校验 + did-you-mean;
CLI --target 选项 + [build] target;list 两轴重排;README 平台表从词汇表重画。
设计:.agents/docs/2026-07-15-toolchain-target-naming-unification-design.md

v0.0.92

Toggle v0.0.92's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(toolchain): Linux→Windows MinGW cross toolchain (mingw-cross) — …

…host≠target (0.0.92) (#216)

Cross-compile Windows x86_64 PE (incl. import std) from a Linux host — the
deferred host≠target axis registered in the 0.0.89 msvc-mingw design (§4.4/§7).

- registry: mingw-cross → xim mingw-cross-gcc (x86_64-w64-mingw32-g++ frontend,
  triple-prefixed archiver, Linux-host index visibility)
- lifecycle: lift the Windows-host gate for the cross package (native mingw stays
  Windows-only); skip glibc/linux-headers sysroot deps (PE own CRT)
- prepare: --target x86_64-w64-mingw32 convention → mingw-cross@16.1.0, static
- host≠target fixes surfaced by real end-to-end validation:
  * gcc.cppm: find std module source under <prefix>/<triple>/include/c++/
  * gcc.cppm + flags.cppm: self-contained toolchains (musl+mingw) skip external -B
    (Linux as can't assemble MinGW PE/SEH output)
  * flags.cppm: MinGW PE link (-static / -lstdc++exp) keyed on is_mingw_target
    (target) instead of is_windows (host) — was unreachable on a Linux cross
- toolchain: from-source GCC 16.1.0 mingw-w64 MSVCRT cross, published at
  xlings-res/mingw-cross-gcc + xim-pkgindex (import std verified under wine)
- tests: unit MapsMingwCrossSpecToCrossPackage; e2e 102_mingw_cross_wine.sh;
  run_all mingw-cross/wine caps; CI cross-build-test mingw-cross-wine job
- design: .agents/docs/2026-07-15-mingw-linux-cross-windows-design.md

Verified end-to-end via the published ecosystem: mcpp toolchain install
mingw-cross → mcpp build --target x86_64-w64-mingw32 → PE32+ (KERNEL32+msvcrt
only) → wine runs import std + multi-module.

Co-authored-by: Sunrisepeak <x.d2learn.org@gmail.com>

v0.0.91

Toggle v0.0.91's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat: standard = "c++fly" — one knob for latest std + all experimenta…

…l features (0.0.91) (#214)

* feat(toolchain): cppfly registry — latest-std + experimental gates per compiler

* feat(manifest,build): standard=c++fly — latest std + all experimental gates; fix c++latest GNU spelling

* test(e2e): c++fly hard/soft paths + c++latest spelling regression

* docs(release): 0.0.91 — changelog, c++fly design + plan docs, manifest docs, version bump

* fix(e2e): 101 — assert stdlib gate consistency instead of hardcoding libc++ (clang+MSVC STL on windows); .exe-aware binary find

v0.0.90

Toggle v0.0.90's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(toolchain): native MSVC cl.exe build backend + graph-global dial…

…ect flags (#210) — 0.0.90 (#213)

* docs(agents): 0.0.90 single-PR implementation plan (full post-089 roadmap)

* fix(build): dialect-class flags reach the std BMI prebuild and the whole module graph (#210)

[build].cxxflags like -freflection change what libstdc++ headers DECLARE
(<meta> is gated on __cpp_impl_reflection) — they are module-graph dialect,
same nature as -std=. They now ride -std='s channels: the global $cxxflags
(every TU incl. dependency modules — fixes the fmt.gcm-class secondary
failure), the std/std.compat prebuild command, and scans. Known-list
auto-promotion (reflection/contracts/char8_t/_GLIBCXX_USE_CXX11_ABI) +
explicit [build] dialect_cxxflags escape hatch. The fingerprint already
keyed these flags — only the command construction was missing them.

Also: cppStandardFlag is now spelled per-dialect (std_flag_for — msvc
/std:c++20 | /std:c++latest), groundwork for the native MSVC backend.

Verified: issue #210's exact repro prints 'x 2 / y 3' via import std on
gcc@16.1.0; e2e 98 covers both variants + std-module.json assertion.

* feat(toolchain): native MSVC cl.exe build backend (C1-C7)

- C1 env model: find_windows_sdk() + build_env_for_cl() synthesize
  INCLUDE/LIB/PATH/VSLANG=1033 from the detected VC tools + SDK (no
  vcvarsall run); enrich_toolchain_from_cl fills tc.envOverrides; missing
  SDK keeps detection working and fails the BUILD with guidance (replaces
  the 0.0.88 'not yet supported' gate — the gate is gone).
- C2 emission: SeparateLinker rules (link.exe /OUT + rspfile — cmd's 8191
  limit), lib.exe archives, /DLL+/IMPLIB shared, deps=msvc via
  /showIncludes, /interface /TP for .cppm module units, /std: mapping
  (std_flag_for), /MD|/MT CRT model, /Od, /nologo /EHsc /utf-8 baseline,
  .obj object extension end to end (plan objExt + std staging names).
- C3 std/std.compat staging: single-cl commands (/ifcOutput), ifc.cache
  layout, registry-dispatched staged paths (clang hardcoding removed),
  stdmod executes with the toolchain env (capture_with_env).
- C4 scanning: /scanDependencies as the third builtin P1689 producer
  (provider capability + ninja scan rule); dyndep ifc-parameterized as-is.
- C8 fast path: '@env' multi-var encoding in the build cache env slot so
  incremental msvc builds re-create INCLUDE/LIB for ninja.
- cd /d in std stage commands (cmd.exe won't change drive without it;
  D: workspace + C: BMI cache is the real CI layout).

Zero-diff gate re-verified for GCC and LLVM vs the 0.0.89 release binary.

* feat: e2e 99 msvc native build, 95 gate-flip, mingw polish, 0.0.90 version/docs

- e2e 99 (requires: msvc): default msvc → modules build/run → import std →
  incremental; 95's build-gate assertion flips to a real build+run; the
  ci-windows MSVC step now drives 99.
- mingw: windows-only guard with a clear message (was 'invalid xpkg target
  xim:mingw-gcc@'); e2e 97 objdump path unhardcoded; doctor gains Windows
  SDK + mingw sections.
- release.yml publish-ecosystem timeout 20→30 (backstop for the fixed
  mirror script's worst case).
- version 0.0.90 + CHANGELOG + docs/03 MSVC build section.

v0.0.89

Toggle v0.0.89's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(toolchain): backend abstraction (CommandDialect) + MinGW-w64 via…

… the xlings ecosystem — 0.0.89 (#211)

* refactor(toolchain): CommandDialect + backend surface normalization (Part A)

New mcpp.toolchain.dialect: command-line *spellings* (gnu vs msvc) as a
value-type traits table — flags.cppm and ninja rule templates now spell
-I/-D/-std=/-c/-o/-O/-g/ar-invocations through it instead of hardcoding
GNU syntax. BmiTraits gains the module-flag spellings (compileModulesFlag,
stdBmiUsePrefix, moduleOutputPrefix, bmiSearchPrefix), replacing the
is_clang()/stdlib_id branches in flags.cppm. ProviderCapabilities gains
has_builtin_p1689_scan (drops ninja_backend's is_gcc gate). Toolchain gains
envOverrides (EnvVar list — std::pair member trips GCC-16 module pendings)
merged into ninja's child env; the MSVC backend will carry INCLUDE/LIB/PATH
through it. gcc::std_module_build_commands normalizes the provider surface
to the command-sequence shape clang already has. resolve_link_model returns
the empty PE model explicitly on Windows.

Zero-diff verified: build.ninja byte-identical (modulo the mcpp self-path
var) for GCC and LLVM toolchains on a multi-module import-std project;
mcpp test 31/31.

* feat(toolchain): MinGW-w64 GCC via the xlings ecosystem (mingw@16.1.0) (0.0.89)

User-facing 'mingw' spec → xim:mingw-gcc (winlibs GCC 16.1.0 + MinGW-w64
14.0.0 UCRT standalone build, mirrored at xlings-res/mingw-gcc). Reuses the
GCC backend end-to-end (gcm module pipeline, bits/std.cc import std);
Windows adds static libstdc++/libgcc defaults so produced exes run
standalone, and -static under linkage="static". archive_tool resolves the
bundled ar.exe; std.cc lookup gains a version-dir scan fallback.

Fixes ridden along: toolchain list 'Available' + partial-version resolution
read xpkg versions for the HOST platform (was hardcoded linux — empty on
win/mac); toolchain install no longer pulls glibc/linux-headers on win/mac.

e2e 97 (requires: windows cap) + ci-windows MinGW step + unit tests
(dialect rows, mingw spec mapping); docs + CHANGELOG; version 0.0.89.

* fix(linkmodel): key the PE early-out on the target, not the host

The Windows-host if-constexpr broke the linkmodel contract tests on
Windows CI (they resolve synthetic Linux-shaped toolchains anywhere).
Target-keyed is also the semantics a future cross build needs.

* fix(flags): MinGW links libstdc++exp for std::print terminal symbols

std::vprint_unicode's __open_terminal/__write_to_terminal live in
libstdc++exp.a on Windows-GCC targets — first real MinGW link on CI failed
with undefined references from bits/print.h.

* fix(flags): force winpthread static on MinGW links

winlibs POSIX-threads libstdc++ otherwise leaves produced exes depending on
libwinpthread-1.dll — the standalone-exe e2e caught it (empty output,
missing-DLL abort). -Wl,-Bstatic -lwinpthread -Wl,-Bdynamic is the standard
recipe; libwinpthread.a ships in the payload.

* test(e2e): 97 asserts the exe import table (objdump) + diagnostic output

The silent standalone-run failure gave nothing to debug — inspect DLL
imports directly and dump them on any failure.

* fix(flags): MinGW default links -static — the piecemeal winpthread recipe loses to driver implicit libs

CI import table still showed libwinpthread-1.dll after
-Wl,-Bstatic -lwinpthread; winlibs' documented answer for standalone exes
is a full -static link (system DLLs still resolve via import libs).
Gated on staticStdlib so [build] static_stdlib=false opts out.

v0.0.88

Toggle v0.0.88's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(toolchain): MSVC system-toolchain detection & selection (msvc@sy…

…stem) — 0.0.88 (#208)

* docs(agents): MSVC system-toolchain detection design + implementation plan

* feat(toolchain): MSVC system-toolchain detection & selection (msvc@system) (0.0.88)

MSVC joins as the first *system* toolchain: mcpp locates and identifies an
installed Visual Studio / Build Tools (vswhere → env → well-known paths;
cl.exe banner → compiler version/arch, localization-tolerant) but never
installs or removes MSVC itself.

- toolchain default msvc: detect + report (VS product, VC tools, cl version,
  std.ixx availability), persist stable 'msvc@system'; absent → install
  guidance (VS Installer C++ workload / winget BuildTools), exit non-zero.
  msvc@<prefix> acts as pin-verify against the detected install.
- toolchain list: Windows 'System:' section; install msvc reports what's
  there or guides; remove msvc refuses (system component).
- self doctor: Windows 'msvc (system)' check section.
- manifest [toolchain] windows = "msvc@system" now actually works; msvc
  specs on non-Windows hosts error clearly.
- build: native cl.exe (.ifc) pipeline is gated off with one owned message
  pointing at llvm@20.1.7 (MSVC-ABI Clang) until it lands.
- detect(): cl.exe classification path (filename short-circuit, banner
  enrich); bmi_traits gains the MSVC .ifc branch.
- tests: unit (banner/guidance/spec/traits) + e2e 95 (Windows, requires msvc
  cap) / 96 (non-Windows rejection); run_all.sh msvc capability.
- design: .agents/docs/2026-07-13-msvc-system-toolchain-detection-design.md

* fix(e2e/ci): run msvc detection assertions from a neutral cwd

toolchain list stars the *effective* default; the repo root's mcpp.toml
[toolchain] windows=llvm@20.1.7 would shadow the freshly-set global
msvc@system when run_all.sh executes from the workspace.

* ci: run MSVC detection step before the LLVM self-host rebuild

The rebuild cleans target/, invalidating the job's $MCPP_SELF fingerprint
path — the MSVC step then failed with exit 127 (binary gone).

* fix(msvc): well-known-paths fallback covers major-version VS directories

windows-latest now installs VS under 'Microsoft Visual Studio\18\Enterprise'
(major version, not year branding) — vswhere finds it, but the strategy-3
path scan should too.

* fix(msvc): const ref when iterating path segments — libc++ yields temporaries

GCC/libstdc++ and Clang/MSVC-STL accepted 'auto&' here; Clang/libc++ (macOS
job) correctly rejects binding a non-const lvalue ref to the temporary.

v0.0.87

Toggle v0.0.87's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(config): don't inject official global xim index into project scop…

…e (0.0.87) (#205)

* fix(config): don't inject official global xim index into project scope

Project-local mode (a project with a custom `[indices]`, e.g. a local path
index) force-added the official `xim` index into the project's `.xlings.json`
`index_repos` (ensure_project_index_dir), intending to make `xim:*` deps
resolvable in project mode. But xlings scopes by which group a repo lands in:
packages from project `index_repos` are `PackageScope::Project`. So every `xim`
GLOBAL tool (cmake/glibc/gcc/make/binutils/…) resolved project-scoped and
installed into the project store instead of the shared registry. That broke ELF
loader resolution for build-dep tools — a build-dep `xim:cmake`'s interpreter was
patched to an unmaterialized project-store glibc → `cannot execute`. Any compat
package running a glibc-dynamic build-dep tool in install() (e.g. a source-built
CMake OpenCV) failed under `mcpp test`, universally (fresh MCPP_HOME too).

global IS the default: `xim` (and its dynamically-discovered sub-indexes) are
xlings global-default indices. `xim:*` resolves at global scope via the global
index_repos + the registry-local xim clone, and stays visible to the project via
additive. Only user-declared local custom indices are project-scoped. Remove the
xim injection and the project-data-dir xim exposure; not a hardcoded allowlist —
just don't inject an index the user didn't declare.

Verified: opencv workspace member closes (cmake now installs to the global
registry, project store holds only the local package); mcpp self-test 30/30;
mcpp-index full workspace green.

Design + analysis: .agents/docs/2026-07-09-project-index-scope-global-infra-fix.md
Bumps 0.0.86 → 0.0.87.

Claude-Session: https://claude.ai/code/session_01Y3KE7MAE8yV7BG35eXy7FV

* test(e2e): 52 asserts xim is NOT injected into project .xlings.json (matches fix)

The fake-xlings in 52_local_path_namespaced_index.sh asserted the OLD behavior
(project .xlings.json must contain the official xim index). Flip it: xim is a
global-default index and must NOT be injected project-scoped. Verified: e2e 52 OK.

Claude-Session: https://claude.ai/code/session_01Y3KE7MAE8yV7BG35eXy7FV

v0.0.86

Toggle v0.0.86's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
release: 0.0.86 — pipeline hardening (A4), unified macOS test stdlib …

…(A1), cross gcc16 floor (A2/R5a) (#203)

Version bump + remediation-doc live status. Ships on top of the merged
PRs #201 (verified gated mirroring) and #202 (static libc++ for test
binaries, llvm 22.1.8 green); this branch adds the aarch64 cross floor:
<triple>-gcc@16.1.0 (xim entry #344), retiring GCC 15 from the cross
path. The manifest instantiation anchor REMAINS for the x86_64 musl
release build (musl-gcc 15.1.0) until R5b packages its gcc 16.

v0.0.85

Toggle v0.0.85's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
0.0.85: descriptor grammar v2, xpkg parse (strict), scan_overrides + …

…ddi audit, index version floor (#200)

* feat(manifest): Lua long-bracket strings + block comments in xpkg descriptor reader

Descriptor grammar v2 (design: .agents/docs/2026-07-08-index-version-semantics-
and-descriptor-grammar-design.md D1):

- LuaCursor gains long_bracket_level_at / read_long_bracket / at_string_start;
  read_string accepts [[...]] / [=[...]=] with Lua first-newline stripping.
- skip_ws_and_comments / skip_table / read_table_body understand --[[ ]]
  block comments and long strings (content may contain braces).
- strip_lua_comments_and_strings blanks long-string content and block
  comments so the mcpp-segment locator's depth count stays correct.
- Unknown top-level mcpp-segment keys are now RECORDED (Manifest.
  xpkgUnknownKeys) instead of silently dropped — surfaced by the upcoming
  `mcpp xpkg parse`; `schema` becomes a known (informational) key.

Verified: 4 new unit tests (embedded ]], braces in content, decoy
`mcpp = {` inside block comment, CRLF/first-newline, unknown-key capture);
full `mcpp test` green; integration: mcpp-index fmtlib.fmt descriptor
rewritten with [==[ ]==] parses and its member test passes.

* feat(cli): mcpp xpkg parse — single-source-of-truth descriptor validation

`mcpp xpkg parse <file.lua> [--json] [--allow-unknown]` parses an xpkg
descriptor with EXACTLY the resolver's grammar (synthesize_from_xpkg_lua +
canonical identity), so index lint and user builds can never disagree
(design D2). Strict by default: unknown mcpp-segment keys exit 1 — they
would be silently ignored at build time; --allow-unknown downgrades to
warnings. --json emits identity, versions, and verbatim generated_files
contents (the lua5.4 parity oracle for descriptor migrations).

Verified: e2e 93_xpkg_parse (long brackets + block-comment decoy, JSON
round-trip byte-identical, unknown-key strictness both ways, malformed
segment fails); parity vs lua5.4 extraction on fmtlib.fmt = identical.

* refactor(manifest): split into :types / :toml / :xpkg partitions

manifest.cppm mixed three concerns in 2560 lines: the shared data model,
mcpp.toml parsing, and the xpkg .lua mcpp-segment reader. Now a directory
module with one data model and two independent surface grammars:

  src/manifest/manifest.cppm  primary — export import :types/:toml/:xpkg
  src/manifest/types.cppm     Manifest/Target/BuildConfig/errors + shared
                              helpers (module linkage, not exported)
  src/manifest/toml.cppm      parse_string/load/default_template
  src/manifest/xpkg.cppm      LuaCursor, identity, synthesize_from_xpkg_lua

Module name and exported API unchanged — zero importer churn. Full test
suite + e2e 93 green.

* feat(scanner): scan_overrides — author-asserted scan results bypass the text scan

For sha256-pinned third-party module units whose imports sit behind
preprocessor guards (fmt's official src/fmt.cc: #ifdef FMT_IMPORT_STD
import std;), the import set is a CONSTANT — recomputing it per build with
compiler processes is the wrong cost placement, and the M1 text scan must
reject it. Instead the descriptor asserts the scan result as data:

    scan_overrides = {
        ["*/src/fmt.cc"] = { provides = { "fmt" }, imports = { "std" } },
    }

Matched files skip scan_file(); the declared unit enters the graph with
scanOverridden=true (the flag plan-vs-ddi verification keys on). Both
surfaces parse it: xpkg mcpp segment and mcpp.toml [scan_overrides."glob"].
Every glob must match >=1 collected source (unmatched = loud error).
A unit may declare at most one provided module.

Verified: 3 unit tests (xpkg parse, empty-declaration reject, toml parse);
full suite green; end-to-end: mcpp-index fmtlib.fmt rewritten WITHOUT its
3.4KB generated_files copy — upstream fmt.cc verbatim + -DFMT_IMPORT_STD +
override — builds and its member test passes (import fmt; works).

Design: .agents/docs/2026-07-08-scanner-backend-abstraction-design.md §3-pre.

* feat(dyndep): plan-vs-ddi reconciliation — the compiler audits the planner

The .ddi (compiler's own P1689 scan under real flags) is the ground truth
of what phase 4 saw. ninja_backend now embeds the planner's per-TU
assumption on the dyndep edge (--expect-provides / --expect-imports /
--expect-none); `mcpp dyndep --single` compares and fails the edge on
divergence with both sides named. Mandatory for scan_overrides units (an
assertion needs its auditor); MCPP_VERIFY_MODGRAPH=1 at generation time
extends it to every module unit. Zero extra compiler invocations.

Verified: 3 unit tests; e2e negative — an fmt override deliberately
omitting imports={std} fails at DYNDEP with
  planned : provides [fmt] imports [<none>]
  compiler: provides [fmt] imports [std]
while the correct declaration builds green.

Design: .agents/docs/2026-07-08-scanner-backend-abstraction-design.md §3d.

* feat(pm): index.toml version contract — floor check at the index-open choke point

An index tree may carry index.toml ([index] spec / min_mcpp / latest_mcpp).
The contract travels WITH the tree, so ONE check in
read_identity_verified_xpkg_lua — the choke point every transport
converges on (artifact snapshot, git clone, [indices] path, CI-restored
cache) — covers all of them, offline included. own < min_mcpp → loud
E0006 with the upgrade one-liner, once per index per process, then the
resolve fails with the cause already printed. Missing index.toml → no
constraint (back-compat, third-party indices). Malformed versions never
brick a client. Escape hatch: MCPP_INDEX_FLOOR=ignore.

Deviation from design D3 noted: staged-unpack + atomic swap for the
artifact refresh lives in vendored xlings (separate codebase) — the
open-time check is the mcpp-side enforcement; staging is a follow-up
there.

Verified: 3 unit tests (ordering incl. 0.0.90>0.0.85, malformed/absent
tolerance, TOML round-trip); e2e on mcpp-index: min_mcpp=9.9.9 → E0006 +
resolve stop; =0.0.84 → builds; MCPP_INDEX_FLOOR=ignore bypasses.

Design: .agents/docs/2026-07-08-index-version-semantics-and-descriptor-
grammar-design.md D3.

* release: 0.0.85 — descriptor grammar v2, xpkg parse, scan_overrides, ddi audit, index floor

Version bump (mcpp.toml + MCPP_VERSION) and docs: [scan_overrides] section
in 05-mcpp-toml.md. One-time compatibility note for release notes:
mcpp-index will declare min_mcpp = 0.0.85 (index.toml floor) and start
using long-bracket descriptors + scan_overrides; pre-0.0.85 binaries
reading those descriptors fail to parse them — upgrade via install.sh.
From 0.0.85 on, the floor mechanism turns every future evolution into a
graceful keep-old-snapshot + upgrade hint instead of a parse error.

* docs(roadmap): live progress table for the 0.0.85 train

* fix(xpkg): survive the full mcpp-index corpus — 42/42 descriptors parse strict

Dry-running the new lint over every existing mcpp-index descriptor found
three gaps, all fixed:

- list_xpkg_versions only accepted double-quoted version keys; tensorvia's
  ['0.1.1'] spelling made its versions invisible. Accept both quotes.
- linux/macosx/windows per-platform sub-tables are KNOWN schema keys (the
  current platform's body is merged before the key loop); they no longer
  read as unknown on other platforms.
- Form A descriptors (no mcpp segment; build info from the source's own
  mcpp.toml) are a valid form: `xpkg parse` reports form A and passes
  instead of failing on the missing segment.

Corpus check: all 42 pkgs/*.lua in mcpp-index now pass `xpkg parse`
(strict) with zero warnings.

* fix(manifest): partitions -> separate modules + umbrella (GCC 15 cross link)

GCC 15 (the aarch64-linux-musl cross toolchain) drops implicit template
instantiations of module-attached types from partition object files —
undefined refs to std::map<..., ScanOverride>::map() etc. at final link.
Same split, same importer API, but as three plain modules re-exported by
an umbrella mcpp.manifest, the pattern the rest of the codebase already
links with everywhere. Shared parser helpers become exported (separate-
module visibility requires it).

* docs(roadmap): W6 findings — corpus dry-run catches, gcc15 partition workaround

* fix(manifest): GCC 15 cross-link — anchor member instantiations in the types module

GCC 15 (aarch64-linux-musl cross) does not emit implicit std::map/...
member instantiations of module-attached structs in importer objects; the
old single-file mcpp.manifest provided them by accident (its parser code
constructed every struct). A non-inline exported
force_template_instantiations() in mcpp.manifest.types recreates that
guarantee deliberately. Remove when the cross toolchain floor is GCC 16.

Verified locally: mcpp build --target aarch64-linux-musl with the same
xim gcc 15.1.0 toolchain links (static aarch64 ELF produced); native
build + full unit suite green.

* chore: ignore .cache/ (clangd index)

* ci(macos): discover the xlings LLVM version instead of hardcoding 20.1.7

xlings bumped its default llvm to 22.1.8; the hardcoded sandbox link path
and toolchain pin made the job fail at 'Configure dev mcpp sandbox'
deterministically. Discover the installed version from
~/.xlings/data/xpkgs/xim-x-llvm/*/ and thread it via MCPP_LLVM_VER.
(Install step keeps 'xlings install llvm -y || llvm@20.1.7' as fallback.)

* ci(macos): pin xlings llvm@20.1.7 (llvm 22.1.8 libc++ ABI link breakage)

xlings' default llvm moved to 22.1.8, whose libc++ headers reference
std::__1::__hash_memory — undefined at link on macOS (ld64.lld), failing
any gtest-using e2e (78_test_main_combinations). Pin the known-good
20.1.7 first, keep latest as fallback. Real fix (link against the
toolchain's own libc++) belongs to the hermetic-toolchain-link track
(.agents/docs/2026-07-07-hermetic-toolchain-link-model-design.md).
The version-discovery from the previous commit stays (picks whatever is
installed).