Skip to content

Commit 640e8bc

Browse files
committed
docs: sync with 2026.8.3.4 — ZH windows→linux section, artifact naming, correct the pin-checker claim
Review of #348 against the current tree (2026.8.3.4, three releases newer than when the sync was written). Four things needed adjusting. 1. The ZH toolchain doc was missing THREE sections the EN one has, including the whole `x86_64-linux-musl`-from-Windows feature (2026.8.3.2). A Chinese reader had no way to learn that Windows can produce Linux ELF at all. Added, mirroring EN: "Windows 上产出 Linux ELF", "MSVC(系统工具链,Windows)", and the Clang 20+ operator-template hazard. EN/ZH are now at 16 sections each, and every other doc pair already matched. The EN section's claims were re-derived from `toolchain::host_can_serve` before translating: Windows serves linux targets only when musl AND same arch, which is exactly "no x86_64-linux-gnu, no cross-arch". Both languages now also state the fact that function makes explicit and the docs omitted — **a macOS host has no Linux-targeting payload at all** — and point at `mcpp toolchain list` as the authority so nobody has to memorize the matrix. 2. Artifact naming, undocumented since 2026.8.3.3 changed it. `kind = "lib"` for `x86_64-windows-gnu` produces `libfoo.a`, not `foo.lib`: the static-lib convention splits on the triple's *env* segment, not its OS. That release fixed a name that was wrong (a GNU archive wearing an MSVC name, which MSVC cannot consume), so anyone globbing `*.lib` out of a mingw build needs to know. Added as a table to both languages. 3. `docs/spec/package-identity.md` carried "当前实现为 2026.8.3.2" — already stale two releases later. A spec should not restate a value that expires on every release; the minimum-implementation version (0.0.106) is the load bearing one and it is still there. Dropped the parenthetical rather than bumping it, so it cannot go stale again. 4. **`check_version_pins.sh` does not have a Bash syntax error.** It parses (`bash -n`), runs, and exits 0 — verified on this tree. The failure is `sh check_version_pins.sh`: the script uses process substitution (`done < <(...)`), which dash cannot parse, so it reports "line 95: Syntax error: redirection unexpected". That is the invoking shell, not the script — its shebang is `#!/usr/bin/env bash` and CI invokes it as bash. This mattered enough to chase down because the claim appeared in six places across three files, each instructing the releaser to skip the guard and check pins by hand. That guard is the only machine check for pin drift, and pin drift has broken releases here before. All six now show the correct invocation and explain the sh-vs-bash trap instead. Also noted the cache-entry layout change from 2026.8.3.4 in the `[build] cache` section (both languages): entry layout is versioned, an upgrade that changes it retires older entries and the next build repopulates — nothing to clean by hand. The PR's other two findings were re-verified against the source and are correct: `kind = "shared"` really is refused off Linux/ELF (plan.cppm:513), and `[build].cxx_runtime` really is parsed but missing from `kKnownBuildKeys` — the allowlist's own comment says it "MUST stay in sync with the doc->get_* reads", and it is not. Left as-is; this PR touches no source.
1 parent 43587ae commit 640e8bc

8 files changed

Lines changed: 222 additions & 28 deletions

File tree

.agents/skills/mcpp-release/SKILL.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,19 @@ mcpp 有 **三个持久化版本位置**,以及 `ci-fresh-install` 的一个
4747
Release 推导一次,所有安装 job 消费同一个输出。绝不能手工编辑或恢复字面量
4848
`MCPP_PIN`,否则 index guard 和实际安装版本会再次漂移。
4949

50-
`.github/tools/check_version_pins.sh` 的目标是校验版本关系和 xlings pin;但当前版本在
51-
第 95 行有 Bash 语法错误,不能把它的执行当成有效验证。修复该实现前,手工核对
52-
`mcpp.toml``MCPP_VERSION` 相等、`.xlings.json` 不领先于正在构建的版本;也不要
53-
通过修改文档或 workflow 绕开动态 `MCPP_PIN` 设计。`src/xlings.cppm`
50+
`.github/tools/check_version_pins.sh` 校验版本关系和 xlings pin:
51+
52+
```bash
53+
bash .github/tools/check_version_pins.sh
54+
```
55+
56+
**必须用 `bash` 跑,不能用 `sh`** 脚本用了进程替换(`done < <(...)`),POSIX
57+
`sh`/dash 解析不了,用 `sh` 调用会在第 95 行附近报 `Syntax error: redirection
58+
unexpected`。那是调用它的 shell 的问题,不是脚本的缺陷 —— 它的 shebang 是
59+
`#!/usr/bin/env bash`,CI 也是用 `bash` 调的。别据此把这条 guard 当成坏的而跳过:
60+
它是唯一能机器化捕捉 pin 漂移的东西。
61+
62+
也不要通过修改文档或 workflow 绕开动态 `MCPP_PIN` 设计。`src/xlings.cppm`
5463
`pinned::kXlingsVersion` 仍是 xlings 版本的唯一真源。
5564

