Skip to content

Revert: glx-runtime 拉 xim:graphics 静默把全 home 的编译期 glibc 抬到 2.44 - #180

Merged
Sunrisepeak merged 1 commit into
mainfrom
revert/glx-runtime-ecosystem
Aug 8, 2026
Merged

Revert: glx-runtime 拉 xim:graphics 静默把全 home 的编译期 glibc 抬到 2.44#180
Sunrisepeak merged 1 commit into
mainfrom
revert/glx-runtime-ecosystem

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

main 在 f44e8968(我的合并)变红,上一次 main 运行是绿的。

失败不是图形相关的 —— asio-modulecore 也挂,形状一致:

.../xim-x-glibc/2.39/lib64/libc.so.6: version `GLIBC_2.42' not found
                                      (required by <测试二进制>)

机制

mesa 声明 xim:glibc@>=2.38 —— 下界,不是钉死。于是拉进 xim:graphics 时装了 glibc 2.44 与 2.39 并存。而 mcpp 的载荷探测取最高版本,于是那个 home 里每一次构建都开始对着 2.44 编译链接 —— 而 gcc 载荷烙定的 interpreter 与 specs 仍然是 2.39

结果:产物引用 GLIBC_2.42/2.43 符号,运行时给不出来,在与图形毫无关系的包上炸

为什么先 revert

这条依赖不只是「加了个图形栈」——它静默移动了这个 home 里所有构建所依据的 glibc,而且只移动了编译那一半。这是 mcpp 选载荷版本的真实缺陷,不该在这个 recipe 里糊过去;要先在 mcpp 侧修掉,这个改动才能重新落地

GL 部分本身是验过的(载荷 libEGL、GPU 渲染器、消费者 RUNPATH 上无 C 运行时),不在质疑之列。缺的是:没有检查过「装这个栈会对 home 的其余部分做什么」。

main is red at f44e896 and the previous run was green, so this is mine.

The failures are not graphics ones -- asio-module and core fail too, all with
the same shape:

    .../xim-x-glibc/2.39/lib64/libc.so.6: version `GLIBC_2.42' not found
                                          (required by <the test binary>)

mesa declares `xim:glibc@>=2.38`, a floor rather than a pin, so pulling
`xim:graphics` in as a dependency installed glibc 2.44 alongside 2.39. mcpp's
payload probe takes the HIGHEST version it finds, so every build in that home
started compiling and linking against 2.44 -- while the gcc payload's baked-in
interpreter and specs still name 2.39. The result is binaries that reference
GLIBC_2.42/2.43 symbols and a runtime that cannot provide them, in packages
that have nothing to do with graphics.

So the dependency did not just add a graphics stack: it silently moved the
glibc every build in the home compiles against, and only the compile half
moved. That is a real defect in how mcpp picks a payload version, not
something to paper over in this recipe -- and it has to be fixed on the mcpp
side before this change can land again.

