diff --git a/.github/tools/check_docs_structure.sh b/.github/tools/check_docs_structure.sh index 911ba7cf..443c9d52 100755 --- a/.github/tools/check_docs_structure.sh +++ b/.github/tools/check_docs_structure.sh @@ -17,6 +17,8 @@ # 11. every chapter states its reader, its question and its exclusions # 12. a citation naming a section lands in the chapter that contains it # 13. every table the manifest reference documents is in the lookup index +# 14. a link labelled with a chapter number points at that chapter, by its title +# 15. every table row is inside a table # # What it deliberately does NOT check: whether a chapter documents what is # implemented, whether an assertion's strength matches its evidence, or whether @@ -144,13 +146,17 @@ for f in .agents/docs/[0-9]*.md; do || bad "$f: front matter declares no valid \`status\` (active | landed | superseded | abandoned)" done -# ── 9. every relative link in docs/ and examples/ resolves, fragment included ─ +# ── 9. every relative link in docs/, examples/ and the READMEs resolves ────── # # Rule 3 catches `docs/NN-*.md` named anywhere, including from source comments. # This is the other half: a Markdown link in a document that points at a file # which is not there. Both halves are needed -- a chapter moved in this batch # would satisfy one and break the other. # +# THE TWO TOP-LEVEL READMEs ARE IN THE SET. They are the entry point to every +# tree below them and they carry more relative links than most chapters, and +# until they were added here nothing checked one of those links at all. +# # THE FRAGMENT IS PART OF THE LINK. The first version of this rule discarded # it (`(?:#[^)]*)?`), so a link to a section that had been renamed resolved to # the file and was reported correct. Renaming 100 headings for register in one @@ -195,7 +201,9 @@ def anchors_of(path): out.add(s if n == 0 else f"{s}-{n}") return out -files = list(pathlib.Path("docs").rglob("*.md")) + list(pathlib.Path("examples").rglob("*.md")) +files = (list(pathlib.Path("docs").rglob("*.md")) + + list(pathlib.Path("examples").rglob("*.md")) + + [pathlib.Path("README.md"), pathlib.Path("README.zh-CN.md")]) cache = {} bad = 0 for f in files: @@ -227,11 +235,19 @@ PYCHECK # 简体中文 `[features]` section had no body at all, and 简体中文 §2.11 was # missing the `identity` verdict table. Both predate this check and both are # invisible to every other one. +# +# THE PAIR AT THE ROOT IS CHECKED TOO, AND IT IS WHERE THE COST WAS HIGHEST. +# `README.zh-CN.md` carried 14 target rows against the English 21: the seven it +# lacked were every bare-metal row, so a reader of the 简体中文 README saw a +# tool with no freestanding support at all. Heading count, code-block count and +# `
` count were all equal, which is why every other check was green. python3 - <<'PYPARITY' || fail=1 import pathlib, sys, re bad = 0 -for en in sorted(pathlib.Path("docs").glob("*.md")): - zh = pathlib.Path("docs/zh") / en.name +pairs = [(en, pathlib.Path("docs/zh") / en.name) + for en in sorted(pathlib.Path("docs").glob("*.md"))] +pairs.append((pathlib.Path("README.md"), pathlib.Path("README.zh-CN.md"))) +for en, zh in pairs: if not zh.exists(): continue def count(f): @@ -330,6 +346,107 @@ for k in missing: sys.exit(1 if missing else 0) PYLOOKUP +# ── 14. a link labelled with a chapter number points at that chapter ───────── +# +# Rule 3 checks that a named path exists and rule 9 that a link resolves. Both +# passed on `[docs/13 -- Bare-Metal and Freestanding Targets](docs/40-baremetal.md)` +# in README.md: the renumbering rewrote the path and left the label, so the +# README told its reader to read chapter 13 for eleven of the twenty-one rows +# in its own target table. A label that names a number is an assertion about +# where the reader is being sent, and it is checkable against the path. +python3 - <<'PYLABEL' || fail=1 +import re, pathlib, sys +LINK = re.compile(r"\[([^\]]+)\]\((?!https?:|mailto:)([^)\s#]+)(?:#[^)\s]+)?\)") +NUM = re.compile(r"(?:docs/|^|[^0-9a-zA-Z])(\d{2})(?:\s*(?:--|—|-|\s)|$)") +files = (list(pathlib.Path("docs").rglob("*.md")) + + [pathlib.Path("README.md"), pathlib.Path("README.zh-CN.md")]) +bad = 0 +for f in files: + for m in LINK.finditer(f.read_text(errors="ignore")): + label, path = m.group(1), m.group(2) + base = pathlib.Path(path).name + target_no = re.match(r"(\d{2})-", base) + label_no = NUM.match(label.strip()) + if not target_no or not label_no: + continue + if target_no.group(1) != label_no.group(1): + print(f"FAIL: {f}: label `{label}` names chapter " + f"{label_no.group(1)}, the link goes to {base}") + bad += 1 + continue + # The number agrees. In the two READMEs the label is also expected to + # carry the chapter's own title, because that is where a renumbering or + # a rename rots unseen and five 简体中文 labels were translated from the + # English titles rather than taken from the chapters. + # + # NOT IN docs/. Measured across the tree: sixty-odd links there label a + # chapter by its SUBJECT on purpose -- `[30 -- build.mcpp]`, + # `[04 -- \u00a72.6.1]`, `[10 -- Packaging & Release]` -- and that is a + # convention, not a defect. A check that would require editing all of + # them is imposing a new rule rather than enforcing an existing one. + if f.name not in ("README.md", "README.zh-CN.md"): + continue + said = label.strip()[label_no.end(1):].strip(" -\u2014\u2013:\uff1a") + if not said: + continue + target = (f.parent / path) if not path.startswith("docs/") else pathlib.Path(path) + if not target.is_file(): + continue + head = target.read_text(errors="ignore").split("\n")[0] + title = re.sub(r"^#\s*\d{2}\s*(?:\u2014\u2014|\u2014|--|-)?\s*", "", head).strip() + # A PREFIX rather than equality: shortening a title by dropping its tail + # is honest, and `[30 -- Build Programs]` for `Build Programs: + # \u0060build.mcpp\u0060` is the shape that takes. Words the chapter does not + # use are what this rejects -- a label translated from the other + # language's title rather than taken from the chapter's own. + if title and not title.startswith(said): + print(f"FAIL: {f}: label says `{said}`, chapter {base} is titled `{title}`") + bad += 1 +sys.exit(1 if bad else 0) +PYLABEL + +# ── 15. every table row is inside a table ─────────────────────────────────── +# +# Rule 10 counts a translation's table rows, and a COUNT cannot see WHERE a row +# is. One row of the target table was moved to line 1 of README.zh-CN.md, above +# the document's own title, and rule 10 stayed green at 61 rows against 61: the +# row was still in the file. What a reader saw was a stray table row before the +# heading, and only a reader saw it. +# +# The check is positional rather than numeric: a maximal run of lines beginning +# with `|` is a table only if its second line is a delimiter row. A row that has +# been moved somewhere else lands in a run of its own and has no delimiter. +python3 - <<'PYROW' || fail=1 +import re, pathlib, sys +DELIM = re.compile(r"^\|[\s:|-]+\|?\s*$") +files = (list(pathlib.Path("docs").rglob("*.md")) + + [pathlib.Path("README.md"), pathlib.Path("README.zh-CN.md")]) +bad = 0 +for f in files: + lines, infence, run = f.read_text(errors="ignore").split("\n"), False, [] + def close(run): + global bad + if not run: + return + if len(run) < 2 or not DELIM.match(run[1][1]): + n, text = run[0] + print(f"FAIL: {f}:{n}: a table row outside a table: {text[:60]}") + bad += 1 + for n, line in enumerate(lines, 1): + if line.startswith("```"): + infence = not infence + close(run); run = [] + continue + if infence: + continue + if line.startswith("|"): + run.append((n, line)) + else: + close(run); run = [] + close(run) +sys.exit(1 if bad else 0) +PYROW + if [[ "$fail" -eq 0 ]]; then echo "OK: docs structure checks pass" fi diff --git a/README.md b/README.md index 64de02b1..578ec150 100644 --- a/README.md +++ b/README.md @@ -20,20 +20,23 @@ ## Highlights -- **Native C++23 module support** — `import std` handled automatically, file-level incremental builds, automatic module dependency analysis, zero manual configuration -- **Pure modular self-hosting** — mcpp itself consists of 43+ C++23 modules and builds itself; the module pipeline is battle-tested -- **Works out of the box** — one-command install, bundled GCC 16 / LLVM 20 toolchains downloaded into an isolated sandbox, never polluting your system -- **Integrated dependency management** — SemVer constraint resolution, lockfile, cross-project BMI cache, custom package indices -- **Multi-package workspaces** — unified lockfile and version management for larger projects +- **Modular build system** — C++ modules first: `import std` handled automatically, file-level incremental builds, automatic dependency analysis, nothing to configure +- **Build plugins and heterogeneous hardware** — `build.mcpp` and rule packages extend the build; CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C are each a rule package +- **Package management and a module-library ecosystem** — SemVer constraints, lockfile, cross-project BMI cache, custom indices; a library from [mcpplibs](https://github.com/mcpplibs) is two lines away from `import` +- **Toolchain management and cross-compilation** — `family@version` installed on demand; `--target` moves the same build to Windows, macOS, Cortex-M or RISC-V bare metal, and one source tree reaches several hosted targets over openkal +- **Environment and runtime** — the user-space environment xlings provides: toolchains and dependencies stay in an isolated sandbox, and a runner puts the artifact on a board or an emulator +- **Pure modular self-hosting** — mcpp is written entirely in C++23 module interface units and builds itself ## Why mcpp -mcpp is built specifically for **C++23 module-first development**. If you want to use `import std`, module interface units (`.cppm`), module partitions, and other modern C++ features in your project, mcpp gives you a smooth, friendly experience on Linux, macOS ARM64, and Windows x86_64: +mcpp is built specifically for **C++23 module-first development**. If you want to use `import std`, module interface units (`.cppm`), module partitions, and other modern C++ features in your project, mcpp gives you a smooth, friendly experience on Linux, macOS ARM64, and Windows x86_64. -- **Modular by default** — projects created by `mcpp new` use C++23 modules directly; `import std` just works -- **File-level incremental builds** — three-layer optimization based on P1689 dyndep (front-end dirty check + per-file scanning + BMI restat); only the modules that actually changed get recompiled -- **Create & build in one go** — `mcpp new hello && cd hello && mcpp build`; toolchains install automatically, no compiler or build-system setup required -- **A modular ecosystem** — [mcpplibs](https://github.com/mcpplibs) offers a growing set of directly `import`-able C++ module libraries, plus support for custom package indices +C++ normally spreads these five jobs across five tools, and mcpp is one command +for all five. The second row names what each column is usually recognised as. + +| mcpp | build system | build plugins | package manager | toolchain manager | environment and runtime | +|---|---|---|---|---|---| +| **closest to** | CMake + Ninja | CMake modules, xmake rules | vcpkg, Conan | rustup, nvm | conda, Nix | > [!NOTE] > **Early-stage project** — mcpp is under active development; interfaces and behavior may change in future releases. @@ -255,6 +258,29 @@ import mcpplibs.cmdline;
+
+Cross-compilation, bare metal and devices + +- `mcpp build --target ` — one flag; the toolchain payload for that target is resolved and installed automatically +- Targets from `x86_64-linux-gnu` to Cortex-M, Cortex-A and RISC-V bare metal; the full table is under [Platform Support](#platform-support) +- Freestanding targets carry no operating system: the C library, startup code, memory layout and emulator travel with a board-support package rather than with mcpp +- Runners reach an artifact that cannot run on the build machine — `mcpp run --runner flash`, `--list-runners`, `mcpp why runners` +- `mcpp new --template riscv-virt-rt` — a board template a package ships, instantiated by name +- Cross-compilation over openkal: a portable program builds for a target whose kernel interface and C library come from packages + +
+ +
+Heterogeneous builds and accelerators + +- `[build] accel = "cuda12.9+{sm_89}, vulkan1.2"` — a build names one or more device backends, and `cfg(accelerator = "cuda")` is true in that build +- Five programming models have rule packages today: CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C +- Device translation units are compiled by their own compiler and join the ordinary link; the host/device boundary is generated rather than written twice +- A constrained glob selects device sources: `{ glob = "src/kernels/**/*.cu", accel = "cuda12.9+{sm_89}" }` +- Nothing in the engine holds a vendor name, so a sixth backend is a package rather than an engine change + +
+
Package & dependency management @@ -289,6 +315,16 @@ import mcpplibs.cmdline;
+
+Extending the build + +- `build.mcpp` — a build program for a step mcpp has no rule for, speaking a directive protocol that is versioned rather than guessed +- `mcpp::action` declares work with explicit inputs and outputs, so a generated file takes part in the incremental graph instead of sitting outside it +- A rule package carries that step to other projects: it declares a rule module, and a consumer selects it as a feature +- Payloads, runtime adapters and board-support packages are ordinary packages — a tool, a driver or a board is installed by the resolver that installs a library + +
+
Developer experience @@ -297,7 +333,9 @@ import mcpplibs.cmdline; - `mcpp test [pattern] [-- args]` — auto-discover and run tests (filter by name; `--list`, `--timeout `, `--message-format json`) - `mcpp search` — search package indices - `mcpp add / remove / update` — dependency management -- `mcpp why [toolchain|runtime|deps]` — explain resolved build decisions +- Profiles and features on the command line: `--release` / `--profile ` on `build` and `run`, `--features ` on `build`, `run` and `test` +- `mcpp why [toolchain|runtime|deps|runners]` — explain resolved build decisions; `--format json` for a machine reader +- `mcpp emit sbom` — a CycloneDX bill of materials for the resolution just recorded - `mcpp --offline` / `MCPP_OFFLINE=1` — use only already available local state - `mcpp explain E0001` — detailed error-code explanations - `mcpp self doctor` — environment self-diagnosis @@ -306,10 +344,10 @@ import mcpplibs.cmdline; ## Benchmark -Building **mcpp itself** — 137 module interface units, 57k lines, every one of -them `import std;` — with four engines handed the **same compiler binary**. -Each cell is the median of **3 samples** and how many times faster it is than -cmake. Every column comes from **one run**. +Building **mcpp itself** — 137 module interface units and 57k lines at the +pinned workload, every one of them `import std;` — with four engines handed the +**same compiler binary**. Each cell is the median of **3 samples** and how many +times faster it is than cmake. Every column comes from **one run**. | scenario | `mcpp` | `mcpp +opt` | `mcpp (old)` | `cmake` | `xmake` | @@ -324,38 +362,29 @@ cmake. Every column comes from **one run**.
`mcpp` = mcpp@2026.8.13.1, the build under test · `mcpp +opt` = the SAME binary as `mcpp`, with the opt-in key `[build] bmi_schedule = "on"` (off by default) · `mcpp (old)` = mcpp@2026.8.11.3, the previously published release.
Linux x86_64 · i9-13900K · gcc 16.1.0 · n=3 · pinned workload `a749e9f` · -cmake 4.4.2 / xmake 3.1.0 · `-` would mean not measured, and there is none here · -min/max sit within 4% of every median above 1s · +cmake 4.4.2 / xmake 3.1.0 · min/max sit within 4% of every median above 1s · data: [`standard-20260814-linux-x86_64`](bench/results/standard-20260814-linux-x86_64/). * **Cascade suppression accounts for the `touch-hub` and `edit-comment` rows.** - cmake and xmake decide by timestamp and rebuild every downstream unit. mcpp + cmake and xmake decide by timestamp and rebuild every downstream unit; mcpp compares the BMI the compiler has just produced against the previous one and skips the cascade when the interface is unchanged. This is default behaviour - and requires no configuration. The `mcpp (old)` column measures the previous - release at 81.72s, level with cmake, so the effect is new in this revision. -* **`edit-body` measures the case where the cascade is genuinely owed** — and - whether an edit owes one depends on where the body lives: - - | the function body is in… | editing it | this row | - |---|---|---| - | a `.cppm`, and the edit **moves lines** | GCC records declaration positions, so the BMI changes → cascade owed | **what is measured: 1.1x, and 2.9x with `+opt`** | - | a `.cppm`, edited **in place** (same line count) | GCC does not serialise non-template bodies → BMI unchanged → no cascade | ~200x, like `touch-hub` | - | a separate `.cpp` implementation unit | that file has no BMI at all → no cascade, on every compiler | ~200x | - - The perturbation here inserts a statement, so it takes the first row: every - engine has to rebuild the importers, and one that did not would be skipping - work. `+opt` does not skip it either — it does the same work 2.9x faster. - Splitting interface from implementation is the sturdiest of the three, because - it does not depend on GCC's body handling or on avoiding line shifts. - Measured in + and requires no configuration. `mcpp (old)` measures the previous release at + 81.72s, level with cmake, so the effect is new in this revision. +* **`edit-body` is the control, and mcpp is deliberately not fast on it.** The + perturbation inserts a statement into an interface unit, which moves the + source positions GCC records, so the BMI changes and every importer is owed a + rebuild — an engine that were fast on that row would be skipping work it owes. + Whether an edit owes a cascade depends on where the body lives: an in-place + edit of the same length, or a body in a separate `.cpp`, owes none and lands + near the 200x rows. Measured in [`.agents/docs/2026-08-15-module-edit-granularity.md`](.agents/docs/2026-08-15-module-edit-granularity.md). * **`bmi_schedule` is opt-in and disabled by default** (`auto` resolves to off). - It moves code generation off the critical path, so it helps only where a - cascade is required: `cold` 86.69s → 35.73s, `edit-body` 80.87s → 29.83s. On - the two rows where mcpp already skips the cascade it yields no improvement. - An incorrect scheduling change fails silently rather than loudly, so the - default is not changed on the evidence of a single machine. + It moves code generation off the critical path, so it pays only where a + cascade is owed — `cold` 86.69s → 35.73s, `edit-body` 80.87s → 29.83s, and + nothing on the two rows mcpp already skips. An incorrect scheduling change + fails silently rather than loudly, so the default is not changed on the + evidence of a single machine. **[Methodology, pinned versions, and the full data → `bench/README.md`](bench/README.md)** · [简体中文](bench/README.zh-CN.md) @@ -370,29 +399,31 @@ the right toolchain payload is resolved and installed automatically. **Hosts** (where mcpp itself runs): Linux x86_64 / aarch64, macOS arm64, Windows x86_64. -**Targets** (what `--target` accepts; this table mirrors the in-code vocabulary): +**Targets** (what `--target` accepts; the rows and their tiers are the ones in +`modules/toolchain-model/src/triple.cppm`, which is also what `mcpp toolchain +list` reports for this machine): -| Target | Convention toolchain | Status | +| Target | Convention toolchain | Tier | |---|---|:---:| -| `x86_64-linux-gnu` | gcc *(Linux default)* or llvm | yes | -| `x86_64-linux-musl` | gcc 16, fully static | yes | -| `aarch64-linux-musl` | gcc 16, fully static — cross from x86_64 (qemu-verified) or native | yes | -| `x86_64-windows-gnu` | gcc 16 MinGW-w64 — native on Windows, cross from Linux (wine-verified) *(Windows default without Visual Studio)* | yes | -| `x86_64-windows-msvc` | `msvc@system` (detected VS/BuildTools) or llvm ¹ *(Windows default with Visual Studio)* | yes | -| `aarch64-macos` | llvm *(macOS default)* | yes | -| `riscv64-none-elf` | llvm 22 — bare metal, no OS; needs no per-host cross payload ² | yes | -| `riscv32-none-elf` | llvm 22 — bare metal, no OS; needs no per-host cross payload ² | yes | -| `thumbv6m-none-eabi` | llvm 22 — Cortex-M0/M0+/M1, bare metal ² | yes | -| `thumbv7m-none-eabi` | llvm 22 — Cortex-M3, bare metal ² | yes | -| `thumbv7em-none-eabihf` | llvm 22 — Cortex-M4F/M7F, hard float ² | yes | -| `thumbv8m.main-none-eabi` | llvm 22 — Cortex-M33/M55, soft float ² | yes | -| `armv7a-none-eabi` · `armv7a-none-eabihf` | llvm 22 — Cortex-A 32-bit, bare metal ² | yes | -| `thumbv7em-none-eabi` · `thumbv8m.base-none-eabi` · `thumbv8m.main-none-eabihf` | llvm 22 — builds and links; no emulator run recorded | planned | -| `riscv64-linux-musl` | — | planned | -| `aarch64-linux-gnu` | — | planned | -| `x86_64-macos` | — | planned | - -verified — CI builds **and executes** the artifact end-to-end (qemu/wine included) | planned +| `x86_64-linux-gnu` | gcc *(Linux default)* or llvm | verified | +| `x86_64-linux-musl` | gcc 16, fully static | verified | +| `aarch64-linux-musl` | gcc 16, fully static — cross from x86_64 (qemu) or native | verified | +| `x86_64-windows-gnu` | gcc 16 MinGW-w64 — native on Windows, cross from Linux (wine) *(Windows default without Visual Studio)* | verified | +| `x86_64-windows-msvc` | `msvc@system` (detected VS/BuildTools) or llvm ¹ *(Windows default with Visual Studio)* | verified | +| `x86_64-windows-musl` | llvm 22 — a PE with a musl C library, which no gcc emits; the system comes from the dependency graph | preview | +| `aarch64-macos` | llvm *(macOS default)* | verified | +| `riscv64-none-elf` · `riscv32-none-elf` | llvm 22 — bare metal, `xim:picolibc-riscv` ² | verified | +| `thumbv6m-none-eabi` · `thumbv7m-none-eabi` | llvm 22 — Cortex-M0/M0+/M1, Cortex-M3 ² | verified | +| `thumbv7em-none-eabihf` · `thumbv8m.main-none-eabi` | llvm 22 — Cortex-M4F/M7F hard float, Cortex-M33/M55 soft float ² | verified | +| `armv7a-none-eabi` · `armv7a-none-eabihf` | llvm 22 — Cortex-A 32-bit, the first row with an MMU ² | verified | +| `aarch64-none-elf` · `x86_64-none-elf` | llvm 22 — bare metal, no C library by default ² | preview | +| `thumbv7em-none-eabi` · `thumbv8m.base-none-eabi` · `thumbv8m.main-none-eabihf` | llvm 22 — Cortex-M4/M7 soft float, M23, M33F/M55F ² | preview | +| `riscv64-linux-musl` · `aarch64-linux-gnu` · `x86_64-macos` | — | planned | + +`verified` an image has been built **and run** for the row, qemu and wine +included · `preview` it builds and links, and no emulator run has been recorded +· `planned` registered in the vocabulary and nothing wired yet — a build for +such a target is refused rather than attempted. > Linux release binaries are fully static musl builds for x86_64 and aarch64 > (`x86_64-linux-musl` and `aarch64-linux-musl`). @@ -413,19 +444,27 @@ verified — CI builds **and executes** the artifact end-to-end (qemu/wine inclu > cross-compilers by construction, so any host that can install the LLVM > payload produces these targets. The C library, startup code, memory layout > and emulator travel with a board-support package rather than with mcpp — see -> [docs/13 — Bare-Metal and Freestanding Targets](docs/40-baremetal.md). +> [40 — Bare-Metal and Freestanding Targets](docs/40-baremetal.md). ## Documentation -- [Getting Started](docs/01-getting-started.md) — install → new → build → run in 5 minutes -- [Examples](docs/03-examples.md) -- [Packaging & Release](docs/10-pack-and-release.md) -- [Toolchain Management](docs/20-toolchains.md) -- [Building from Source](docs/90-build-from-source.md) -- [mcpp.toml Guide](docs/04-mcpp-toml.md) -- [Workspaces](docs/07-workspace.md) +[`docs/`](docs/README.md) is the manual. A chapter's first digit says which part +it belongs to, and the index carries the reverse lookup — from a manifest key or +a command in front of a reader, to the chapter that owns it. + +| Part | Start at | +|---|---| +| `0x` fundamentals | [01 Getting Started](docs/01-getting-started.md) · [04 The mcpp.toml Manifest](docs/04-mcpp-toml.md) · [09 Commands by Scenario](docs/09-commands-by-scenario.md) | +| `1x` publishing | [10 Packaging an Application for Release](docs/10-pack-and-release.md) · [11 Publishing a Library to mcpp-index](docs/11-publishing-a-library.md) · [12 Distributing a Prebuilt Library](docs/12-binary-distribution.md) | +| `2x` toolchains and targets | [20 Toolchain Management](docs/20-toolchains.md) · [21 The Target Triple](docs/21-the-target-triple.md) · [24 Cross-Compilation Over openkal](docs/24-openkal-cross.md) | +| `3x` extending mcpp | [30 Build Programs: `build.mcpp`](docs/30-build-mcpp.md) · [31 Authoring a Rule Package](docs/31-authoring-a-rule-package.md) · [34 Authoring a Board-Support Package](docs/34-authoring-a-bsp.md) | +| `4x` devices and accelerators | [40 Bare-Metal and Freestanding Targets](docs/40-baremetal.md) · [41 Reaching a Device](docs/41-devices.md) · [42 Heterogeneous Builds](docs/42-heterogeneous-builds.md) | +| `5x` contracts for programs | [50 Machine-Readable Output](docs/50-machine-output.md) · [51 Supported Versions and Compatibility](docs/51-supported-versions.md) · [the specifications](docs/specs/README.md) | +| `9x` mcpp itself | [90 Building from Source and Contributing](docs/90-build-from-source.md) · [92 Releasing mcpp](docs/92-release.md) | -Full options for any command are available via `mcpp --help`. +Every directory under [`examples/`](examples/) is a project that builds, and +[03 — Examples](docs/03-examples.md) says which one teaches what. Full options +for any command are available via `mcpp --help`. **AI-assisted learning**: send the following prompt to an AI coding assistant to get up to speed with mcpp quickly: @@ -441,8 +480,8 @@ Real projects built with mcpp — `import`-able C++23 modules and the toolchain | Project | Description | | --- | --- | -| [mcpp](https://github.com/mcpp-community/mcpp) | mcpp itself — 43+ C++23 modules, fully self-hosted | -| [xlings](https://github.com/openxlings/xlings) | Toolchain & package-management foundation mcpp builds on | +| [mcpp](https://github.com/mcpp-community/mcpp) | mcpp itself — written in C++23 modules, fully self-hosted | +| [xlings](https://github.com/openxlings/xlings) | Toolchain and package-management foundation mcpp builds on | | [tinyhttps](https://github.com/mcpplibs/tinyhttps) | Minimal C++23 HTTP/HTTPS client with SSE streaming | | [llmapi](https://github.com/mcpplibs/llmapi) | Modern C++ LLM API client (OpenAI-compatible) | | [imgui-m](https://github.com/mcpplibs/imgui-m) | Dear ImGui as a C++23 module package | @@ -481,7 +520,7 @@ then follow the guide to help me submit a contribution to mcpp. Dependencies and sources of inspiration: -- [xlings](https://github.com/d2learn/xlings) — toolchain / package-management foundation +- [xlings](https://github.com/openxlings/xlings) — toolchain / package-management foundation - [mcpplibs.cmdline](https://github.com/mcpplibs/cmdline) — CLI framework - [ninja](https://github.com/ninja-build/ninja) — underlying build engine - [xmake](https://github.com/xmake-io/xmake) — cross-platform build tool diff --git a/README.zh-CN.md b/README.zh-CN.md index c2e374f3..c029f543 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -20,20 +20,23 @@ ## 核心特性 -- **C++23 模块原生支持** — `import std` 自动处理,文件级增量构建,模块依赖自动分析,零手动配置 -- **纯模块化自举** — mcpp 自身由 43+ 个 C++23 模块组成,用自己构建自己,模块系统经实战验证 -- **开箱即用** — 一条命令安装,内置 GCC 16 / LLVM 20 工具链,自动下载到隔离沙盒,不污染系统 -- **集成依赖管理** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义包索引 -- **多包工作空间** — Workspace 统一锁文件与版本管理,适合大型项目 +- **模块化构建系统** — 专注 C++ 模块:`import std` 自动处理,文件级增量构建,模块依赖自动分析,零手动配置 +- **构建插件与异构硬件编程** — `build.mcpp` 与规则包扩展构建;CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C 各是一个规则包 +- **包管理与模块化库生态** — SemVer 约束、锁文件、跨项目 BMI 缓存、自定义索引;[mcpplibs](https://github.com/mcpplibs) 的库两行引入即可 `import` +- **工具链管理与通用交叉构建** — `family@version` 按需安装;`--target` 让同一次构建换到 Windows、macOS、Cortex-M 或 RISC-V 裸机,一份源码经 openkal 触及多个有操作系统的目标 +- **环境与运行时** — xlings 提供的用户态环境:工具链与依赖都留在隔离沙盒里,runner 把产物送上板子或模拟器 +- **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用它自己构建自己 ## 为什么选择 mcpp -mcpp 专门为 **C++23 模块化开发** 打造。如果你想在项目中使用 `import std`、模块接口单元(`.cppm`)、模块分区等现代 C++ 特性,mcpp 在 Linux、macOS ARM64 和 Windows x86_64 上能为你提供便捷且友好的开发体验: +mcpp 专门为 **C++23 模块化开发** 打造。如果你想在项目中使用 `import std`、模块接口单元(`.cppm`)、模块分区等现代 C++ 特性,mcpp 在 Linux、macOS ARM64 和 Windows x86_64 上能为你提供便捷且友好的开发体验。 -- **默认模块化** — `mcpp new` 创建的项目模板直接使用 C++23 模块,`import std` 开箱即用 -- **文件级增量构建** — 基于 P1689 dyndep 的三层优化(前端脏检查 + 逐文件扫描 + BMI restat),只重编真正变化的模块 -- **一键创建 & 构建** — `mcpp new hello && cd hello && mcpp build`,工具链自动安装,无需手动配置编译器和构建系统 -- **模块化生态** — [mcpplibs](https://github.com/mcpplibs) 提供一系列可直接 `import` 的 C++ 模块化库,支持自定义包索引 +C++ 通常把这五件事分给五个工具,而 mcpp 用一条命令承担全部五件。第二行是每一列 +在既有认知里通常对应的东西。 + +| mcpp | 通用构建系统 | 构建插件 | 包管理 | 工具链管理 | 环境与运行时 | +|---|---|---|---|---|---| +| **最接近的** | CMake + Ninja | CMake modules、xmake rules | vcpkg、Conan | rustup、nvm | conda、Nix | > [!NOTE] > **早期版本** — mcpp 仍在积极开发中,接口和行为可能在后续版本调整。 @@ -233,7 +236,7 @@ import mcpplibs.cmdline; - 三层增量优化:前端脏检查 + 逐文件 P1689 dyndep + BMI copy-if-different restat - 指纹化 BMI 缓存:按编译器/标志/标准库哈希,跨项目共享 - Ninja 后端:自动生成 build.ninja,并行编译 -- compile_commands.json 自动生成(clangd / ccls 即用) +- compile_commands.json 自动生成(clangd / ccls 即用);`mcpp build --configure-only` 可在编译普通源码之前先刷新它 - C 语言一等支持:`.c` 文件自动检测,混合 C/C++ 项目 - 用户自定义 cflags / cxxflags / ldflags / c_standard @@ -251,6 +254,29 @@ import mcpplibs.cmdline;
+
+交叉构建、裸机与设备 + +- `mcpp build --target ` — 一个开关;该目标所需的工具链载荷会自动解析并安装 +- 从 `x86_64-linux-gnu` 到 Cortex-M、Cortex-A 与 RISC-V 裸机,完整的表见[平台支持](#平台支持) +- freestanding 目标不带操作系统:C 库、启动代码、内存布局与模拟器随板级支持包走,而不随 mcpp 走 +- runner 用来触及构建机器上跑不了的产物 —— `mcpp run --runner flash`、`--list-runners`、`mcpp why runners` +- `mcpp new --template riscv-virt-rt` — 由包自带的板级模板,按名字实例化 +- 基于 openkal 的交叉编译:一个可移植程序,为内核接口与 C 库都来自包的目标构建 + +
+ +
+异构硬件构建与加速器 + +- `[build] accel = "cuda12.9+{sm_89}, vulkan1.2"` — 一次构建可以点名一个或多个设备后端,该构建里 `cfg(accelerator = "cuda")` 为真 +- 目前有规则包的编程模型有五个:CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C +- 设备翻译单元由它自己的编译器编译,产物进入普通链接;主机与设备之间的边界是生成的,不是写两遍的 +- 带约束的 glob 用来挑出设备源码:`{ glob = "src/kernels/**/*.cu", accel = "cuda12.9+{sm_89}" }` +- 引擎里不含任何厂商名,因此第六个后端是一个包,而不是一次引擎改动 + +
+
包管理与依赖 @@ -285,6 +311,16 @@ import mcpplibs.cmdline;
+
+扩展构建 + +- `build.mcpp` — 为 mcpp 没有现成规则的那一步写的构建程序,说的是一套带版本号的指令协议,而不是靠猜 +- `mcpp::action` 用显式的输入与输出声明一份工作,于是生成物参与增量图,而不是待在图外 +- 规则包把那一步带给别的项目:包声明一个 rule 模块,消费者以 feature 的形式选中它 +- 载荷、运行时适配包与板级支持包都是普通的包 —— 一个工具、一个驱动或一块板子,由安装库的那个解析器安装 + +
+
开发体验 @@ -293,7 +329,9 @@ import mcpplibs.cmdline; - `mcpp test [pattern] [-- args]` — 自动发现并运行测试(按名字过滤;`--list`、`--timeout `、`--message-format json`) - `mcpp search` — 搜索包索引 - `mcpp add / remove / update` — 依赖管理 -- `mcpp why [toolchain|runtime|deps]` — 解释已解析的构建决策 +- 命令行上的 profile 与 feature:`--release` / `--profile `(`build`、`run`),`--features `(`build`、`run`、`test`) +- `mcpp why [toolchain|runtime|deps|runners]` — 解释已解析的构建决策;`--format json` 供程序读取 +- `mcpp emit sbom` — 为已记录的那次解析产出一份 CycloneDX 格式的 SBOM - `mcpp --offline` / `MCPP_OFFLINE=1` — 仅使用已存在的本地状态 - `mcpp explain E0001` — 错误码详细解释 - `mcpp self doctor` — 环境自诊断 @@ -302,8 +340,8 @@ import mcpplibs.cmdline; ## 性能对比 -用**四个构建引擎**编译 **mcpp 自己** —— 137 个模块接口单元、57k 行、每一个都 -`import std;` —— 并且**给它们同一个编译器二进制**。每格是 **3 轮的中位数**,以及 +用**四个构建引擎**编译 **mcpp 自己** —— 锁定的工作负载有 137 个模块接口单元、 +57k 行,每一个都 `import std;` —— 并且**给它们同一个编译器二进制**。每格是 **3 轮的中位数**,以及 相对 cmake 的倍率。所有列出自**同一次跑**。 @@ -319,31 +357,23 @@ import mcpplibs.cmdline;
`mcpp` = mcpp@2026.8.13.1,被测的这一版 · `mcpp +优化` = **和 `mcpp` 同一个二进制**,开了 opt-in 的 `[build] bmi_schedule = "on"`(默认关闭) · `mcpp (旧版)` = mcpp@2026.8.11.3,上一个已发布版。
Linux x86_64 · i9-13900K · gcc 16.1.0 · n=3 · 锁定的工作负载 `a749e9f` · -cmake 4.4.2 / xmake 3.1.0 · `-` 表示未测,本表没有 · -所有大于 1s 的中位数 min/max 都在 ±4% 以内 · +cmake 4.4.2 / xmake 3.1.0 · 所有大于 1s 的中位数 min/max 都在 ±4% 以内 · 数据:[`standard-20260814-linux-x86_64`](bench/results/standard-20260814-linux-x86_64/)。 * **`touch-hub` 与 `edit-comment` 两行由级联抑制决定。** cmake 与 xmake 按时间戳判断,重编全部下游单元;mcpp 将编译器刚产出的 BMI 与上 一份比较,接口未变则不触发级联。这是默认行为,无需任何配置。`mcpp (旧版)` 一列 测得上一个发布版为 81.72s,与 cmake 同量级,因此该效果在本版本中才生效。 -* **`edit-body` 量的是级联确实欠着的那种改动** —— 一次改动欠不欠级联,取决于函数体 - 写在哪里: - - | 函数体所在 | 改动它 | 对应本行 | - |---|---|---| - | `.cppm`,且改动**移动了行号** | GCC 在 BMI 里记录声明位置,BMI 随之改变 → 欠级联 | **本行所测:1.1x,`+优化` 2.9x** | - | `.cppm`,**原地等长**修改 | GCC 不序列化非模板函数体 → BMI 不变 → 不级联 | 约 200x,与 `touch-hub` 同档 | - | 独立的 `.cpp` 实现单元 | 该文件根本不产生 BMI → 不级联,且跨编译器成立 | 约 200x | - - 这里的扰动插入一条语句,因此落在第一行:所有引擎都必须重建导入者,更快只能意味着 - 漏做。`+优化` 也不漏做,只是把同一份工作加快 2.9 倍。三者中**接口与实现分离最稳**, - 因为它既不依赖 GCC 对函数体的处理方式,也不依赖你避免行号移动。实测见 +* **`edit-body` 是对照行,mcpp 在这一行有意不快。** 扰动往接口单元里插入一条语句, + GCC 记录的声明位置随之移动,BMI 因而改变,每一个导入者都欠一次重建 —— 在这一行 + 跑得快的引擎,漏掉的是它欠下的工作。一次改动欠不欠级联取决于函数体写在哪里: + 原地等长的修改,或者写在独立 `.cpp` 里的函数体,都不欠级联,落在约 200x 的那一档。 + 实测见 [`.agents/docs/2026-08-15-module-edit-granularity.md`](.agents/docs/2026-08-15-module-edit-granularity.md)。 * **`bmi_schedule` 为 opt-in,默认关闭**(`auto` 解析为 off)。它将代码生成移出关键 - 路径,因此仅在级联必需时有效:`cold` 86.69s → 35.73s、`edit-body` 80.87s → - 29.83s;而在 mcpp 本已跳过级联的两行上没有收益。调度错误的表现是静默失效而非 - 报错,因此不以单台机器的证据变更默认值。 + 路径,因此只在级联确实欠着时才有收益 —— `cold` 86.69s → 35.73s、`edit-body` + 80.87s → 29.83s,而在 mcpp 本已跳过级联的两行上没有收益。调度错误的表现是静默 + 失效而非报错,因此不以单台机器的证据变更默认值。 **[方法、锁定的版本、完整数据 → `bench/README.zh-CN.md`](bench/README.zh-CN.md)** · [English](bench/README.md) @@ -356,22 +386,30 @@ mcpp 的身份模型是两条正交轴:**工具链** = `family@version`(family **宿主**(mcpp 本身运行在哪):Linux x86_64 / aarch64、macOS arm64、Windows x86_64。 -**目标**(`--target` 接受什么;本表与代码内词汇表同源): +**目标**(`--target` 接受什么;表里的行与它们的档位取自 +`modules/toolchain-model/src/triple.cppm`,也就是 `mcpp toolchain list` 为本机 +报告的那一份): -| Target | 约定工具链 | 状态 | +| Target | 约定工具链 | 档位 | |---|---|:---:| -| `x86_64-linux-gnu` | gcc(*Linux 默认*)或 llvm | 是 | -| `x86_64-linux-musl` | gcc 16,全静态 | 是 | -| `aarch64-linux-musl` | gcc 16,全静态——x86_64 交叉(qemu 实测)或原生 | 是 | -| `x86_64-windows-gnu` | gcc 16 MinGW-w64——Windows 原生,Linux 交叉(wine 实测)(*无 Visual Studio 时的 Windows 默认*) | 是 | -| `x86_64-windows-msvc` | `msvc@system`(探测 VS/BuildTools)或 llvm ¹(*有 Visual Studio 时的 Windows 默认*) | 是 | -| `aarch64-macos` | llvm(*macOS 默认*) | 是 | -| `thumbv7em-none-eabi` · `thumbv8m.base-none-eabi` · `thumbv8m.main-none-eabihf` | llvm 22——可构建可链接;未记录模拟器运行 | 计划中 | -| `riscv64-linux-musl` | — | 计划中 | -| `aarch64-linux-gnu` | — | 计划中 | -| `x86_64-macos` | — | 计划中 | - -是——CI 端到端构建**并真实执行**产物(含 qemu/wine)| 计划中——尚未验证 +| `x86_64-linux-gnu` | gcc(*Linux 默认*)或 llvm | verified | +| `x86_64-linux-musl` | gcc 16,全静态 | verified | +| `aarch64-linux-musl` | gcc 16,全静态——x86_64 交叉(qemu)或原生 | verified | +| `x86_64-windows-gnu` | gcc 16 MinGW-w64——Windows 原生,Linux 交叉(wine)(*无 Visual Studio 时的 Windows 默认*) | verified | +| `x86_64-windows-msvc` | `msvc@system`(探测 VS/BuildTools)或 llvm ¹(*有 Visual Studio 时的 Windows 默认*) | verified | +| `x86_64-windows-musl` | llvm 22——带 musl C 库的 PE,没有 gcc 能产出它;系统由依赖图供给 | preview | +| `aarch64-macos` | llvm(*macOS 默认*) | verified | +| `riscv64-none-elf` · `riscv32-none-elf` | llvm 22——裸机,`xim:picolibc-riscv` ² | verified | +| `thumbv6m-none-eabi` · `thumbv7m-none-eabi` | llvm 22——Cortex-M0/M0+/M1、Cortex-M3 ² | verified | +| `thumbv7em-none-eabihf` · `thumbv8m.main-none-eabi` | llvm 22——Cortex-M4F/M7F 硬浮点、Cortex-M33/M55 软浮点 ² | verified | +| `armv7a-none-eabi` · `armv7a-none-eabihf` | llvm 22——Cortex-A 32 位,第一条带 MMU 的行 ² | verified | +| `aarch64-none-elf` · `x86_64-none-elf` | llvm 22——裸机,默认不带 C 库 ² | preview | +| `thumbv7em-none-eabi` · `thumbv8m.base-none-eabi` · `thumbv8m.main-none-eabihf` | llvm 22——Cortex-M4/M7 软浮点、M23、M33F/M55F ² | preview | +| `riscv64-linux-musl` · `aarch64-linux-gnu` · `x86_64-macos` | — | planned | + +`verified` 该行的镜像已被构建**并运行**过,qemu 与 wine 都算 · `preview` 可构建 +可链接,未记录过模拟器运行 · `planned` 已登记在词表中,尚未接线 —— 面向这类目标 +的构建会被拒绝,而不是被尝试。 > Linux release 二进制为 x86_64 与 aarch64 的 musl 全静态构建 > (`x86_64-linux-musl` 与 `aarch64-linux-musl`)。 @@ -384,18 +422,30 @@ mcpp 的身份模型是两条正交轴:**工具链** = `family@version`(family > 完全自包含、不需要 Visual Studio、`import std` 可用。无需安装或配置,裸 Windows 上 > `mcpp new && mcpp build` 直接可用。而 `mcpp.toml` 里显式写的 `[toolchain]` 永远按你 > 写的执行——mcpp 只修正自己选的默认值,不改你的。 +> +> ² 裸机的那些行不带操作系统:clang 与 lld 天生就是交叉编译器,因此任何能安装 +> LLVM 载荷的宿主都能产出这些目标。C 库、启动代码、内存布局与模拟器随板级支持包 +> 走,而不随 mcpp 走 —— 见 +> [40 — 裸机与 freestanding 目标](docs/zh/40-baremetal.md)。 ## 文档 -- [快速开始](docs/zh/01-getting-started.md) — 5 分钟完成 install → new → build → run -- [示例项目](docs/zh/03-examples.md) -- [发布打包](docs/zh/10-pack-and-release.md) -- [工具链管理](docs/zh/20-toolchains.md) -- [从源码构建](docs/zh/90-build-from-source.md) -- [mcpp.toml 指南](docs/zh/04-mcpp-toml.md) -- [工作空间](docs/zh/07-workspace.md) +[`docs/zh/`](docs/zh/README.md) 是手册。章节号的第一位说明它属于哪一部分;索引 +另有一份反向查表 —— 从读者眼前的一个 manifest 键或一条命令,查到拥有它的那一章。 + +| 部分 | 从这里开始 | +|---|---| +| `0x` 基础 | [01 快速开始](docs/zh/01-getting-started.md) · [04 mcpp.toml 工程文件指南](docs/zh/04-mcpp-toml.md) · [09 按场景选命令](docs/zh/09-commands-by-scenario.md) | +| `1x` 发布 | [10 发布打包](docs/zh/10-pack-and-release.md) · [11 发布一个库到 mcpp-index](docs/zh/11-publishing-a-library.md) · [12 分发预编译库](docs/zh/12-binary-distribution.md) | +| `2x` 工具链与目标 | [20 工具链管理](docs/zh/20-toolchains.md) · [21 目标三元组](docs/zh/21-the-target-triple.md) · [24 基于 openkal 的交叉构建](docs/zh/24-openkal-cross.md) | +| `3x` 扩展 mcpp | [30 构建程序:`build.mcpp`](docs/zh/30-build-mcpp.md) · [31 编写规则包](docs/zh/31-authoring-a-rule-package.md) · [34 编写板级支持包](docs/zh/34-authoring-a-bsp.md) | +| `4x` 设备与加速器 | [40 裸机与 freestanding 目标](docs/zh/40-baremetal.md) · [41 抵达一台设备](docs/zh/41-devices.md) · [42 异构硬件构建](docs/zh/42-heterogeneous-builds.md) | +| `5x` 给程序的契约 | [50 机器可读输出](docs/zh/50-machine-output.md) · [51 受支持的版本与兼容性](docs/zh/51-supported-versions.md) · [规范](docs/specs/README.md) | +| `9x` mcpp 自身 | [90 从源码构建与参与贡献](docs/zh/90-build-from-source.md) · [92 发布 mcpp](docs/zh/92-release.md) | -任意命令的完整选项可通过 `mcpp --help` 查阅。 +[`examples/`](examples/) 下的每一个目录都是一个能构建的工程, +[03 — 示例项目](docs/zh/03-examples.md) 说明哪一个教什么。任意命令的完整选项 +可通过 `mcpp --help` 查阅。 **AI 辅助学习**:你可以将以下提示词发给 AI 编码助手,让它帮你快速了解 mcpp: @@ -411,7 +461,7 @@ mcpp 的身份模型是两条正交轴:**工具链** = `family@version`(family | 项目 | 说明 | | --- | --- | -| [mcpp](https://github.com/mcpp-community/mcpp) | mcpp 自身 —— 43+ 个 C++23 模块,完全自举 | +| [mcpp](https://github.com/mcpp-community/mcpp) | mcpp 自身 —— 由 C++23 模块写成,完全自举 | | [xlings](https://github.com/openxlings/xlings) | mcpp 依赖的工具链与包管理底座 | | [tinyhttps](https://github.com/mcpplibs/tinyhttps) | 极简 C++23 HTTP/HTTPS 客户端,支持 SSE 流式 | | [llmapi](https://github.com/mcpplibs/llmapi) | 现代 C++ LLM API 客户端(OpenAI 兼容) | @@ -451,7 +501,7 @@ mcpp 的身份模型是两条正交轴:**工具链** = `family@version`(family 项目依赖和灵感来源: -- [xlings](https://github.com/d2learn/xlings) — 工具链 / 包管理底座 +- [xlings](https://github.com/openxlings/xlings) — 工具链 / 包管理底座 - [mcpplibs.cmdline](https://github.com/mcpplibs/cmdline) — CLI 框架 - [ninja](https://github.com/ninja-build/ninja) — 底层构建引擎 - [xmake](https://github.com/xmake-io/xmake) — 跨平台构建工具 diff --git a/docs/12-binary-distribution.md b/docs/12-binary-distribution.md index 6b44891f..15b2e1be 100644 --- a/docs/12-binary-distribution.md +++ b/docs/12-binary-distribution.md @@ -320,7 +320,7 @@ no test in this suite produces a `.dylib` to measure the edit on. ### Debug information is removed -See [docs/02](10-pack-and-release.md) for the flags, the per-shape table, and +See [docs/10](10-pack-and-release.md) for the flags, the per-shape table, and `--debug-symbols`. The rule that matters for a *library* package: a static archive is only ever `--strip-debug`ed, because `--strip-all` removes the archive symbol index and the consumer's link then fails with `archive has no diff --git a/docs/24-openkal-cross.md b/docs/24-openkal-cross.md index 14ac6f31..e48a22a1 100644 --- a/docs/24-openkal-cross.md +++ b/docs/24-openkal-cross.md @@ -313,7 +313,7 @@ the paths where a project overrides the contract explicitly. ## Reference -[docs/14 — The Target Side](22-target-side.md) for the five layers, the four +[docs/22 — The Target Side](22-target-side.md) for the five layers, the four origins and the rules. [SPEC-002](specs/target-side.md) for the normative statement of the capability grammar. diff --git a/docs/specs/manifest-semantics.md b/docs/specs/manifest-semantics.md index 2854fe0d..fcc9f411 100644 --- a/docs/specs/manifest-semantics.md +++ b/docs/specs/manifest-semantics.md @@ -10,7 +10,7 @@ | **最低实现版本** | 条件化形状:mcpp **2026.8.29.1**(`[target..build-dependencies]` 起齐备);目标轴:mcpp **2026.9.6.4** | | **作者/维护** | mcpp-community | | **相关设计文档** | `.agents/docs/2026-09-07-mcpp-toml-unified-semantics-design.md`
`.agents/docs/2026-06-04-manifest-schema-ownership.md`
`.agents/docs/2026-09-03-xlings-workspace-as-the-one-table.md` | -| **相关使用文档** | [docs/05 —— mcpp.toml 字段参考](../04-mcpp-toml.md) | +| **相关使用文档** | [docs/04 —— mcpp.toml 字段参考](../04-mcpp-toml.md) | ## 规范用语 diff --git a/docs/specs/target-side.md b/docs/specs/target-side.md index d17eac9c..b4a837eb 100644 --- a/docs/specs/target-side.md +++ b/docs/specs/target-side.md @@ -8,7 +8,7 @@ | 最后修改 | 2026-08-24 | | 对应实现 | mcpp >= 2026.8.24.2 | | 相关设计文档 | `.agents/docs/2026-08-24-target-side-design.md` | -| 使用文档 | [docs/14 - 目标侧](../zh/22-target-side.md) | +| 使用文档 | [docs/22 - 目标侧](../zh/22-target-side.md) | 本规范定义一次构建的目标侧由哪些层构成、每一层可以由谁供给、 供给者与需求者如何声明,以及引擎据此执行的规则。 diff --git a/docs/zh/12-binary-distribution.md b/docs/zh/12-binary-distribution.md index 48ca5c7a..9030f58a 100644 --- a/docs/zh/12-binary-distribution.md +++ b/docs/zh/12-binary-distribution.md @@ -286,7 +286,7 @@ Mach-O 上打包器会读出 `LC_RPATH` 并在包会携带它时告警;自动改 ### 调试信息会被剥掉 -参数、分档表与 `--debug-symbols` 见 [docs/02](10-pack-and-release.md)。 +参数、分档表与 `--debug-symbols` 见 [docs/10](10-pack-and-release.md)。 对**库**包最要紧的一条:静态归档只做 `--strip-debug`,因为 `--strip-all` 会删掉 归档的符号索引,消费方链接时会报 `archive has no index; run ranlib to add one`。 diff --git a/docs/zh/24-openkal-cross.md b/docs/zh/24-openkal-cross.md index 632291dc..91257635 100644 --- a/docs/zh/24-openkal-cross.md +++ b/docs/zh/24-openkal-cross.md @@ -265,6 +265,6 @@ g++: error: unrecognized command-line option '-fuse-ld=…/ld.lld' ## 参考 -[docs/14 — 目标侧](22-target-side.md) 给出五个层、四种来源与规则。 +[docs/22 — 目标侧](22-target-side.md) 给出五个层、四种来源与规则。 [SPEC-002](../specs/target-side.md) 给出能力语法的规范性陈述。 diff --git a/modules/toolchain-model/src/triple.cppm b/modules/toolchain-model/src/triple.cppm index 8b01aa08..2a605a65 100644 --- a/modules/toolchain-model/src/triple.cppm +++ b/modules/toolchain-model/src/triple.cppm @@ -199,10 +199,11 @@ std::optional parse(std::string_view s); // // tier semantics (Rust-style): // verified — CI builds AND executes the artifact end-to-end (qemu/wine count) +// preview — it builds and links; no execution has been recorded for the row // planned — registered intent; payload or CI row not wired yet struct TargetInfo { std::string_view canonical; // "x86_64-linux-musl" - std::string_view tier; // "verified" | "planned" + std::string_view tier; // "verified" | "preview" | "planned" std::string_view note; // display annotation: "static" / "PE" / "" // Convention toolchain pin for `--target ` with no explicit // [target.X] toolchain override. Empty = no convention (host default).