本 issue 的根因已被重写。 初版归因为「同一 home 用过两个 mcpp 版本 ⇒ 缓存 key 少一轴」,
那个结论被我自己的后续测量否掉了:两个版本选中的 std identity 是同一个
(50c5b8df12f1bf98),而且单一版本、单一 home 就能复现。下面是纠正后的内容。
Bug: 依赖 BMI 缓存命中时,被恢复的包 BMI 的传递 import std 没有进入消费方的构建图
最小复现(一个 mcpp 版本,干净缓存)
rm -rf ~/.mcpp/build-cache/v1/pkg/mcpplibs/imgui@0.0.6/
mcpp new a --template imgui:window && (cd a && mcpp build) # OK ← 缓存 miss
mcpp new b --template imgui:window && (cd b && mcpp build) # FAIL ← 缓存 hit
error: build failed
std: error: failed to read compiled module: No such file or directory
std: note: compiled module file is 'gcm.cache/std.gcm'
std: note: imports must be built before being imported
imgui.app: error: failed to read compiled module: Bad import dependency
根因
imgui 包的模块 import std。消费方 main.cpp 只有:
import imgui.core;
import imgui.app;
它自己不 import std。
- 缓存 miss 时,包在本地被编译,这个动作本身就把
std BMI 边带进了构建图 ⇒
gcm.cache/std.gcm 存在 ⇒ 一切正常。
- 缓存 hit 时,包的 BMI 被直接恢复进消费方的
gcm.cache,但没有任何东西把
std BMI 边加进消费方的构建图 ⇒ std.gcm 根本不存在 ⇒ 被恢复的
imgui.app.gcm 读不到它要的 std。
两条都成立,互为佐证:
| 变量 |
结果 |
mcpp build --cache off |
OK(绕开缓存,包本地编译) |
消费方 main.cpp 加一行 import std; |
OK(std 边因此进图) |
| 原样 + 缓存命中 |
FAIL |
所以缺的不是 key 的某一轴,而是:恢复一个包的 BMI 时,必须把它传递依赖的
std(以及任何它 import 而消费方图里没有的模块)一并纳入消费方的构建图。
为什么它看起来像「升级把我弄坏了」
第一个构建它的人(缓存 miss)永远是好的,之后每个人(缓存 hit)都坏。
所以现象是「以前能跑,现在不行」,而实际上和版本无关 —— 我最初正是被这个顺序
误导,把它归因成跨版本投毒;用同一个版本跑两个项目就能证伪。
影响
任何 import std 的索引包,只要消费方自己不 import std,第二次起就构建失败,
而错误信息(No such file or directory / Bad import dependency)完全不指向缓存。
imgui 模板是现成的例子 —— 它生成的 main.cpp 就不 import std。
绕过
mcpp build --cache off
- 或消费方源码里显式
import std;
- 或删
~/.mcpp/build-cache/v1/pkg/<ns>/<pkg>@<ver>/(只回到 miss,下一个项目还会再犯)
环境
mcpp 2026.8.10.1(2026.8.8.2 / 2026.8.8.4 同样复现,早于最近这批改动)、
gcc 16.1.0、x86_64-linux-gnu。
Bug: 依赖 BMI 缓存命中时,被恢复的包 BMI 的传递
import std没有进入消费方的构建图最小复现(一个 mcpp 版本,干净缓存)
根因
imgui包的模块import std。消费方main.cpp只有:它自己不
import std。stdBMI 边带进了构建图 ⇒gcm.cache/std.gcm存在 ⇒ 一切正常。gcm.cache,但没有任何东西把stdBMI 边加进消费方的构建图 ⇒std.gcm根本不存在 ⇒ 被恢复的imgui.app.gcm读不到它要的std。两条都成立,互为佐证:
mcpp build --cache offmain.cpp加一行import std;所以缺的不是 key 的某一轴,而是:恢复一个包的 BMI 时,必须把它传递依赖的
std(以及任何它 import 而消费方图里没有的模块)一并纳入消费方的构建图。为什么它看起来像「升级把我弄坏了」
第一个构建它的人(缓存 miss)永远是好的,之后每个人(缓存 hit)都坏。
所以现象是「以前能跑,现在不行」,而实际上和版本无关 —— 我最初正是被这个顺序
误导,把它归因成跨版本投毒;用同一个版本跑两个项目就能证伪。
影响
任何
import std的索引包,只要消费方自己不import std,第二次起就构建失败,而错误信息(
No such file or directory/Bad import dependency)完全不指向缓存。imgui模板是现成的例子 —— 它生成的main.cpp就不import std。绕过
mcpp build --cache offimport std;~/.mcpp/build-cache/v1/pkg/<ns>/<pkg>@<ver>/(只回到 miss,下一个项目还会再犯)环境
mcpp
2026.8.10.1(2026.8.8.2/2026.8.8.4同样复现,早于最近这批改动)、gcc 16.1.0、x86_64-linux-gnu。