The GL work itself was verified (payload libEGL, GPU renderer, no C runtime on
the consumer's RUNPATH) and is not in question. What was missing was any check
of what installing the stack does to the REST of a home.
@Sunrisepeak

Copy link
Copy Markdown
Member Author

关闭。main 已经通过 revert 恢复绿色,而这个 revert PR 本身不再需要 —— 图形栈迁移会在 mcpp 侧修好 D1(载荷版本探测)之后重新落地,届时连同「装这个栈不影响 home 其余部分」的验证一起提。

根因记录在 mcpp 仓 .agents/docs/2026-08-08-payload-version-and-contract-drift-design.md:mesaxim:glibc@>=2.38 下界拉进 glibc 2.44,而 mcpp 的载荷探测取 readdir 第一个 ⇒ 编译对着 2.44、运行是 gcc specs 烙定的 2.39。

@Sunrisepeak Sunrisepeak closed this Aug 8, 2026
@Sunrisepeak

Copy link
Copy Markdown
Member Author

重开 —— 我上一条评论说「main 已经通过 revert 恢复绿色」是错的:关闭这个 PR 时它并没有合入,main 仍停在 f44e896,也就是仍然红着。

先合它让 main 回绿;图形栈迁移在 mcpp 侧修好 D1 之后连同副作用验证一起重新提。

@Sunrisepeak Sunrisepeak reopened this Aug 8, 2026
@Sunrisepeak
Sunrisepeak merged commit 297d0a9 into main Aug 8, 2026
12 checks passed
@Sunrisepeak
Sunrisepeak deleted the revert/glx-runtime-ecosystem branch August 8, 2026 00:23
Sunrisepeak added a commit that referenced this pull request Aug 8, 2026
重新应用 f44e896(#179),它在 #180 被整体 revert。改动本身是对的:
compat.glx-runtime 之前从 /usr/lib* 符号链接**宿主的** libGL/libEGL,而
mcpp#352 正是这么来的 —— 宿主 Mesa 需要 GLIBC_2.43,mcpp 的 payload glibc 是
2.39,程序链接干净、退出 255、一行输出都没有。它也是 xlings hermetic 政策
禁止清单上的第一条。

被 revert 的原因不在这两个文件里。mesa 声明 `xim:glibc@>=2.38`,下限被任何
更高版本满足,于是 xim 在 2.39 旁边装了 2.44;而当时的 mcpp 用 readdir 的第一项
来解析「那个 glibc payload」,编译侧取了 2.44,产物的 interpreter 却仍是 2.39。
二进制开始引用 GLIBC_2.42 符号,而报错落在 asio-module 和 core 上 —— 两个不用
图形、不依赖 mesa、这次改动根本没碰的成员。

引擎侧已在 mcpp 2026.8.8.2 修好(runtime binding 从 subos 读,不再猜)。

真正缺的是**这里**的一个测试。这个仓库的每个测试都在测「它自己那个包」,所以
没有任何一个问出唯一重要的那个问题:装了这个,对**其他所有人**有没有影响?
tests/check_graphics_install_side_effects.sh 就问这一个:装图形栈前后,各构建
一次与图形无关的成员,断言产物的 PT_INTERP 与 glibc 符号上界**逐字不变**。

它在任何早于 2026.8.8.2 的 mcpp 上都会失败,这是有意的 —— 图形栈不该落在一个
仍会犯这个错的工具链上。
Sunrisepeak added a commit that referenced this pull request Aug 8, 2026
重新应用 f44e896(#179),它在 #180 被整体 revert。改动本身是对的:
compat.glx-runtime 之前从 /usr/lib* 符号链接**宿主的** libGL/libEGL,而
mcpp#352 正是这么来的 —— 宿主 Mesa 需要 GLIBC_2.43,mcpp 的 payload glibc 是
2.39,程序链接干净、退出 255、一行输出都没有。它也是 xlings hermetic 政策
禁止清单上的第一条。

被 revert 的原因不在这两个文件里。mesa 声明 `xim:glibc@>=2.38`,下限被任何
更高版本满足,于是 xim 在 2.39 旁边装了 2.44;而当时的 mcpp 用 readdir 的第一项
来解析「那个 glibc payload」,编译侧取了 2.44,产物的 interpreter 却仍是 2.39。
二进制开始引用 GLIBC_2.42 符号,而报错落在 asio-module 和 core 上 —— 两个不用
图形、不依赖 mesa、这次改动根本没碰的成员。

引擎侧已在 mcpp 2026.8.8.2 修好(runtime binding 从 subos 读,不再猜)。

真正缺的是**这里**的一个测试。这个仓库的每个测试都在测「它自己那个包」,所以
没有任何一个问出唯一重要的那个问题:装了这个,对**其他所有人**有没有影响?
tests/check_graphics_install_side_effects.sh 就问这一个:装图形栈前后,各构建
一次与图形无关的成员,断言产物的 PT_INTERP 与 glibc 符号上界**逐字不变**。

它在任何早于 2026.8.8.2 的 mcpp 上都会失败,这是有意的 —— 图形栈不该落在一个
仍会犯这个错的工具链上。
Sunrisepeak added a commit that referenced this pull request Aug 8, 2026
两件事,都是评审提问逼出来的。

一、`MCPP_VERSION` 2026.8.6.2 → 2026.8.8.2。不是顺手升级。

`compat.glx-runtime` 依赖 mesa,mesa 声明 `xim:glibc@>=2.38`;下限被任何更高版本
满足,于是安装图形栈会在既有 glibc 旁边再装一个。2026.8.8.2 之前的 mcpp 用
`readdir` 的第一项解析「那个 glibc payload」,编译侧与产物 interpreter 因此可以
指向不同版本 —— 这正是 #179 落地后 asio-module 和 core 变红、整份改动被 #180
revert 的原因。用更旧的 mcpp 重新落地,就是在仍会犯这个错的引擎上复现事故条件。

二、`tests/check_graphics_install_side_effects.sh` 不被任何 workflow 引用。

它是一个永远不会运行的检查 —— 与它自己反对的东西同一形状。现在有专属作业,
Linux,装 pin 住的 mcpp 后执行。

顺带回答「为什么触发了全量 CI」:选择规则里 `tests/*.sh` 一律 full。这条规则是为
共享测试骨架写的,而新文件匹配了它。就本 PR 而言全量恰恰是想要的 —— 上次坏掉的
正是与图形无关的成员,只跑图形相关的那几个看不见任何东西。

注意:动 `MCPP_VERSION` 会改变 registry 缓存键(它进 key 也进 restore-keys),
所以这一轮所有 workspace 作业都从冷缓存起步。潜伏的缺陷可能因此「突然出现」——
那是暴露,不是新增。
Sunrisepeak added a commit that referenced this pull request Aug 8, 2026
* feat(glx-runtime): GL 来自生态而非 /usr/lib,这次带上缺失的那个测试

重新应用 f44e896(#179),它在 #180 被整体 revert。改动本身是对的:
compat.glx-runtime 之前从 /usr/lib* 符号链接**宿主的** libGL/libEGL,而
mcpp#352 正是这么来的 —— 宿主 Mesa 需要 GLIBC_2.43,mcpp 的 payload glibc 是
2.39,程序链接干净、退出 255、一行输出都没有。它也是 xlings hermetic 政策
禁止清单上的第一条。

被 revert 的原因不在这两个文件里。mesa 声明 `xim:glibc@>=2.38`,下限被任何
更高版本满足,于是 xim 在 2.39 旁边装了 2.44;而当时的 mcpp 用 readdir 的第一项
来解析「那个 glibc payload」,编译侧取了 2.44,产物的 interpreter 却仍是 2.39。
二进制开始引用 GLIBC_2.42 符号,而报错落在 asio-module 和 core 上 —— 两个不用
图形、不依赖 mesa、这次改动根本没碰的成员。

引擎侧已在 mcpp 2026.8.8.2 修好(runtime binding 从 subos 读,不再猜)。

真正缺的是**这里**的一个测试。这个仓库的每个测试都在测「它自己那个包」,所以
没有任何一个问出唯一重要的那个问题:装了这个,对**其他所有人**有没有影响?
tests/check_graphics_install_side_effects.sh 就问这一个:装图形栈前后,各构建
一次与图形无关的成员,断言产物的 PT_INTERP 与 glibc 符号上界**逐字不变**。

它在任何早于 2026.8.8.2 的 mcpp 上都会失败,这是有意的 —— 图形栈不该落在一个
仍会犯这个错的工具链上。

* ci: mcpp 2026.8.8.2 是这份改动的前置,而那个新检查从没被跑过

两件事,都是评审提问逼出来的。

一、`MCPP_VERSION` 2026.8.6.2 → 2026.8.8.2。不是顺手升级。

`compat.glx-runtime` 依赖 mesa,mesa 声明 `xim:glibc@>=2.38`;下限被任何更高版本
满足,于是安装图形栈会在既有 glibc 旁边再装一个。2026.8.8.2 之前的 mcpp 用
`readdir` 的第一项解析「那个 glibc payload」,编译侧与产物 interpreter 因此可以
指向不同版本 —— 这正是 #179 落地后 asio-module 和 core 变红、整份改动被 #180
revert 的原因。用更旧的 mcpp 重新落地,就是在仍会犯这个错的引擎上复现事故条件。

二、`tests/check_graphics_install_side_effects.sh` 不被任何 workflow 引用。

它是一个永远不会运行的检查 —— 与它自己反对的东西同一形状。现在有专属作业,
Linux,装 pin 住的 mcpp 后执行。

顺带回答「为什么触发了全量 CI」:选择规则里 `tests/*.sh` 一律 full。这条规则是为
共享测试骨架写的,而新文件匹配了它。就本 PR 而言全量恰恰是想要的 —— 上次坏掉的
正是与图形无关的成员,只跑图形相关的那几个看不见任何东西。

注意:动 `MCPP_VERSION` 会改变 registry 缓存键(它进 key 也进 restore-keys),
所以这一轮所有 workspace 作业都从冷缓存起步。潜伏的缺陷可能因此「突然出现」——
那是暴露,不是新增。

* ci: watch the home the build actually uses

The side-effect check reported INCONCLUSIVE on its first CI run, correctly: a
released mcpp is self-contained and resolves its registry from beside its own
executable, so copying the payload tree into ~/.mcpp and pointing MCPP_HOME
there watched one home while the build used another.

MCPP_HOME is now the tarball root. The check was right; the job was wrong.

* ci: 缓存 host tool store,并让 registry 缓存真正生效;补 cmdline / llmapi 成员

三件事,起因是 #181 的 CI 太长。

一、registry 缓存一直是摆设。

Download 步骤把 release 的 registry 拷进 ~/.mcpp/registry,而缓存也覆盖那里 ——
但发布版 mcpp 是 **self-contained**,从自己可执行文件旁边解析 registry。所以每次
构建用的是 <tarball>/registry,缓存恢复和保存的那份从没被读过。

证据取自加入 grpc-codegen 的那次 run:abseil 的源码编译自
`<tarball>/registry/data/xpkgs/compat-x-abseil/...`,而同一个 job 在报告 registry
缓存 **命中** 的情况下重新下载了 xim:glibc@2.44 和 xim:python@3.13.12。

修法是一行 `MCPP_HOME=$HOME/.mcpp`。payload 从此跨 run 复用。

二、host tool store 从不缓存。

同一次 run 实测:建 protoc 636s、建 grpc_cpp_plugin 660s —— 3363s 的成员里占
1296s,而且每个 job 每次 run 都重来。`protobuf-protoc`(945s)和 `grpc-module`
(1724s)建的是同一个 protoc。

store 在 `$MCPP_HOME/build-cache/v1/tool`,本机实测 116MB —— 缓存得起。粗粒度滚动
键是安全的:store 按 `<包>@<版本>/<hash>` 内容寻址,且 mcpp 逐字段比对
entry.json(epoch、target、host triple、编译器身份、profile、features、传递依赖
闭包),对不上就重建而不是误用。

刻意不缓存 `build-cache/v1/pkg`:本机 6.0GB,而 Actions 每仓库 10GB —— 塞进去会把
更需要的 registry 缓存挤掉。

三、cmdline 和 llmapi 有描述符却没有成员。

两个都补上,并且是**消费型**测试而不是「能链上就算过」:

- cmdline 用 `parse_from` 解析真实命令行,断言 positional、长选项、`--opt=value`;
  再断言**缺少必填参数会被拒绝** —— 没有这一条,前面几条对一个「什么都接受」的
  解析器同样成立。
- llmapi 全部断言离线。它是 HTTP 客户端,真打端点需要 CI 没有的 key、要花钱、且
  会因与包无关的原因失败。测的是依赖边:`:url` 的端点常量、`:types` 的 variant
  内容模型、`:errors` 的异常层次 —— 三者都是纯数据/纯逻辑。

两个成员都在本机跑通,并各自验证过把断言改错会变红。

* ci: 每片按耗时升序跑,让「核心已覆盖」成为一个可判断的中间状态

LPT 装箱按降序考虑成员,所以每片交给 run_members.sh 的顺序也是降序 —— 贵的先跑。
反过来。

理由不是「更快发现失败」,而是让维护者能在跑完之前就**做决定**。少数时候,一个
改动在核心已被证明覆盖之后就值得合入,不必等尾巴跑完。

一次全量 linux run 是 13427s 成员墙钟,前四名占 52%(grpc-codegen 3363s、
grpc-module 1724s、opencv-module-dnn 1017s、protobuf-protoc 945s)。按这个顺序,
约 55 个成员在第一个重量级启动前就已报完 —— 于是「除了那四个已知的贵成员之外
全绿」是一个**存在的、早早出现的、可以判断的状态**。贵的先跑则没有这种中间状态:
一小时内什么都说明不了,然后一次性全部结束。

超时的后果按同一逻辑读:分片现在丢的是贵成员而不是便宜成员 —— 那正是维护者本来
就会选择跳过的那一半,数量少,且在 tests/member-timings.tsv 里逐个有名有姓。

装箱与顺序是两个问题,这里只动后者:LPT 仍按降序装箱(否则箱子会不均)。三平台
七个分片逐一比对过成员集合 —— 完全一致。单片路径(`--shard 0/1`)同样升序,所以
本地与 CI 的顺序是同一个。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant