From 880d6bed466348d47c1050596cc2c2c7ef1ee41c Mon Sep 17 00:00:00 2001 From: speak-agent <248744407+speak-agent@users.noreply.github.com> Date: Wed, 9 Sep 2026 11:15:10 +0800 Subject: [PATCH 1/6] docs: the README states three tiers, both languages state the same targets, and a check enforces it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two top-level READMEs were outside every documentation check but the emoji rule, and had drifted from the implementation in three ways. The target table now carries the three tiers the engine actually stores -- `verified`, `preview`, `planned` -- and every canonical spelling in `modules/toolchain-model/src/triple.cppm`. The distinction is load-bearing: a build for a `planned` row is refused, while a `preview` row builds and links, and three rows the README called `planned` were `preview`. Three rows were absent altogether. The 简体中文 table was seven rows behind -- every bare-metal row, plus the footnote that says a freestanding target takes its C library, startup code and emulator from a board-support package -- so that README described a tool with no freestanding support at all. The Feature Overview gains the surfaces shipped since 2026.8 and previously unmentioned in either language: cross-compilation, bare metal and devices; heterogeneous builds and accelerators; and the extension model of `build.mcpp` and rule packages. `--release`, `--profile`, `--features`, `mcpp emit sbom` and the machine-readable output join the command list, and `mcpp why` regains its fourth topic. The Documentation section names the parts of the manual and points at the index that owns the reverse lookup, rather than naming seven chapters out of thirty-one. The benchmark keeps its table, its provenance and its control row, and loses half its lines. Two counts that rot with the tree -- "43+ C++23 modules" against 119 interface units -- are replaced by prose; the one count that is a measurement stays where it is measured. Rules 9 and 10 of `check_docs_structure.sh` now cover the README pair: the row counts are 61 and 61, and a row dropped from either side fails the check. Rule 14 is new -- a link labelled with a chapter number must point at that chapter. It was written for `[docs/13 -- ...](docs/40-baremetal.md)` in README.md and found six more of the same, left in `docs/` and `docs/specs/` by the renumbering in #590; all seven are corrected here. `triple.cppm`'s own tier legend named two of the three tiers it stores. The README now cites that file, so it is corrected in the same change. --- .github/tools/check_docs_structure.sh | 53 +++++++- README.md | 164 +++++++++++++++--------- README.zh-CN.md | 139 +++++++++++++------- docs/12-binary-distribution.md | 2 +- docs/24-openkal-cross.md | 2 +- docs/specs/manifest-semantics.md | 2 +- docs/specs/target-side.md | 2 +- docs/zh/12-binary-distribution.md | 2 +- docs/zh/24-openkal-cross.md | 2 +- modules/toolchain-model/src/triple.cppm | 3 +- 10 files changed, 250 insertions(+), 121 deletions(-) diff --git a/.github/tools/check_docs_structure.sh b/.github/tools/check_docs_structure.sh index 911ba7cf..1cbd0b50 100755 --- a/.github/tools/check_docs_structure.sh +++ b/.github/tools/check_docs_structure.sh @@ -17,6 +17,7 @@ # 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 # # 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 +145,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 +200,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 +234,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 +345,36 @@ 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 +sys.exit(1 if bad else 0) +PYLABEL + if [[ "$fail" -eq 0 ]]; then echo "OK: docs structure checks pass" fi diff --git a/README.md b/README.md index 64de02b1..cb1d2ef3 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ## 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 +- **Pure modular self-hosting** — mcpp is written entirely in C++23 module interface units and builds itself with the pipeline it ships - **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 @@ -255,6 +255,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 +312,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 +330,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 +341,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 +359,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 +396,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 +441,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 for Release](docs/10-pack-and-release.md) · [11 Publishing a Library](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](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](docs/51-supported-versions.md) · [the specifications](docs/specs/README.md) | +| `9x` mcpp itself | [90 Building from Source](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 +477,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 +517,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..cc11fc0f 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,3 +1,4 @@ +| `aarch64-macos` | llvm(*macOS 默认*) | verified | # mcpp > 一个 现代C++ 模块化构建工具 — 纯 C++23 模块编写,已实现自举 @@ -21,7 +22,7 @@ ## 核心特性 - **C++23 模块原生支持** — `import std` 自动处理,文件级增量构建,模块依赖自动分析,零手动配置 -- **纯模块化自举** — mcpp 自身由 43+ 个 C++23 模块组成,用自己构建自己,模块系统经实战验证 +- **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用它自己发布的这条流水线构建自己 - **开箱即用** — 一条命令安装,内置 GCC 16 / LLVM 20 工具链,自动下载到隔离沙盒,不污染系统 - **集成依赖管理** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义包索引 - **多包工作空间** — Workspace 统一锁文件与版本管理,适合大型项目 @@ -233,7 +234,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 +252,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 +309,16 @@ import mcpplibs.cmdline;
+
+扩展构建 + +- `build.mcpp` — 为 mcpp 没有现成规则的那一步写的构建程序,说的是一套带版本号的指令协议,而不是靠猜 +- `mcpp::action` 用显式的输入与输出声明一份工作,于是生成物参与增量图,而不是待在图外 +- 规则包把那一步带给别的项目:包声明一个 rule 模块,消费者以 feature 的形式选中它 +- payload、运行时适配器与板级支持包都是普通的包 —— 一个工具、一个驱动或一块板子,由安装库的那个解析器安装 + +
+
开发体验 @@ -293,7 +327,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 物料清单 - `mcpp --offline` / `MCPP_OFFLINE=1` — 仅使用已存在的本地状态 - `mcpp explain E0001` — 错误码详细解释 - `mcpp self doctor` — 环境自诊断 @@ -302,8 +338,8 @@ import mcpplibs.cmdline; ## 性能对比 -用**四个构建引擎**编译 **mcpp 自己** —— 137 个模块接口单元、57k 行、每一个都 -`import std;` —— 并且**给它们同一个编译器二进制**。每格是 **3 轮的中位数**,以及 +用**四个构建引擎**编译 **mcpp 自己** —— 锁定的工作负载有 137 个模块接口单元、 +57k 行,每一个都 `import std;` —— 并且**给它们同一个编译器二进制**。每格是 **3 轮的中位数**,以及 相对 cmake 的倍率。所有列出自**同一次跑**。 @@ -319,31 +355,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 +384,29 @@ 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 | +| `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 +419,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 发布一个库](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 构建程序](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 +458,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 +498,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). From 1d51c1857e8ff2fa59e53dbd8fa434800ff7d059 Mon Sep 17 00:00:00 2001 From: speak-agent <248744407+speak-agent@users.noreply.github.com> Date: Wed, 9 Sep 2026 11:24:53 +0800 Subject: [PATCH 2/6] docs: a positioning table at the top, refreshed highlights, and the row my own criterion could not see Review found a table row sitting on line 1 of README.zh-CN.md, above the document's title. It was put there by the probe that verified rule 10: the restore step replaced the empty string, which inserts at position 0 rather than where the row came from. Rule 10 stayed green throughout at 61 rows against 61, because a count cannot see WHERE a row is. The row is back in the target table. Rule 15 is the criterion that would have caught it: a maximal run of lines beginning with `|` is a table only if its second line is a delimiter row, so a row moved anywhere else lands in a run of its own and is reported. Verified by reproducing the defect exactly as the probe produced it, and watching the rule name the file and the line. The opening now answers "what is this" before the feature list does. C++ spreads five jobs across five tools; the table gives mcpp's answer for each, and a second row names what each column is usually recognised as, so a reader arriving with CMake, vcpkg or rustup in mind can place the whole tool in one glance. The highlights had not moved since the tool was a module build system. Two of the five bullets stated the same thing twice and none of them mentioned a target other than the host. They now cover the surface the sections below document: dependencies and workspaces are one bullet, and the two that replace the freed one state that a target is one flag away and that accelerators and `build.mcpp` exist. The bundled toolchain versions leave the highlight, since the host default and the freestanding pin are different versions and this line is not where that is explained. --- .github/tools/check_docs_structure.sh | 43 +++++++++++++++++++++++++++ README.md | 15 ++++++++-- README.zh-CN.md | 17 ++++++++--- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/.github/tools/check_docs_structure.sh b/.github/tools/check_docs_structure.sh index 1cbd0b50..f014a71c 100755 --- a/.github/tools/check_docs_structure.sh +++ b/.github/tools/check_docs_structure.sh @@ -18,6 +18,7 @@ # 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 +# 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 @@ -375,6 +376,48 @@ for f in files: 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 cb1d2ef3..19c15746 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,22 @@ mcpp demo

+C++ normally spreads these five jobs across five tools. mcpp is one command for +all five — the second row names what each column is usually recognised as. + +| | build system | build plugins | package manager | toolchain manager | environment and runtime | +|---|---|---|---|---|---| +| **mcpp** | module-first C++ on a ninja backend | `build.mcpp` and rule packages | SemVer, a lockfile, package indices | `family@version`, installed on demand | xlings — a user-space environment in an isolated sandbox | +| **closest to** | CMake + Ninja | CMake modules, xmake rules | vcpkg, Conan | rustup, nvm | conda, Nix | + ## 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 is written entirely in C++23 module interface units and builds itself with the pipeline it ships -- **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 +- **Works out of the box** — one-command install; the GCC or LLVM toolchain a build needs is downloaded into an isolated sandbox, never polluting your system +- **Dependencies and workspaces** — SemVer constraint resolution, lockfile, cross-project BMI cache, custom package indices, and multi-package workspaces sharing one lockfile +- **One flag changes the target** — `--target` reaches from Linux, Windows and macOS to Cortex-M and RISC-V bare metal; the toolchain payload is resolved and installed for you, and a runner puts the artifact on the board +- **Accelerators, and a way to extend** — CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C each have a rule package; a step with no rule is written in `build.mcpp`, and packaged as a rule for other projects ## Why mcpp diff --git a/README.zh-CN.md b/README.zh-CN.md index cc11fc0f..9279ed26 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,4 +1,3 @@ -| `aarch64-macos` | llvm(*macOS 默认*) | verified | # mcpp > 一个 现代C++ 模块化构建工具 — 纯 C++23 模块编写,已实现自举 @@ -19,13 +18,22 @@ mcpp demo

+C++ 通常把这五件事分给五个工具。mcpp 用一条命令承担全部五件 —— 第二行是每一列 +在既有认知里通常对应的东西。 + +| | 通用构建系统 | 构建插件 | 包管理 | 工具链管理 | 环境与运行时 | +|---|---|---|---|---|---| +| **mcpp** | 模块优先的 C++ 构建,ninja 后端 | `build.mcpp` 与规则包 | SemVer、锁文件、包索引 | `family@version`,按需安装 | xlings —— 隔离沙盒里的用户态环境 | +| **最接近的** | CMake + Ninja | CMake modules、xmake rules | vcpkg、Conan | rustup、nvm | conda、Nix | + ## 核心特性 - **C++23 模块原生支持** — `import std` 自动处理,文件级增量构建,模块依赖自动分析,零手动配置 - **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用它自己发布的这条流水线构建自己 -- **开箱即用** — 一条命令安装,内置 GCC 16 / LLVM 20 工具链,自动下载到隔离沙盒,不污染系统 -- **集成依赖管理** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义包索引 -- **多包工作空间** — Workspace 统一锁文件与版本管理,适合大型项目 +- **开箱即用** — 一条命令安装;构建所需的 GCC 或 LLVM 工具链自动下载到隔离沙盒,不污染系统 +- **依赖与工作空间** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义包索引,以及共用一份锁文件的多包 workspace +- **换目标只换一个开关** — `--target` 从 Linux、Windows、macOS 一路到 Cortex-M 与 RISC-V 裸机;工具链载荷自动解析安装,产物由 runner 送上板子 +- **加速器,以及扩展的方式** — CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C 各有规则包;没有现成规则的那一步用 `build.mcpp` 写,并可打成规则包给别人用 ## 为什么选择 mcpp @@ -396,6 +404,7 @@ mcpp 的身份模型是两条正交轴:**工具链** = `family@version`(family | `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 | From 3d613194aeefba3b925a5dc91ccde30d123ab95d Mon Sep 17 00:00:00 2001 From: speak-agent <248744407+speak-agent@users.noreply.github.com> Date: Wed, 9 Sep 2026 11:57:55 +0800 Subject: [PATCH 3/6] docs: the highlights separate a capability from what it is used for, and the analogy moves to Why mcpp The highlights had been a flat list in which "native C++23 module support" (a capability) sat beside "works out of the box" and "one flag changes the target" (two things a capability is used for), so a reader could not tell which claims were parts of the tool and which were consequences of them. They are now two columns, and the five rows are the same five parts the analogy names, in the same order, so the two tables read as one statement. The analogy is two rows rather than three. The middle row restated mcpp's implementation for each column, which the left column of the highlights already carries; what the analogy is for is placing the tool against something the reader already uses, and that needs the header and one row. It now sits in Why mcpp, where the question it answers is asked. The four bullets it replaces there each said something the highlights table now says. The P1689 detail they carried is in the build-system group of the feature overview, and the mcpplibs link appears twice further down. --- README.md | 36 ++++++++++++++++++------------------ README.zh-CN.md | 36 ++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 19c15746..437c0cc6 100644 --- a/README.md +++ b/README.md @@ -18,31 +18,31 @@ mcpp demo