5665
## 发布步骤
@@ -82,8 +91,8 @@ git checkout -b "chore/bump-$NEW_VERSION"
8291
sed -i "s/^version.*=.*/version = \"$NEW_VERSION\"/" mcpp.toml
8392
sed -i "s/MCPP_VERSION = \".*\"/MCPP_VERSION = \"$NEW_VERSION\"/" src/toolchain/fingerprint.cppm
8493

85-
# 当前 check_version_pins.sh 有 Bash 语法错误;在它修复前手工确认:
86-
# mcpp.toml 与 MCPP_VERSION 相等,.xlings.json 仍是已发布的 bootstrap 版本。
94+
# 校验:mcpp.toml 与 MCPP_VERSION 相等,.xlings.json 不领先于正在构建的版本。
95+
bash .github/tools/check_version_pins.sh
8796

8897
# 自查:构建产物真的报新版本。注意 target/ 目录名带指纹哈希,
8998
# 版本一变就是新目录 —— 用 `ls -dt` 取最新的那个,`head -1` 会拿到旧二进制。
@@ -212,7 +221,7 @@ xlings update && xlings install mcpp@$NEW_VERSION -y
212221
# 3) bootstrap pin 收尾 —— 仅 .xlings.json;新版此时已发布、已镜像、已进索引
213222
sed -i "s/\"mcpp\": \"[^\"]*\"/\"mcpp\": \"$NEW_VERSION\"/" .xlings.json
214223
# 不编辑 ci-fresh-install.yml 的 MCPP_PIN:它由 wait-index 运行时推导。
215-
# 当前 check_version_pins.sh 有 Bash 语法错误;手工确认 pin 关系
224+
bash .github/tools/check_version_pins.sh # 复核 pin 关系
216225
git commit -am "ci: workspace mcpp bootstrap pin -> $NEW_VERSION (released, mirrored, indexed)"
217226
```
218227

@@ -304,7 +313,7 @@ gh workflow run release.yml --ref "v$NEW_VERSION"
304313
| `.xlings.json` | `workspace.mcpp` — CI bootstrap 装哪个 mcpp(发布****才 bump) |
305314
| `.github/workflows/ci-fresh-install.yml` | `MCPP_PIN` — 由 `wait-index` 从最新 release 推导,**从不手工 bump** |
306315
| `src/xlings.cppm` | `kXlingsVersion` — xlings pin 的**唯一真源** |
307-
| `.github/tools/check_version_pins.sh` | 版本/pin 校验的预期 guard;当前有 Bash 语法错误,修复前须手工核对 |
316+
| `.github/tools/check_version_pins.sh` | 版本/pin 校验 guard**`bash` 跑,不能用 `sh`** |
308317
| `.github/tools/slim_linux_payload.sh` | linux 载荷 strip + 断言 |
309318
| `.github/tools/mirror_res.sh` | 双端镜像(并发上传 + leg deadline + 完整性 gate) |
310319
| `.github/tools/gtc` | GitCode CLI(release create/upload、PR) |
@@ -315,5 +324,4 @@ gh workflow run release.yml --ref "v$NEW_VERSION"
315324
> **注意版本 bump 的两个阶段**`mcpp.toml` + `fingerprint.cppm` 在发版****
316325
> (它们定义要发什么);`.xlings.json` 只在发版成功、镜像并进索引后才可更新
317326
> (它指定 bootstrap 使用的已发布版本)。`MCPP_PIN` 是被测版本的运行时推导值,
318-
> 不属于任何手工 bump 阶段。当前 `check_version_pins.sh` 的 Bash 语法错误修复前,
319-
> 这些关系须手工核对。
327+
> 不属于任何手工 bump 阶段。这些关系由 `bash .github/tools/check_version_pins.sh` 校验。

docs/03-toolchains.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ windows = "gcc@16" # gcc family on Windows = MinGW-w64
162162
# legacy value "mingw@16.1.0" keeps working
163163
```
164164

165+
Artifact names follow the **target**, and for static libraries the convention
166+
splits on the *env* segment, not on the OS:
167+
168+
| Target | `kind = "lib"` produces |
169+
|---|---|
170+
| `x86_64-windows-gnu` | `libfoo.a` (GNU convention) |
171+
| `x86_64-windows-msvc` | `foo.lib` (MSVC convention) |
172+
173+
Before 2026.8.3.3 a mingw build on a Windows host emitted `foo.lib` — a GNU
174+
archive wearing an MSVC name, which MSVC cannot consume. If you have a script
175+
that globs `*.lib` out of a `windows-gnu` build, it needs to glob `*.a` now.
176+
165177
## Linux ELF from Windows (`x86_64-linux-musl`, no WSL required)
166178

167179
The mirror of the section above: a Windows machine producing a **fully static
@@ -193,9 +205,13 @@ mcpp: ELF 64-bit LSB executable, x86-64, statically linked, stripped
193205
Linux hosts only. The musl target is self-contained and needs neither.
194206

195207
Cross-arch from Windows (e.g. `aarch64-linux-musl`) is not available either —
196-
the canadian-cross payload is built per host arch. `mcpp toolchain list` shows
197-
only what the current host can actually install, so if a target is missing from
198-
the Targets block, that host genuinely cannot serve it.
208+
the canadian-cross payload is built per host arch. **A macOS host has no
209+
Linux-targeting payload at all**, so no Linux target is reachable from there.
210+
211+
You do not have to memorize any of this: `mcpp toolchain list` shows only what
212+
the current host can actually install, so if a target is missing from the
213+
Targets block, that host genuinely cannot serve it (implemented by
214+
`toolchain::host_can_serve`).
199215

200216
## MSVC (System Toolchain, Windows)
201217

docs/05-mcpp-toml.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,14 @@ mcpp cache gc --older-than 30d # ...or by how long since they were last use
895895
mcpp cache clean [--deps|--std|--all|--legacy]
896896
```
897897

898+
The on-disk entry layout is versioned. An mcpp release that changes it retires
899+
every older entry at once, so the first build after such an upgrade rebuilds
900+
its dependencies and repopulates — nothing to clean by hand. 2026.8.3.4 did
901+
exactly that: an entry's object paths are now addressed relative to the
902+
*package*, never to the build directory of whichever project happened to
903+
populate the entry first. `mcpp cache verify` additionally reports any entry
904+
whose recorded addresses escape it, so a recurrence is auditable offline.
905+
898906
### 2.11 `[runtime]` — Host Runtime Capabilities
899907

900908
```toml

docs/09-release.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ of those commit messages contains a misdiagnosis that is corrected in §5.
1515
| `.xlings.json` `[workspace].mcpp` | **bootstrapped from** | separately, *after* a release is installable |
1616
| `ci-fresh-install.yml` `MCPP_PIN` | **version under test** | **nothing — it is derived at run time** (§5) |
1717

18-
The intended `.github/tools/check_version_pins.sh` guard covers the persistent
19-
relationships: the two "being built" sites must be equal, and the bootstrap
20-
pin must never be **newer** than the version being built. At this revision the
21-
script has a Bash syntax error, so it cannot currently provide that verification;
22-
check these relationships manually until its implementation is repaired.
18+
`.github/tools/check_version_pins.sh` machine-checks the persistent
19+
relationships: the two "being built" sites must be equal, and the bootstrap pin
20+
must never be **newer** than the version being built.
21+
22+
```bash
23+
bash .github/tools/check_version_pins.sh
24+
```
25+
26+
Run it with **bash**, not `sh`. It uses process substitution (`done < <(...)`),
27+
which POSIX `sh`/dash cannot parse — `sh check_version_pins.sh` fails with
28+
`Syntax error: redirection unexpected` around line 95. That is the invoking
29+
shell, not a defect in the script: its shebang is `#!/usr/bin/env bash` and CI
30+
invokes it as `bash`.
2331

