Skip to content

Commit 2010630

Browse files
committed
fix(cache): module_extensions 进依赖缓存键的 E 轴
指纹管的是 target/<triple>/<fp>/,全局依赖缓存是另一套键。一个声明了 module_extensions 的依赖产出不同的 .o/BMI,它的缓存键必须体现这一点。 今天不可达 —— 默认 glob 会跟着变,sourceGlobs 已经动了;索引包描述符按版本 冻结,version 在 D 轴。但这正是本 PR 在消灭的形状(同一决策漏一处),一行补上 比留着等它以后变成一次错误的缓存命中便宜。 不 bump epoch:老条目命令行里没有 -x c++,而该旗标在已识别后缀上幂等(产物逐 字节相同),沿用安全,不必让全网缓存作废。
1 parent 230fc0c commit 2010630

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

.agents/docs/2026-08-11-source-kind-table-and-build-program-timeout.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,45 @@ BMI 坏掉时报错会指向一个和你的改动毫无关系的模块,极难归
893893

894894
---
895895

896+
## 7.4 深度自审(CI 后)发现并修掉的两条
897+
898+
### ① 未捕获的有界运行丢了流式输出 —— 真回归
899+
900+
`run_exec_deadline``mcpp test` **非 JSON 模式**跑测试二进制的路径,原本
901+
**继承调用方 stdio**。我第一版把它改成「捕获后在结束时回放」,后果两条:
902+
903+
1. 长测试的输出全部憋到退出才出现 —— 恰好抵消 `mcpp test` 可观察性那一整轮工作
904+
(「只有子进程输出、mcpp 一行没有」正是缓冲问题的指纹);
905+
2. 子进程 stdout 变成管道而非终端 ⇒ gtest 之类**静默关掉彩色输出**
906+
907+
修法:两侧启动器共用一条契约 —— **`sink == nullptr` 表示不捕获**,子进程直接继承
908+
调用方 stdio,但仍然有界。POSIX 不建管道不设 dup2;Windows 不设
909+
`STARTF_USESTDHANDLES`,也不加 `CREATE_NO_WINDOW`(未捕获的运行本来就是给人看的)。
910+
911+
### ② 依赖缓存键的 E 轴漏了 `module_extensions`
912+
913+
指纹管的是 `target/<triple>/<fp>/`,**全局依赖缓存是另一套键**。一个声明了
914+
`module_extensions` 的依赖产出不同的 `.o`/BMI,但它的缓存键此前不含这个字段。
915+
916+
**今天不可达**:默认 glob 会跟着变 ⇒ `sourceGlobs` 已经动了;而索引包描述符按版本
917+
冻结,`package.version` 在 D 轴。⇒ 但这正是本方案要消灭的形状(同一决策漏一处),
918+
一行补上比留着等它以后变成一次「错误的缓存命中」便宜。
919+
920+
### 顺带确认:`-x c++` 不需要 bump 缓存 epoch
921+
922+
老 mcpp 写入的缓存条目(命令行里没有 `-x c++`)会被新 mcpp 读到。因为该旗标在
923+
已识别后缀上**幂等**(§3.8.1 实测),产物逐字节相同 ⇒ 沿用是安全的,不必让全网
924+
缓存作废。
925+
926+
### 一处**刻意的**行为变化
927+
928+
`is_compilable_output`(build.mcpp 生成物能否编译)原本是**唯一含 `.ixx` 的清单**
929+
改为按 kind 判定后,`.ixx` 生成物在未声明 `module_extensions` 时不再被自动纳入
930+
`sources`。这是**修正而非回归**:旧路径接受它进 sources,而后面每一个阶段都会
931+
错误处理它 —— 没有任何包能靠那条路径正常工作。
932+
933+
---
934+
896935
## 8.1 本次不做,但已排期
897936

898937
|| 状态 | 说明 |

src/build/cache_key.cppm

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ struct PackageAxes {
118118
std::vector<std::string> includeDirs; // store-relative, ordered
119119
std::vector<std::string> sourceGlobs; // [build] sources, ordered
120120
std::vector<std::string> sources; // package-root-relative, sorted
121+
// [build] module_extensions — decides which of `sources` are module
122+
// interfaces, i.e. which units emit a BMI and which objects link
123+
// unconditionally. Different artifacts, so it belongs in the key.
124+
//
125+
// Not reachable today (a widened default glob already moves `sourceGlobs`,
126+
// and an index descriptor is frozen per version so nothing else can move
127+
// it) — which is exactly why it is easy to leave out and find later as a
128+
// wrong cache hit. Cheap to close now.
129+
std::vector<std::string> moduleExtensions;
121130
// F — keys of direct dependencies, sorted
122131
std::vector<std::string> upstreamKeys;
123132
};
@@ -221,6 +230,7 @@ nlohmann::json to_json(const BuildAxes& b, const PackageAxes& p) {
221230
{"include_dirs", p.includeDirs},
222231
{"source_globs", p.sourceGlobs},
223232
{"sources", p.sources},
233+
{"module_extensions", p.moduleExtensions},
224234
};
225235
j["upstream"] = p.upstreamKeys;
226236
return j;
@@ -262,6 +272,7 @@ std::string key_hex(const BuildAxes& b, const PackageAxes& p) {
262272
put_list(s, "includes", p.includeDirs);
263273
put_list(s, "srcglobs", p.sourceGlobs);
264274
put_list(s, "sources", p.sources);
275+
put_list(s, "modexts", p.moduleExtensions);
265276
// F
266277
put_list(s, "upstream", p.upstreamKeys);
267278
return mcpp::toolchain::hash_string(s);
@@ -311,6 +322,7 @@ void fill_package_config(PackageAxes& out,
311322
out.ldflags = bc.ldflags;
312323
out.defines = bc.defines;
313324
out.sourceGlobs = bc.sources;
325+
out.moduleExtensions = bc.moduleExtensions;
314326

315327
if (!bc.cStandard.empty()) {
316328
// A package may pin its own C standard; it reaches its own C units.

0 commit comments

Comments
 (0)