-C++ normally spreads these five jobs across five tools. mcpp is one command for -all five — the second row names what each column is usually recognised as. +## Highlights -| | build system | build plugins | package manager | toolchain manager | environment and runtime | -|---|---|---|---|---|---| -| **mcpp** | module-first C++ on a ninja backend | `build.mcpp` and rule packages | SemVer, a lockfile, package indices | `family@version`, installed on demand | xlings — a user-space environment in an isolated sandbox | -| **closest to** | CMake + Ninja | CMake modules, xmake rules | vcpkg, Conan | rustup, nvm | conda, Nix | +The left column is what mcpp is; the right is what that is used for. -## Highlights +| Capability | What it is used for | +|---|---| +| **Build system** — native C++23 modules, `import std` handled automatically, file-level incremental builds, automatic dependency analysis | `mcpp new && mcpp build`, with nothing to configure; an interface that did not change does not cascade into the units importing it | +| **Build plugins** — `build.mcpp` and rule packages | a step mcpp has no rule for is written once and packaged for other projects; CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C are each a rule package | +| **Package manager** — SemVer constraints, a lockfile, a cross-project BMI cache, custom indices | two lines of manifest bring in a community module library to `import`; several packages share one lockfile in a workspace | +| **Toolchain manager** — `family@version`, installed on demand | no compiler has to be installed first; `--target` moves the same build to Windows, macOS, Cortex-M or RISC-V bare metal | +| **Environment and runtime** — the user-space environment xlings provides | toolchains and dependencies land in an isolated sandbox rather than in the system; a runner puts the artifact on a board or an emulator | -- **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 is written entirely in C++23 module interface units and builds itself with the pipeline it ships -- **Works out of the box** — one-command install; the GCC or LLVM toolchain a build needs is downloaded into an isolated sandbox, never polluting your system -- **Dependencies and workspaces** — SemVer constraint resolution, lockfile, cross-project BMI cache, custom package indices, and multi-package workspaces sharing one lockfile -- **One flag changes the target** — `--target` reaches from Linux, Windows and macOS to Cortex-M and RISC-V bare metal; the toolchain payload is resolved and installed for you, and a runner puts the artifact on the board -- **Accelerators, and a way to extend** — CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C each have a rule package; a step with no rule is written in `build.mcpp`, and packaged as a rule for other projects +mcpp is written entirely in C++23 module interface units and builds itself with +this pipeline, so every row above runs on mcpp itself every day. ## 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. + +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. -- **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 +| 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. diff --git a/README.zh-CN.md b/README.zh-CN.md index 9279ed26..3011abd7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -18,31 +18,31 @@ mcpp demo