2432
The two groups are deliberately allowed to differ. Bumping them together is what
2533
an earlier revision of the pin checker required, and it sent every CI job to
@@ -123,8 +131,7 @@ hardcoded literal only bought the first:
123131
The guard was already deriving the right answer and throwing it away. Feeding
124132
both from one value makes that disagreement structurally impossible.
125133

126-
The intended `check_version_pins.sh` guard rejects a literal `MCPP_PIN:`. Do
127-
not reintroduce one while its current syntax error is being repaired: a literal
134+
`check_version_pins.sh` rejects a literal `MCPP_PIN:`. Do not reintroduce one: a literal
128135
would again let the index guard and the installed version drift apart.
129136

130137
> **Correction.** Commit `3b1cb6b` ("bootstrap pin -> 2026.7.29.2") states *"the
@@ -139,7 +146,7 @@ would again let the index guard and the installed version drift apart.
139146
```
140147
[ ] version bumped in mcpp.toml + fingerprint.cppm (one commit)
141148
[ ] CHANGELOG entry
142-
[ ] manually verify `mcpp.toml` = `MCPP_VERSION` and `.xlings.json` is not newer (the current `check_version_pins.sh` has a Bash syntax error)
149+
[ ] `bash .github/tools/check_version_pins.sh` passes (verifies `mcpp.toml` = `MCPP_VERSION`, and `.xlings.json` is not newer)
143150
[ ] merge to main, CI green
144151
[ ] gh workflow run release.yml --ref main
145152
[ ] release.yml green (4 builds + publish-ecosystem)

docs/spec/package-identity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
| **状态** | **评审中(Review)** —— 已实现 |
88
| **版本** | 1.1 |
99
| **最后修改** | 2026-08-03 |
10-
| **最低实现版本** | mcpp **0.0.106**(xlings >= 0.4.69;当前实现为 2026.8.3.2) |
10+
| **最低实现版本** | mcpp **0.0.106**(xlings >= 0.4.69) |
1111
| **作者/维护** | mcpp-community |
1212
| **相关设计文档** | `.agents/docs/2026-06-20-package-resolution-architecture.md` §4<br>`.agents/docs/2026-06-26-identity-first-resolution-no-filename.md`<br>`.agents/docs/2026-07-25-issue278-descriptor-name-form-canonicalization-design.md`<br>`.agents/docs/2026-07-25-name-namespace-bidirectional-verification-report.md`<br>`.agents/docs/2026-07-25-name-namespace-canonical-implementation-spec.md` |
1313
| **相关 issue** | [mcpp#278](https://github.com/mcpp-community/mcpp/issues/278)<br>[xlings#381](https://github.com/openxlings/xlings/issues/381) —— 索引键缺命名空间维度(§3.3) |

docs/zh/03-toolchains.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,98 @@ windows = "gcc@16" # Windows 上的 gcc family = MinGW-w64
156156
# 旧值 "mingw@16.1.0" 原样可用
157157
```
158158

