fix(toolchain,build): absent SubOS description must not stop the build; C-only units link with the C driver - #429
Merged
Merged
Conversation
…uild; link C-only units with the C driver (2026.8.15.2) 三条互不相关的缺陷,共同点是「一个事实的缺失被当成了矛盾」。 #427 —— `mcpp build` 与 `mcpp toolchain install` 在 Linux 上硬失败 `ensure_post_install_fixup` 在调用方没给出运行时身份时,自己去读硬编码的 `<xlings home>/subos/default`,并把「读不到」变成 `std::unexpected`。触发条件与 沙箱无关:默认 SubOS 由早于 `subos_info` 块的 xlings 创建即可(实测现场是一个 16 字节、只有 `{"workspace":{}}` 的清单)。`allow_host_libs` 救不了 —— 该判定 发生在 hermeticity 策略之前;`mcpp toolchain install` 同样死。已发布三周。 真因是没做完的迁移。调用点的注释写着「fixup 是 RuntimeBinding 的消费者」, `runtimeId` 参数也早已加上并从四处传入,旧的自行推导没有删。而被它保护的 `gcc_post_install_fixup` 本来就正确处理空值(warning 降级)—— 那个 `else` 从未执行过。 * 删掉第二处推导。身份只能来自调用方。 * 未知降级,矛盾仍然失败:身份为空 ⇒ 跳过并说明;身份声明了却兑现不了 ⇒ 报错。 * 严重程度归调用方:`build` 以 info 级说明一次(按载荷去重), `toolchain install` 以 warning 级说明并给出 `xlings self update`。 * 降级不写 marker,以免「什么都没做」被读成「已经做过」。 * `toolchain_install` 自己解析一次 RuntimeBinding —— 缺了这一步,单删兜底会让 它永远跳过 fixup,把硬失败换成静默的坏安装。 #426 —— 纯 C 的共享库依赖 libstdc++ 所有链接一律走 `$cxx`。同一个对象、同一份 ldflags,只换驱动的实测对照: g++ 给出 `libstdc++.so.6` `libm.so.6` `libgcc_s.so.1` `libc.so.6`,gcc 只给出 `libc.so.6` —— 三个 NEEDED 全部由驱动带入,零真实引用。 * 按内容选驱动,谓词照 `unit_needs_std` 的形状写;⚠️ 查不到的对象(action 产物) 保守判为 C++,与那个谓词相反。 * 只换驱动不够:`-lstdc++exp` 是显式命名的,`-stdlib=libc++` 与 macOS 的 `libc++.a` 路径在契约表里。故 `CompileFlags` 增加 `ldC`(与 `ld` 同一表达式 产生,`ld` 由构造保证不变),契约表增加 `unitFlagsC`(`-static` 与 `-static-libgcc` 属于 libc/编译器运行时,保留)。 * 顺带补上 `std.compat.o` 缺失的 `unit_needs_std` 收窄 —— #416 只修了 `std.o`。 main 的 bench pin 守卫 —— 断言本身是错的 发版收尾 bump `.xlings.json` 后三平台 e2e 全红。该守卫要求 `reference_mcpp` 等于 bootstrap pin,理由是「参照臂就是 CI 装的那个」;两半都不成立(标准集不在任何 workflow 里;bootstrap pin 是自举下界,可合理滞后),而它声称防止的危险已由 `run-standard.sh` 自己防住(按精确版本解析 + 要求二进制自述版本)。 * 删掉跨文件相等断言,保留编译器 pin 那条真耦合。 * 报告表头直接写出实测版本(engine 键本来就带),运行时把请求与实际解析到的 路径写进 `meta.json`。 文档 * `edit-body` 改写为三种情形的表(`.cppm` 移动行号 / `.cppm` 原地等长 / 独立 `.cpp`),不再读作否定级联抑制的价值。 *⚠️ 订正 SPEC.md 中已被实测证否的解释:决定因素是行号移动,不是「成员函数体 进 BMI」——`Version::str()` 原地修改后 BMI 逐字节相同。 * 记录一个具名缺口:没有「原地等长修改」的场景,而那正是日常改动。 测试 * `tests/unit/test_post_install.cpp` +4:门的四个分支。⚠️ 必须是单测 —— 任何低成本 e2e 都用符号链接继承载荷,而 fixup 对继承载荷提前返回, 被测代码一行都执行不到(与 221 是同一种假绿)。 * `tests/e2e/237` 用户可见契约;`tests/e2e/238` 驱动选择,两个方向都钉。
⚠️ 本机绿 CI 红,方向与平时相反:这次是**本机有** runner 没有的东西。 原来的绿色一半是「加上 `allow_host_libs = true` 必须能构建」。落回宿主需要宿主 真有一份 C 运行时,而 runner 上 `crt1.o` / `crti.o` / `libm` 一个都没有 —— 那半个断言实际在断言运行机器的属性,不是 mcpp 的行为。 换成不依赖机器的对照:**同一个 home、同一批载荷、同一个工程,只给 SubOS 补上 `subos_info` 块**,必须构建成功。这同时更强 —— 它证明第 1 部分里的失败确实只是 降级,而不是这个环境本来就编不出东西。 绑定哪个 glibc 也不能猜:向真实 home 的 `subos_info.runtime` 要,取不到才回落到 目录扫描。装了两个 glibc 载荷的机器上,`ls | head -1` 会按字母序挑中工具链没有 针对它打过补丁的那个,让对照因为与被控变量无关的原因失败。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #427, closes #426. Also fixes
main, which is red on all three platforms.三条互不相关的缺陷,共同点是一个事实的缺失被当成了矛盾。
#427 —
mcpp build/mcpp toolchain install在 Linux 上硬失败ensure_post_install_fixup在调用方没给出运行时身份时,自己去读硬编码的<xlings home>/subos/default,并把「读不到」变成std::unexpected。触发条件与沙箱无关。 默认 SubOS 由早于
subos_info块的 xlings 创建即可 ——实测现场是一个 16 字节、只有
{"workspace":{}}的清单。实测影响面(同一环境):mcpp buildmcpp build+allow_host_libsmcpp toolchain install对照实验:只补一个
subos_info块、其它不动 → 构建成功 0.11s。那道门是唯一的墙。真因是一次没做完的迁移
调用点
prepare.cppm:953的注释写着「fixup 是 RuntimeBinding 的消费者」,runtimeId参数也早已加上并从四处传入,旧的自行推导没有删。而被它保护的gcc_post_install_fixup:439本来就正确处理空值(warning 降级)—— 那个else从未执行过。
foo却按default打补丁」这条独立缺陷随之消失。
build以 info 级说明一次(按载荷去重),toolchain install以 warning 级说明并给出
xlings self update。toolchain_install自己解析一次 RuntimeBinding —— 缺了这一步,单删兜底会让它永远跳过 fixup,把硬失败换成静默的坏安装。
#426 — 纯 C 的共享库依赖 libstdc++
同一个对象、同一份 ldflags,只换驱动的实测对照:
NEEDEDg++libstdc++.so.6libm.so.6libgcc_s.so.1libc.so.6gcclibc.so.6唯一像 C++ 的未定义符号是
__cxa_finalize@GLIBC_2.2.5(glibc 的弱符号)。三个 NEEDED全部由驱动带入,零真实引用。
unit_needs_std的形状写。保守判为 C++,与那个谓词的取值相反。
-lstdc++exp是显式命名的,-stdlib=libc++与 macOS 的libc++.a路径在契约表里。故CompileFlags增加ldC(与ld同一表达式产生,
ld由构造保证不变),契约表增加unitFlagsC(-static与-static-libgcc属于 libc / 编译器运行时,保留)。
std.compat.o缺失的unit_needs_std收窄 —— obj/std.o 被无条件链进每个单元:纯 C 的 compat 包因此依赖 libstdc++.so.6 #416 只修了std.o。MSVC 无变化:
separateLinker直接调 link.exe,驱动不参与链接。main的 bench pin 守卫 —— 断言本身是错的发版收尾 bump
.xlings.json后三平台 e2e 全红(linux ·windows ·
macos)。
该守卫要求
reference_mcpp等于 bootstrap pin,理由是「参照臂就是 CI 装的那个」。两半都不成立:标准集不在任何 workflow 里(开发机手工跑,
runtimedir并存多版本);bootstrap pin 是自举下界,可合理滞后于最新发布。而它声称防止的危险 ——「old 列静默变成
另一个 release」—— 已由
run-standard.sh自己防住(按精确版本解析 且要求二进制自述版本,取不到就明说列缺失)。
mcpp@<ver>),运行时把请求与实际解析到的路径写进
meta.json。文档
edit-body改写为三种情形的表(.cppm移动行号 /.cppm原地等长 / 独立.cpp),不再读作否定级联抑制的价值。
SPEC.md中已被实测证否的解释:决定因素是行号移动,不是「成员函数体进 BMI」——
Version::str()原地修改后 BMI 逐字节相同。docs/05-mcpp-toml.md(中英)说明 C-only 目标不承担 C++ 运行时契约。测试
tests/unit/test_post_install.cpp+4:门的四个分支。任何低成本 e2e 都用符号链接继承载荷,而 fixup 对继承载荷提前返回,被测代码一行都
执行不到(与
221是同一种假绿)。原有 4 个DetectBakedLoader测试保留。tests/e2e/237用户可见契约;tests/e2e/238驱动选择,两个方向都钉(纯 C →
c_shared且无 C++ 运行时;含一个 C++ TU →cxx_shared;C++ 二进制 →cxx_link且能跑)。分析与自我 review:
.agents/docs/2026-08-15-issues-426-427-analysis.md