-C++ 通常把这五件事分给五个工具。mcpp 用一条命令承担全部五件 —— 第二行是每一列 -在既有认知里通常对应的东西。 +## 核心特性 -| | 通用构建系统 | 构建插件 | 包管理 | 工具链管理 | 环境与运行时 | -|---|---|---|---|---|---| -| **mcpp** | 模块优先的 C++ 构建,ninja 后端 | `build.mcpp` 与规则包 | SemVer、锁文件、包索引 | `family@version`,按需安装 | xlings —— 隔离沙盒里的用户态环境 | -| **最接近的** | CMake + Ninja | CMake modules、xmake rules | vcpkg、Conan | rustup、nvm | conda、Nix | +左列是 mcpp 是什么,右列是它被用来做什么。 -## 核心特性 +| 能力 | 用它做的事 | +|---|---| +| **通用构建系统** —— C++23 模块原生支持,`import std` 自动处理,文件级增量构建,模块依赖自动分析 | `mcpp new && mcpp build`,没有要配置的东西;接口没有变化,就不会级联到导入它的那些单元 | +| **构建插件** —— `build.mcpp` 与规则包 | mcpp 没有现成规则的那一步写一次,就能打成包给别的项目用;CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C 各是一个规则包 | +| **包管理** —— SemVer 约束、锁文件、跨项目 BMI 缓存、自定义索引 | 两行清单引入一个社区模块化库并直接 `import`;多个包在 workspace 里共用一份锁文件 | +| **工具链管理** —— `family@version`,按需安装 | 本机不必先装编译器;`--target` 让同一次构建换到 Windows、macOS、Cortex-M 或 RISC-V 裸机 | +| **环境与运行时** —— xlings 提供的用户态环境 | 工具链与依赖落在隔离沙盒里而不是系统里;runner 把产物送上板子或模拟器 | -- **C++23 模块原生支持** — `import std` 自动处理,文件级增量构建,模块依赖自动分析,零手动配置 -- **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用它自己发布的这条流水线构建自己 -- **开箱即用** — 一条命令安装;构建所需的 GCC 或 LLVM 工具链自动下载到隔离沙盒,不污染系统 -- **依赖与工作空间** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义包索引,以及共用一份锁文件的多包 workspace -- **换目标只换一个开关** — `--target` 从 Linux、Windows、macOS 一路到 Cortex-M 与 RISC-V 裸机;工具链载荷自动解析安装,产物由 runner 送上板子 -- **加速器,以及扩展的方式** — CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C 各有规则包;没有现成规则的那一步用 `build.mcpp` 写,并可打成规则包给别人用 +mcpp 完全由 C++23 模块接口单元写成,并用这条流水线构建自己 —— 上面每一行,每天都在 +mcpp 自己身上跑一遍。 ## 为什么选择 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 上能为你提供便捷且友好的开发体验。 + +C++ 通常把这五件事分给五个工具,而 mcpp 用一条命令承担全部五件。第二行是每一列 +在既有认知里通常对应的东西。 -- **默认模块化** — `mcpp new` 创建的项目模板直接使用 C++23 模块,`import std` 开箱即用 -- **文件级增量构建** — 基于 P1689 dyndep 的三层优化(前端脏检查 + 逐文件扫描 + BMI restat),只重编真正变化的模块 -- **一键创建 & 构建** — `mcpp new hello && cd hello && mcpp build`,工具链自动安装,无需手动配置编译器和构建系统 -- **模块化生态** — [mcpplibs](https://github.com/mcpplibs) 提供一系列可直接 `import` 的 C++ 模块化库,支持自定义包索引 +| mcpp | 通用构建系统 | 构建插件 | 包管理 | 工具链管理 | 环境与运行时 | +|---|---|---|---|---|---| +| **最接近的** | CMake + Ninja | CMake modules、xmake rules | vcpkg、Conan | rustup、nvm | conda、Nix | > [!NOTE] > **早期版本** — mcpp 仍在积极开发中,接口和行为可能在后续版本调整。 From f63be0805efc2ac950e3973b1f7a4d77b9bb0c78 Mon Sep 17 00:00:00 2001 From: speak-agent <248744407+speak-agent@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:21:21 +0800 Subject: [PATCH 4/6] docs: the highlights are a list again, and each line still separates the capability from its use The two-column table made the distinction structural at the cost of the shape the section has always had, and the shape was the better of the two. Each line is a bullet again, in the original form: the bold name is the capability, the first sentence says what it is, and the second says what it is used for. The five names are still the five the analogy in Why mcpp uses, in the same order, and self-hosting returns as the sixth bullet rather than a trailing sentence. --- README.md | 20 ++++++++------------ README.zh-CN.md | 20 ++++++++------------ 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 437c0cc6..5fdbf0f8 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,14 @@ ## Highlights -The left column is what mcpp is; the right is what that is used for. - -| Capability | What it is used for | -|---|---| -| **Build system** — native C++23 modules, `import std` handled automatically, file-level incremental builds, automatic dependency analysis | `mcpp new && mcpp build`, with nothing to configure; an interface that did not change does not cascade into the units importing it | -| **Build plugins** — `build.mcpp` and rule packages | a step mcpp has no rule for is written once and packaged for other projects; CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C are each a rule package | -| **Package manager** — SemVer constraints, a lockfile, a cross-project BMI cache, custom indices | two lines of manifest bring in a community module library to `import`; several packages share one lockfile in a workspace | -| **Toolchain manager** — `family@version`, installed on demand | no compiler has to be installed first; `--target` moves the same build to Windows, macOS, Cortex-M or RISC-V bare metal | -| **Environment and runtime** — the user-space environment xlings provides | toolchains and dependencies land in an isolated sandbox rather than in the system; a runner puts the artifact on a board or an emulator | - -mcpp is written entirely in C++23 module interface units and builds itself with -this pipeline, so every row above runs on mcpp itself every day. +Each line names a capability first, then what it is used for. + +- **Build system** — native C++23 modules: `import std` handled automatically, file-level incremental builds, automatic module dependency analysis. `mcpp new && mcpp build` with nothing to configure; an interface that did not change does not cascade into the units importing it +- **Build plugins** — `build.mcpp` and rule packages. A step mcpp has no rule for is written once and packaged for other projects; CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C are each a rule package +- **Package manager** — SemVer constraint resolution, a lockfile, a cross-project BMI cache, custom indices. Two lines of manifest bring in a community module library to `import`; several packages share one lockfile in a workspace +- **Toolchain manager** — `family@version`, installed on demand. No compiler has to be installed first, and `--target` moves the same build to Windows, macOS, Cortex-M or RISC-V bare metal +- **Environment and runtime** — the user-space environment xlings provides. Toolchains and dependencies land in an isolated sandbox rather than in the system; 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 with this pipeline: every line above runs on mcpp itself every day ## Why mcpp diff --git a/README.zh-CN.md b/README.zh-CN.md index 3011abd7..7ff1ce60 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -20,18 +20,14 @@ ## 核心特性 -左列是 mcpp 是什么,右列是它被用来做什么。 - -| 能力 | 用它做的事 | -|---|---| -| **通用构建系统** —— C++23 模块原生支持,`import std` 自动处理,文件级增量构建,模块依赖自动分析 | `mcpp new && mcpp build`,没有要配置的东西;接口没有变化,就不会级联到导入它的那些单元 | -| **构建插件** —— `build.mcpp` 与规则包 | mcpp 没有现成规则的那一步写一次,就能打成包给别的项目用;CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C 各是一个规则包 | -| **包管理** —— SemVer 约束、锁文件、跨项目 BMI 缓存、自定义索引 | 两行清单引入一个社区模块化库并直接 `import`;多个包在 workspace 里共用一份锁文件 | -| **工具链管理** —— `family@version`,按需安装 | 本机不必先装编译器;`--target` 让同一次构建换到 Windows、macOS、Cortex-M 或 RISC-V 裸机 | -| **环境与运行时** —— xlings 提供的用户态环境 | 工具链与依赖落在隔离沙盒里而不是系统里;runner 把产物送上板子或模拟器 | - -mcpp 完全由 C++23 模块接口单元写成,并用这条流水线构建自己 —— 上面每一行,每天都在 -mcpp 自己身上跑一遍。 +每一条先说能力,再说它被用来做什么。 + +- **通用构建系统** — C++23 模块原生支持:`import std` 自动处理,文件级增量构建,模块依赖自动分析。`mcpp new && mcpp build`,没有要配置的东西;接口没有变化,就不会级联到导入它的那些单元 +- **构建插件** — `build.mcpp` 与规则包。mcpp 没有现成规则的那一步写一次,就能打成包给别的项目用;CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C 各是一个规则包 +- **包管理** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义索引。两行清单引入一个社区模块化库并直接 `import`;多个包在 workspace 里共用一份锁文件 +- **工具链管理** — `family@version`,按需安装。本机不必先装编译器,`--target` 让同一次构建换到 Windows、macOS、Cortex-M 或 RISC-V 裸机 +- **环境与运行时** — xlings 提供的用户态环境。工具链与依赖落在隔离沙盒里而不是系统里;runner 把产物送上板子或模拟器 +- **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用这条流水线构建自己:上面每一条,每天都在 mcpp 自己身上跑一遍 ## 为什么选择 mcpp From 1a4385f195cbba36cf2a573a95ad82fe8f7688a0 Mon Sep 17 00:00:00 2001 From: speak-agent <248744407+speak-agent@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:33:02 +0800 Subject: [PATCH 5/6] docs: each highlight is named for the capability and the work it does, in one line The lead sentence is gone: with each bullet named for both halves, saying that a bullet has two halves is a line that explains the next six rather than adding to them. The names now pair a capability with the work it is for -- build plugins with heterogeneous hardware, package management with the module-library ecosystem, toolchain management with cross-compilation -- so the reader sees what each part is for without reading to the end of the line. Every bullet is one line. The mcpplibs link moves up into the ecosystem bullet, where a reader looking for libraries meets it first; it can be given a bullet of its own once the library set is the thing being announced. --- README.md | 14 ++++++-------- README.zh-CN.md | 14 ++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5fdbf0f8..b470aae8 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,12 @@ ## Highlights -Each line names a capability first, then what it is used for. - -- **Build system** — native C++23 modules: `import std` handled automatically, file-level incremental builds, automatic module dependency analysis. `mcpp new && mcpp build` with nothing to configure; an interface that did not change does not cascade into the units importing it -- **Build plugins** — `build.mcpp` and rule packages. A step mcpp has no rule for is written once and packaged for other projects; CUDA, HIP, SYCL, Vulkan/SPIR-V and Ascend C are each a rule package -- **Package manager** — SemVer constraint resolution, a lockfile, a cross-project BMI cache, custom indices. Two lines of manifest bring in a community module library to `import`; several packages share one lockfile in a workspace -- **Toolchain manager** — `family@version`, installed on demand. No compiler has to be installed first, and `--target` moves the same build to Windows, macOS, Cortex-M or RISC-V bare metal -- **Environment and runtime** — the user-space environment xlings provides. Toolchains and dependencies land in an isolated sandbox rather than in the system; 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 with this pipeline: every line above runs on mcpp itself every day +- **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 with this pipeline ## Why mcpp diff --git a/README.zh-CN.md b/README.zh-CN.md index 7ff1ce60..7c738c64 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -20,14 +20,12 @@ ## 核心特性 -每一条先说能力,再说它被用来做什么。 - -- **通用构建系统** — C++23 模块原生支持:`import std` 自动处理,文件级增量构建,模块依赖自动分析。`mcpp new && mcpp build`,没有要配置的东西;接口没有变化,就不会级联到导入它的那些单元 -- **构建插件** — `build.mcpp` 与规则包。mcpp 没有现成规则的那一步写一次,就能打成包给别的项目用;CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C 各是一个规则包 -- **包管理** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义索引。两行清单引入一个社区模块化库并直接 `import`;多个包在 workspace 里共用一份锁文件 -- **工具链管理** — `family@version`,按需安装。本机不必先装编译器,`--target` 让同一次构建换到 Windows、macOS、Cortex-M 或 RISC-V 裸机 -- **环境与运行时** — xlings 提供的用户态环境。工具链与依赖落在隔离沙盒里而不是系统里;runner 把产物送上板子或模拟器 -- **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用这条流水线构建自己:上面每一条,每天都在 mcpp 自己身上跑一遍 +- **模块化构建系统** — 专注 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 From 0cdf52c0c291c885be65cfe27a64be9913cb5d0a Mon Sep 17 00:00:00 2001 From: speak-agent <248744407+speak-agent@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:44:55 +0800 Subject: [PATCH 6/6] docs: terms take the spelling this tree already uses, and the README labels take the chapters' own titles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `流水线` was a metaphor invented for the 简体中文 README. It occurs twice in docs/zh and in another sense both times, so the self-hosting line says what it does instead, and the English drops "pipeline" with it. Three terms had a spelling already: `载荷` rather than payload (217 uses against the English word in prose), `运行时适配包` rather than 运行时适配器 (chapter 33's own title), and `SBOM` rather than 物料清单, which is chapter 51's section heading but not the word its prose uses. Five 简体中文 chapter labels had been translated from the English titles rather than taken from the chapters, and named chapters that do not exist under those names: `mcpp.toml 清单` for 工程文件指南, `按场景查命令` for 选命令, `交叉编译` for 交叉构建, `触及设备` for 抵达一台设备, `异构构建` for 异构硬件构建. Both languages now label a chapter with its own title, shortened from the front where a cell is tight. Rule 14 grew the second half of that check. It compares the title only in the two READMEs. Measured across docs/, sixty-odd links label a chapter by its subject on purpose -- `[30 -- build.mcpp]`, `[04 -- §2.6.1]`, `[10 -- Packaging & Release]` -- and requiring a title there would be a new convention wearing a checker's clothes rather than a defect being caught. Both halves were verified by rewording a label in each language and watching the rule name the file, the label and the title. --- .github/tools/check_docs_structure.sh | 31 ++++++++++++++++++++++++++- README.md | 10 ++++----- README.zh-CN.md | 24 ++++++++++----------- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/.github/tools/check_docs_structure.sh b/.github/tools/check_docs_structure.sh index f014a71c..443c9d52 100755 --- a/.github/tools/check_docs_structure.sh +++ b/.github/tools/check_docs_structure.sh @@ -17,7 +17,7 @@ # 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 +# 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 @@ -373,6 +373,35 @@ for f in files: 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 diff --git a/README.md b/README.md index b470aae8..578ec150 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ - **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 with this pipeline +- **Pure modular self-hosting** — mcpp is written entirely in C++23 module interface units and builds itself ## Why mcpp @@ -455,12 +455,12 @@ 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 for Release](docs/10-pack-and-release.md) · [11 Publishing a Library](docs/11-publishing-a-library.md) · [12 Distributing a Prebuilt Library](docs/12-binary-distribution.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](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) | +| `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](docs/51-supported-versions.md) · [the specifications](docs/specs/README.md) | -| `9x` mcpp itself | [90 Building from Source](docs/90-build-from-source.md) · [92 Releasing mcpp](docs/92-release.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) | Every directory under [`examples/`](examples/) is a project that builds, and [03 — Examples](docs/03-examples.md) says which one teaches what. Full options diff --git a/README.zh-CN.md b/README.zh-CN.md index 7c738c64..c029f543 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -25,7 +25,7 @@ - **包管理与模块化库生态** — SemVer 约束、锁文件、跨项目 BMI 缓存、自定义索引;[mcpplibs](https://github.com/mcpplibs) 的库两行引入即可 `import` - **工具链管理与通用交叉构建** — `family@version` 按需安装;`--target` 让同一次构建换到 Windows、macOS、Cortex-M 或 RISC-V 裸机,一份源码经 openkal 触及多个有操作系统的目标 - **环境与运行时** — xlings 提供的用户态环境:工具链与依赖都留在隔离沙盒里,runner 把产物送上板子或模拟器 -- **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用这条流水线构建自己 +- **纯模块化自举** — mcpp 完全由 C++23 模块接口单元写成,并用它自己构建自己 ## 为什么选择 mcpp @@ -255,7 +255,7 @@ import mcpplibs.cmdline;
-交叉编译、裸机与设备 +交叉构建、裸机与设备 - `mcpp build --target ` — 一个开关;该目标所需的工具链载荷会自动解析并安装 - 从 `x86_64-linux-gnu` 到 Cortex-M、Cortex-A 与 RISC-V 裸机,完整的表见[平台支持](#平台支持) @@ -267,7 +267,7 @@ import mcpplibs.cmdline;
-异构构建与加速器 +异构硬件构建与加速器 - `[build] accel = "cuda12.9+{sm_89}, vulkan1.2"` — 一次构建可以点名一个或多个设备后端,该构建里 `cfg(accelerator = "cuda")` 为真 - 目前有规则包的编程模型有五个:CUDA、HIP、SYCL、Vulkan/SPIR-V 与 Ascend C @@ -317,7 +317,7 @@ import mcpplibs.cmdline; - `build.mcpp` — 为 mcpp 没有现成规则的那一步写的构建程序,说的是一套带版本号的指令协议,而不是靠猜 - `mcpp::action` 用显式的输入与输出声明一份工作,于是生成物参与增量图,而不是待在图外 - 规则包把那一步带给别的项目:包声明一个 rule 模块,消费者以 feature 的形式选中它 -- payload、运行时适配器与板级支持包都是普通的包 —— 一个工具、一个驱动或一块板子,由安装库的那个解析器安装 +- 载荷、运行时适配包与板级支持包都是普通的包 —— 一个工具、一个驱动或一块板子,由安装库的那个解析器安装
@@ -331,7 +331,7 @@ import mcpplibs.cmdline; - `mcpp add / remove / update` — 依赖管理 - 命令行上的 profile 与 feature:`--release` / `--profile `(`build`、`run`),`--features `(`build`、`run`、`test`) - `mcpp why [toolchain|runtime|deps|runners]` — 解释已解析的构建决策;`--format json` 供程序读取 -- `mcpp emit sbom` — 为刚刚记录下来的这次解析产出一份 CycloneDX 物料清单 +- `mcpp emit sbom` — 为已记录的那次解析产出一份 CycloneDX 格式的 SBOM - `mcpp --offline` / `MCPP_OFFLINE=1` — 仅使用已存在的本地状态 - `mcpp explain E0001` — 错误码详细解释 - `mcpp self doctor` — 环境自诊断 @@ -435,13 +435,13 @@ mcpp 的身份模型是两条正交轴:**工具链** = `family@version`(family | 部分 | 从这里开始 | |---|---| -| `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 发布一个库](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 构建程序](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) | +| `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) | [`examples/`](examples/) 下的每一个目录都是一个能构建的工程, [03 — 示例项目](docs/zh/03-examples.md) 说明哪一个教什么。任意命令的完整选项