159+
产物名跟随 **target**;静态库的命名约定分岔点是 triple 的 *env* 段,而不是 OS:
160+
161+
| Target | `kind = "lib"` 产出 |
162+
|---|---|
163+
| `x86_64-windows-gnu` | `libfoo.a`(GNU 约定) |
164+
| `x86_64-windows-msvc` | `foo.lib`(MSVC 约定) |
165+
166+
2026.8.3.3 之前,Windows 宿主上的 mingw 构建产出的是 `foo.lib` —— 一个 GNU
167+
archive 顶着 MSVC 的名字,MSVC 拿不去用。如果你有脚本按 `*.lib` 去捞
168+
`windows-gnu` 的产物,现在要改成 `*.a`
169+
170+
## Windows 上产出 Linux ELF(`x86_64-linux-musl`,无需 WSL)
171+
172+
上一节的镜像:一台 Windows 机器直接产出**完全静态的 Linux 二进制**,
173+
不需要 WSL、不需要容器,也不往系统里装任何东西。
174+
175+
```bash
176+
mcpp build --target x86_64-linux-musl # Windows 或 Linux 上皆可
177+
```
178+
179+
两种宿主上这条命令**逐字相同**,因为 "交叉" 在 mcpp 里不是一个名字,
180+
它只是 `host ≠ target` 这个关系。由哪个 payload 承接目标是自动分流的:
181+
Linux x86_64 宿主装原生 `musl-gcc`;Windows 宿主装一条 **canadian-cross**
182+
GCC(以 `x86_64-linux-gnu` 构建 → 运行于 `x86_64-w64-mingw32` → 产出
183+
`x86_64-linux-musl`)。两者都是 GCC 16.1.0,也都带 `bits/std.cc`,
184+
所以 `import std` 在两边行为一致。
185+
186+
产物是没有 `PT_INTERP` 的全静态 ELF —— 不挑发行版、不挑 libc,
187+
这正是 musl 成为第一个被打通的 Linux target 的原因:
188+
189+
```console
190+
$ file mcpp
191+
mcpp: ELF 64-bit LSB executable, x86-64, statically linked, stripped
192+
```
193+
194+
Windows 上**不支持** `x86_64-linux-gnu`:glibc target 还需要 `xim:glibc`
195+
`xim:linux-headers` 两个 sysroot payload,而它们只为 Linux 宿主发布。
196+
musl target 自包含,两者都不需要。
197+
198+
Windows 上也**不支持跨 arch**(如 `aarch64-linux-musl`)—— canadian-cross
199+
payload 是按宿主 arch 构建的。**macOS 宿主则完全没有面向 Linux 的 payload**,
200+
任何 Linux target 都不可用。
201+
202+
判据不必靠记:`mcpp toolchain list` 只列出当前宿主真正装得上的 target,
203+
Targets 一栏里没有的,就是这台机器确实服务不了(实现见
204+
`toolchain::host_can_serve`)。
205+
206+
## MSVC(系统工具链,Windows)
207+
208+
MSVC 与 mcpp 管理的其它工具链都不同:它是一条**系统工具链**。mcpp 只负责
209+
定位并识别已安装的 Visual Studio / Build Tools —— **从不**安装、升级或卸载
210+
MSVC 本身。
211+
212+
```bash
213+
mcpp toolchain default msvc
214+
```
215+
216+
在装有 MSVC 的机器上,mcpp 会自动定位(依次尝试 `vswhere.exe`
217+
`VSINSTALLDIR`/`VS*COMNTOOLS`、标准安装路径),识别涉及的各个版本,
218+
并持久化为稳定 spec `msvc@system`:
219+
220+
```
221+
Detected msvc 19.44.35211 (VS 2022 BuildTools) (VC tools 14.44.35207)
222+
cl: C:\Program Files\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x64\cl.exe
223+
import std: available (std.ixx)
224+
Default set to msvc@system (was: llvm@20.1.7)
225+
```
226+
227+
若机器上**没有** MSVC,mcpp 打印安装指引(Visual Studio Installer 勾选
228+
*Desktop development with C++* 负载,或 `winget install
229+
Microsoft.VisualStudio.2022.BuildTools`)并以非零码退出 —— 需要你自己装好,
230+
再重跑该命令。
231+
232+
`mcpp toolchain list` 会把检测到的 MSVC 列在单独的 `System:` 分区,
233+
`mcpp self doctor` 在 Windows 上会报告它的状态。manifest 里可按平台 pin:
234+
235+
```toml
236+
[toolchain]
237+
windows = "msvc@system"
238+
```
239+
240+
`msvc@<前缀>`(如 `msvc@19.44`)是一个 **pin-verify**:mcpp 仍然使用已安装
241+
的最新 VC tools,但检测到的版本与前缀不符时报错。
242+
243+
自 0.0.90 起,**原生 cl.exe 构建可用**:mcpp 从检测到的 VC tools + Windows
244+
SDK 合成 INCLUDE/LIB 环境(不经 `vcvarsall`),把 `std.ixx`/`std.compat.ixx`
245+
staging 成 `.ifc` BMI,用 `/interface /TP /ifcOutput` 编译 `.cppm` 模块单元,
246+
`/scanDependencies` 扫描,并通过 response file 调 `link.exe`/`lib.exe`
247+
链接。选择 `/MT` CRT 用 `[target.x86_64-windows-msvc] linkage = "static"`
248+
(或 `mcpp build --static`)—— 不是 `[build] linkage`,那个键不存在。
249+
缺 Windows SDK 会让构建失败并给出安装指引(`mcpp self doctor` 会报告 SDK 状态)。
250+
159251
## 项目级版本锁定
160252

161253
若项目需固定特定版本而不依赖全局默认,可在项目的 `mcpp.toml` 中声明:
@@ -239,3 +331,51 @@ mcpp 的运行行为可通过以下环境变量调整:
239331
工具链 ABI 不满足任一依赖的 abi 要求时,构建会**尽早失败**并给出修复建议
240332
(例如 musl-static 工具链遇到 abi:glibc 依赖),取代深层的链接/头文件报错。
241333
查看:`mcpp why toolchain`
334+
335+
## 已知工具链风险:模块接口中的运算符模板(Clang 20+)
336+
337+
一个导出**替换性运算符模板**的模块,在 Clang 20 或 22 下会毒化所有导入者
338+
中该运算符的名字查找:任何 `import` 了这个模块、并用到该运算符的 TU
339+
——**无论作用在什么类型上**——都会让前端崩溃(SIGSEGV)。GCC 16 与
340+
Clang 18 不受影响,所以这是 Clang 18 到 20 之间的一处回归。
341+
342+
它正好打在 module-package 这个模式上。包装一个运算符是 `static inline`
343+
模板的上游头文件,再用一个恒真约束镜像它们的签名(跨 TU 包含关系的标准配方),
344+
恰恰就是踩中它的写法。
345+
346+
**经验判据:**每个模板形参都应由**第一个**函数实参定死。破坏这一点的形状就是有毒的:
347+
348+
```cpp
349+
// 有毒 —— `n` 与 `l` 不由第 1 个实参决定
350+
template<typename T, int m, int n, int l>
351+
Matx<T, m, n> operator*(const Matx<T, m, l>& a, const Matx<T, l, n>& b);
352+
353+
// 有毒 —— 第二个 typename 只出现在第 2 个实参里
354+
template<typename T1, typename T2, int n>
355+
Vec<T1, n>& operator+=(Vec<T1, n>& a, const Vec<T2, n>& b);
356+
357+
// 没问题 —— 每个形参都由第 1 个实参定死
358+
template<typename T, int m, int n>
359+
Matx<T, m, n> operator+(const Matx<T, m, n>& a, const Matx<T, m, n>& b);
360+
```
361+
362+
崩溃是**按名字**触发的:一处被毒化的 `operator*` 声明,会让每个导入者里的
363+
每一个 `x * y` 都崩,哪怕类型完全无关。函数体本身无关紧要。
364+
365+
**绕法**是整体推导操作数类型再加约束,而不是在形参列表里把它们拆开。
366+
这样保持调用兼容,跨 TU 语义也仍然成立 —— 上游那个精确匹配的
367+
`static inline` 更特化,在那边照样胜出:
368+
369+
```cpp
370+
template<typename MA, typename MB>
371+
requires pick<typename MA::value_type>
372+
&& __is_same(MA, typename MA::mat_type)
373+
&& __is_same(MB, Matx<typename MB::value_type,
374+
(int)MA::rows, (int)MA::cols>)
375+
inline MA& operator+=(MA& a, const MB& b);
376+
```
377+
378+
跟踪于 [mcpp#256](https://github.com/mcpp-community/mcpp/issues/256)
379+
`tests/e2e/150_clang_module_operator_template.sh` 是一只跑在内置 LLVM
380+
工具链上的金丝雀 —— 未来某次 Clang 升级修好(或再次弄坏)这一点时,
381+
它会显式暴露出来,而不是悄悄改变包能表达的东西。

docs/zh/05-mcpp-toml.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,13 @@ mcpp cache gc --older-than 30d # 或按"多久没用过"回收
663663
mcpp cache clean [--deps|--std|--all|--legacy]
664664
```
665665

666+
条目的磁盘布局是带版本的。改动布局的 mcpp 版本会**一次性作废全部旧条目**,
667+
所以升级后的第一次构建会重编依赖并重新填充 —— 不需要手工清理。
668+
2026.8.3.4 就是这样一次:条目里对象的地址现在相对****自身,
669+
而不再相对"最先填充这个条目的那个工程"的构建目录。
670+
`mcpp cache verify` 另外会报告任何逃出条目的记录地址,
671+
使这条不变量可以离线审计。
672+
666673
### 2.11 `[runtime]` — 主机运行时能力
667674

668675
```toml

0 commit comments

Comments
 (0)