feat(targetside): five layers, and the largest of them had no name - #494
Merged
Conversation
一次真实使用暴露了十条问题:一个 hello-world 工程,`[dependencies]` 里只加了一行 `openkal-llvm-runtime`,随后在四个目标上连续失败,每一次的错误信息都来自编译器, 没有一条提到 mcpp 作出的决定。 `01d6cef` 把「目标侧从哪来」收敛到了一处解析,但它的消费者仍停在旧模型上。 本次补齐模型本身。 ── 1. 第五层:compiler-runtime ────────────────────────────── 实测 `openkal-llvm-runtime` 编译的 729 个对象里,**498 个是 compiler-rt 的 builtins**、21 个是 libunwind 的。这个包最大的一块此前声明在 `mcpp:c++-abi` 名下 —— 而 `__udivti3` 是一个纯 C 程序需要的东西,与 C++ 无关。 把 builtins 算作 C++ 运行时的一部分,与本文件开头记录的那个缺陷同形: 一个交叉到 macOS 的 C 程序被问「有没有 C++ 运行时」,答「没有」, 链接行因而保留了载荷自带的 libc++。**一个只有部分程序需要的层仍然是层。** `compiler` 同时成为一层,因为规则二需要一个被检查的对象。它是唯一一个 包不能供给的层:族与族之间的差异(flag 拼写、模块模型、BMI 格式、驱动 cfg) 是引擎必须持有的事实,不是数据能描述的。⚠️ `compiler` 层上报的是**族名**(`llvm`)而不是驱动名(`clang`)。 使用者书写的每一处都用族名,报告用驱动名会让 `requires = ["mcpp:compiler=llvm"]` 永远不可满足。 ── 2. requires:在引擎里不出现实现名的前提下执行分层规则 ──── requires = ["mcpp:compiler=llvm"] libc++ 的源码、尤其它的 std 模块源,由 clang 编译。把它递给 gcc 会在 libc++ 自己的头文件深处失败。该事实属于包 —— 在引擎里写 `if (stdlib == "libc++" && compiler == gcc)` 会把两个实现名放进引擎。 实测,修复前后同一条命令: error: std module precompile failed (rc=1): …/std.cppm:16: fatal error: __config: No such file or directory error: `openkal-llvm-runtime@0.1.1` requires the compiler to be `llvm`. compiler gcc (16.1.0, payload) required llvm (required by openkal-llvm-runtime@0.1.1) Select that compiler — yours outranks mcpp's own default: mcpp toolchain default llvm⚠️ 检查在**编译开始之前**运行,这正是声明它的全部意义。 ── 3. 规则一:每层恰好一个供给者 ──────────────────────────── 此前两个包供给同一层时,**图遍历顺序里第一个静默胜出** —— 那个顺序既不是 作者写的,也不是他能预测的 —— 而落选者的 `[build]` 段仍然进入命令行, 于是一份 C 库的头配另一份 C 库的实现。 C 库、内核接口、C++ 运行时是**互斥的选择**,不是可叠加的贡献; `[build] runner` 早已按同一条规则处理。判据是失败模态:选错不会让链接失败, 会得到一个能跑、偶尔崩的程序。 ── 4. std-module* 从 [package] 移入 [build] ──────────────── 模块源是这个包的一个翻译单元 —— 它以包的 include 目录与定义被编译, 引擎自己的注释早就这么写了。放在 `[package]` 下损失的恰恰是位置所决定的那件事: `[build]` 可条件化而 `[package]` 不可,于是一个在多种 C 库之上供给同一 C++ 运行时的包,无法为不同 C 库给出不同的 flag。`-D_GNU_SOURCE` 对 musl 与 glibc 是对的,对 picolibc 是错的,而此前没有拼写能表达这个差别。 `[package]` 写法保留为别名。 ── 5. 报告按需暴露 ──────────────────────────────────────── 零配置构建的五个层全部解析自同一份载荷,五行 `(payload)` 回答的是无人提出的 问题。默认只列出来源不是编译器载荷的层;`MCPP_VERBOSE=1` 列出全部; **诊断始终列出它所依据的每一层**,包括平凡的那些 —— 省略证据的错误信息 无法被读者复核。 Target x86_64-linux-gnu ← 零配置:一行 ── 6. Family 去掉 OpenkalLlvm ────────────────────────────── 它命名同一份 llvm 载荷,携带的是一条关于目标侧的事实,而 `mcpp.targetside` 从包的声明中解析该事实。保留枚举项的代价不止是一条死分支: 可用工具链列表按族枚举,一份载荷挂在两个族名下就出现两次, 而安装状态按族记录 ⇒ **第二份被报成未安装,并被推荐给已经装了它的人。** 拼写归一为 `llvm` 保留(e2e 269 守着)。 ── 7. 词表 pin 替换用户默认时,说出来 ──────────────────────⚠️ 让全局默认压过词表 pin 的做法被实测否掉:一个无依赖的工程、全局默认 `llvm@22.1.8`、`--target x86_64-windows-gnu`,**从能构建变成不能构建** —— clang 单独不携带该目标的 C 运行时,而行所命名的载荷携带。那是升级把一个 可用的构建变成不可用的。 行所 pin 的不是「偏好的编译器」,而是「供给该目标 C 库的载荷」; 用户的默认能否代替它,取决于是否有别的东西供给目标侧 —— 而那要到依赖图 解析之后才知道。因此保留行为,并补上两条它一直欠缺的话: Resolved gcc@16.1.0 → x86_64-windows-gnu → … target default for x86_64-windows-gnu, replacing your llvm@22.1.8 — override with `[target.x86_64-windows-gnu] toolchain` warning: this project's target side comes from its dependency graph, so llvm@22.1.8 would have served x86_64-windows-gnu. 第二条在图已知之后发出 —— 那是「这次替换本可不必」第一次可判定的时刻。⚠️ 结构性修法是把 pin 的决定与目标侧一样后移。未在本次落地:`tc` 在解析后到 图之间被读写 **39 处**(有效三元组、cross flag、目标 sysroot、MSVC 运行时契约), 在那里重解析会让它们乱序重做。 ── 兼容性 ──────────────────────────────────────────────── * `hosted-standard-library` 继续表示 C++ 层; * `openkal-llvm` 拼写继续解析; * `[package]` 下的三个 std-module 键继续被接受; * 实测:**旧引擎(2026.8.24.1)读带 `requires` 的清单构建成功** —— TOML 侧忽略未知键,xpkg 侧警告而非报错。已发布的包因此可以先行声明。 ── 测试 ────────────────────────────────────────────────── 单元:test_targetside 26 个(五层 × 四来源、能力语法五层全覆盖、 规则一二各自的诊断文本),全套 93 passed / 0 failed。 e2e:新增 280(五层与报告收窄)、281(两条规则各自的拒绝 + 包不得供给 compiler); 268/269 的断言改用 MCPP_VERBOSE 读取全栈 —— 它们的意图不变, 变的是默认报告不再打印载荷层。⚠️ 本机 e2e 279 条中 26 条红,**逐条与基线二进制对照后全部为既有失败** (本机全局默认是 llvm,而它们断言 GCC 的 `gcm.cache`)。CI 是判据。 设计文档:.agents/docs/2026-08-24-target-side-design.md 规范:docs/spec/target-side.md(SPEC-002) 使用文档:docs/14-target-side.md + docs/zh/14-target-side.md
…s row
自查发现:`format_layers` 用「到目前为止有没有打印过东西」来决定一个缺席的层
要不要打印,而这让它依赖**行序**。
裸机构建的 `kernel-abi` 是缺席的,并且排在预制的 `c-abi` 之上,于是:
Target riscv64-none-elf
c-abi picolibc-riscv (xim:picolibc-riscv@1.8.12, prebuilt)
c++-abi —
缺席的 `kernel-abi` 被吞掉了,而下方同样缺席的 `c++-abi` 打印了 ——
两个同为「这一层没有供给者」的陈述,一个在场一个不在场。
「一台裸机没有内核」正是这份报告要说的话之一。改成两遍:
先判定这次是否展示整栈,再逐行输出。
Target riscv64-none-elf
kernel-abi —
c-abi picolibc-riscv (xim:picolibc-riscv@1.8.12, prebuilt)
c++-abi —
test: TargetSideReport.AnAbsentLayerAboveAPrintedOneIsStillPrinted;
test_targetside 27 passed。
…ap, not a typo⚠️ 这条由生态 CI 实测暴露,而它让层名词表**对已发布的包永远不可扩展**。 `openkal-llvm-runtime` 声明本次新命名的那一层,被上一版引擎读到: error: dependency 'openkal-llvm-runtime': mcpp.toml: error: `provides = ["mcpp:compiler-runtime=compiler-rt"]` names no capability mcpp knows. 保留前缀是闭集,为的是让**拼写错误成为错误而不是一个被静默禁用的行为**。 在解析期直接拒绝,让这个闭集在第二个、没人打算要的意义上也闭上了: 一个声明了「读者发布之后才被命名的层」的包,**整份清单加载不了**。 ── 谁的清单决定答案 ────────────────────────────────────── * **根工程**的清单里出现未知层名 ⇒ **错误**。那是作者自己的拼写, 而他正看着这次构建。 * **依赖**的清单里出现未知层名 ⇒ **警告并忽略该层**。那份清单是对着一个更新的 引擎写的,而「忽略未知的并说出来」正是本引擎对其它每一种未知键已有的做法 (`warn_unknown_xpkg_keys` 的注释:should not fail outright, only tell the user what it ignored)。⚠️ 警告放在扫描**全部包**的那个循环里,不放在 `warn_unknown_xpkg_keys`: 后者只走到经索引解析的依赖,而 path / git 依赖自带清单,先前一条警告都收不到。⚠️ 这条规定只对**此后的**引擎生效。一个包若要声明某个层名,其使用者的引擎仍须 不早于该层名被引入的版本 —— 本次修的是「从今往后可扩展」,不是追溯。 test: e2e 281 增两格(依赖声明未知层 ⇒ 构建成功且点名被忽略的层; 根工程拼错 ⇒ 报错并列出五个层名);unit 93 passed。 spec: SPEC-002 §5.1 拆成两条;docs/14 中英同步。
Sunrisepeak
added a commit
to mcpplibs/openkal-llvm-runtime
that referenced
this pull request
Aug 24, 2026
⚠️ 实测:该层名在 2026.8.24.2 之前的每一个已发布构建工具上都让整份清单 加载失败 —— 不是「该层被忽略」,是这个包用不了: error: dependency 'openkal-llvm-runtime': mcpp.toml: error: `provides = ["mcpp:compiler-runtime=compiler-rt"]` names no capability mcpp knows. 那条拒绝本身已在 mcpp 2026.8.24.2 修掉(依赖的清单里出现未知层名改为警告并 忽略,根工程自己的仍然报错),但**修复不能追溯到已经发布出去的工具**。 本仓 CI 的 MCPP_VERSION 目前是 2026.8.19.4。 `requires = ["mcpp:compiler=llvm"]` 保留 —— 实测旧引擎忽略未知的 [package] 键, 因此这一半今天就能发。声明留在注释里,连同它的依据与解除条件。 engine: mcpp-community/mcpp#494
生态 e2e 暴露两处: 1. 警告只说了「不认识」,没有列出**存在的**层名 —— 而它替代的那条错误列了。 一条比它所替代的错误说得更少的警告,是一条穿着更轻处罚的更差诊断。 两处警告(依赖清单、任意包)改为复用 `parse_capability` 的原文。 2. e2e 268 的断言写的是**严重级别**,而这个前缀存在的理由是**不静默**。⚠️ 但一条断言若跟着策略改就该说清它现在测什么:改为断言三件事 —— 拼错的名字被报出、被拼错的那一层**没有被填上**、以及旁边拼对的那一条 **仍然解析**(一个坏条目只该花掉一层,不是整个包)。 删掉的那条「必须在编译开始之前被拒绝」不再成立,而它成立的地方仍被守着: 根工程自己的拼写错误与 `requires` 不满足,都在 e2e 281 里,都在编译之前。 unit 93 passed;e2e 268/269/280/281 全绿。
macOS CI 报出两件事,一件是我的测试写错,一件是这份报告刚刚让一个既有缺陷
变得可见。
── 1. `c-abi glibc (payload)`,在 macOS 上 ────────────────
`resolve` 对没有 env 段的三元组回落到字面量 `glibc`,而 macOS 的规范三元组
正是没有 env 段的。这条一直在,但此前报告只打印「这次构建有话要说」的那几层,
于是一个错误的标签从未被打印出来;把整栈显示出来,错标签就成了错陈述。
c-abi glibc (payload) ← macOS
改为按平台取名:macOS `libSystem`、Windows `ucrt`、其余 `glibc`;
三元组自己说了 env 的仍以它为准。
⚠️ 这几个名字可以写在引擎里,而包供给的实现名不可以 —— 区别在于载荷是 mcpp
自己分发的,它知道里面装着什么。保留能力语法存在的理由正是守住这条界线。
── 2. `c++-abi` 在 BSD grep 的 ERE 里是非法的 ────────────
grep: repetition-operator operand invalid
`c++` 在扩展正则里是「重复算子作用于重复算子」,GNU grep 容忍,BSD grep 直接
拒绝。e2e 280 的层名循环改用 `grep -F` 定长匹配。
test: TargetSideResolve.ThePayloadCLibraryIsNamedForItsPlatform;
unit 93 passed;本机全量 e2e 288 pass / 26 fail,失败集与基线逐条相同。
Sunrisepeak
force-pushed
the
feat/target-side-five-layers
branch
from
August 24, 2026 11:48
995c962 to
3c45cfe
Compare
Sunrisepeak
added a commit
to mcpplibs/openkal-llvm-runtime
that referenced
this pull request
Aug 24, 2026
…layer⚠️ 实测:该层名在 2026.8.24.2 之前的每一个已发布构建工具上都让整份清单 加载失败 —— 不是「该层被忽略」,是这个包用不了: error: dependency 'openkal-llvm-runtime': mcpp.toml: error: `provides = ["mcpp:compiler-runtime=compiler-rt"]` names no capability mcpp knows. 那条拒绝本身已在 mcpp 2026.8.24.2 修掉(依赖的清单里出现未知层名改为警告并 忽略,根工程自己的仍然报错),但**修复不能追溯到已经发布出去的工具**。 本仓 CI 的 MCPP_VERSION 目前是 2026.8.19.4。 `requires = ["mcpp:compiler=llvm"]` 保留 —— 实测旧引擎忽略未知的 [package] 键, 因此这一半今天就能发。声明留在注释里,连同它的依据与解除条件。 engine: mcpp-community/mcpp#494
Sunrisepeak
added a commit
to mcpplibs/openkal-windows
that referenced
this pull request
Aug 24, 2026
…C library
-[target.'cfg(all(windows, env = "gnu"))'.build]
+[target.'cfg(all(windows, not(env = "msvc")))'.build]
ldflags = ["-lntdll", "-lsynchronization", "-lshell32", "-lkernel32"]
这四个是 Win32 导入库 —— 本包所实现的**平台接口**的性质,不是 C 库的性质。
`env = "gnu"` 一直在代表「GNU/PE 的 ABI 而不是 MSVC 的」,而在传统栈上两者重合。
它们在 C 库改由依赖图供给的那一刻不再重合:一次 `x86_64-windows-gnu` 的
openkal 构建解析出的 C 库是 musl —— mcpp 自己的报告就这么打印:
kernel-abi openkal (openkal-windows@0.1.3, graph)
c-abi musl (openkal-musl@0.3.3, graph)
而拼作 `x86_64-windows-musl` 的是同一次构建的诚实名字。旧谓词下第二个拼法
不带这四个库中的任何一个,实测:
ld.lld: error: undefined symbol: __declspec(dllimport) GetStdHandle
ld.lld: error: undefined symbol: __declspec(dllimport) WriteFile
…
两份 build.ninja 的 ldflags 逐 token 对比,差别只有这四个 token;
连 `--target=x86_64-w64-windows-gnu` 都完全相同 —— 两个 mcpp 三元组翻译成
同一个 LLVM 三元组。
实测(改动后):
Finished dev in 2.75s
test3.exe: PE32+ executable (console) x86-64, 14 sections
imports: ntdll.dll / api-ms-win-core-synch-l1-2-0.dll / SHELL32.dll / KERNEL32.dll
wine test3.exe → Hello from test3!
`cxxflags = ["-fno-exceptions", "-fno-rtti"]` 在同一张表里,因此一并生效于
两种拼法 —— 那也是对的:它们的理由同样是 ABI 而非 C 库。
⚠️ 兼容性:`x86_64-windows-gnu` 的求值结果不变(`gnu != msvc`),
新增覆盖的是 `msvc` 之外的其它 env 拼法。
related: mcpp-community/mcpp#494
Sunrisepeak
added a commit
to mcpplibs/openkal-llvm-runtime
that referenced
this pull request
Aug 24, 2026
…eeds
这个包编译 729 个对象,其中 **498 个是 compiler-rt 的 builtins**、21 个是
libunwind 的、159 个 libcxx、51 个 libcxxabi。也就是说它最大的一块此前声明在
`mcpp:c++-abi` 名下 —— 而 `__udivti3` 及其同类是一个**纯 C 程序**需要的东西,
与 C++ 无关。
把 builtins 算作 C++ 运行时的一部分,等价于断言 C 程序不需要整数除法。
该断言已经产生过一次实测缺陷:一个交叉到 macOS 的 C 程序被问「有没有 C++
运行时」,答「没有」,链接行因而保留了编译器载荷自带的 libc++,
把一个 Linux 共享对象递给了 Mach-O 链接器。
provides = [..., "mcpp:compiler-runtime=compiler-rt"]
── requires ──────────────────────────────────────────────
libc++ 的源码、尤其它的 std 模块源,由 clang 编译。递给 gcc 的实测结果:
fatal error: __config: No such file or directory
该消息命名一个读者从未打开过的文件,以及一个 mcpp 从未作出的决定。
把需求写在包里,构建工具就能在编译任何东西之前拒绝这个组合,
并且能够指出族名,而不必把这条事实写进构建工具:
requires = ["mcpp:compiler=llvm"]
实测(mcpp 2026.8.24.2):
error: `openkal-llvm-runtime@0.1.1` requires the compiler to be `llvm`.
compiler gcc (16.1.0, payload)
required llvm (required by openkal-llvm-runtime@0.1.1)
Select that compiler — yours outranks mcpp's own default:
mcpp toolchain default llvm
── 兼容性 ────────────────────────────────────────────────
⚠️ 实测:**旧引擎(mcpp 2026.8.24.1)读带 `requires` 的清单构建成功** ——
TOML 侧忽略未知键。因此本次声明不要求使用者先升级。
`hosted-standard-library` 与 `mcpp:c++-abi=libc++` 两条拼写均保留。
engine: mcpp-community/mcpp#494
Sunrisepeak
added a commit
to mcpplibs/openkal-llvm-runtime
that referenced
this pull request
Aug 24, 2026
…layer⚠️ 实测:该层名在 2026.8.24.2 之前的每一个已发布构建工具上都让整份清单 加载失败 —— 不是「该层被忽略」,是这个包用不了: error: dependency 'openkal-llvm-runtime': mcpp.toml: error: `provides = ["mcpp:compiler-runtime=compiler-rt"]` names no capability mcpp knows. 那条拒绝本身已在 mcpp 2026.8.24.2 修掉(依赖的清单里出现未知层名改为警告并 忽略,根工程自己的仍然报错),但**修复不能追溯到已经发布出去的工具**。 本仓 CI 的 MCPP_VERSION 目前是 2026.8.19.4。 `requires = ["mcpp:compiler=llvm"]` 保留 —— 实测旧引擎忽略未知的 [package] 键, 因此这一半今天就能发。声明留在注释里,连同它的依据与解除条件。 engine: mcpp-community/mcpp#494
Sunrisepeak
added a commit
to mcpplibs/openkal-windows
that referenced
this pull request
Aug 24, 2026
…C library (#6) -[target.'cfg(all(windows, env = "gnu"))'.build] +[target.'cfg(all(windows, not(env = "msvc")))'.build] ldflags = ["-lntdll", "-lsynchronization", "-lshell32", "-lkernel32"] 这四个是 Win32 导入库 —— 本包所实现的**平台接口**的性质,不是 C 库的性质。 `env = "gnu"` 一直在代表「GNU/PE 的 ABI 而不是 MSVC 的」,而在传统栈上两者重合。 它们在 C 库改由依赖图供给的那一刻不再重合:一次 `x86_64-windows-gnu` 的 openkal 构建解析出的 C 库是 musl —— mcpp 自己的报告就这么打印: kernel-abi openkal (openkal-windows@0.1.3, graph) c-abi musl (openkal-musl@0.3.3, graph) 而拼作 `x86_64-windows-musl` 的是同一次构建的诚实名字。旧谓词下第二个拼法 不带这四个库中的任何一个,实测: ld.lld: error: undefined symbol: __declspec(dllimport) GetStdHandle ld.lld: error: undefined symbol: __declspec(dllimport) WriteFile … 两份 build.ninja 的 ldflags 逐 token 对比,差别只有这四个 token; 连 `--target=x86_64-w64-windows-gnu` 都完全相同 —— 两个 mcpp 三元组翻译成 同一个 LLVM 三元组。 实测(改动后): Finished dev in 2.75s test3.exe: PE32+ executable (console) x86-64, 14 sections imports: ntdll.dll / api-ms-win-core-synch-l1-2-0.dll / SHELL32.dll / KERNEL32.dll wine test3.exe → Hello from test3! `cxxflags = ["-fno-exceptions", "-fno-rtti"]` 在同一张表里,因此一并生效于 两种拼法 —— 那也是对的:它们的理由同样是 ABI 而非 C 库。⚠️ 兼容性:`x86_64-windows-gnu` 的求值结果不变(`gnu != msvc`), 新增覆盖的是 `msvc` 之外的其它 env 拼法。 related: mcpp-community/mcpp#494
Sunrisepeak
added a commit
to mcpplibs/openkal-llvm-runtime
that referenced
this pull request
Aug 24, 2026
…layer (#2) * feat: declare the compiler-runtime layer and the compiler family it needs 这个包编译 729 个对象,其中 **498 个是 compiler-rt 的 builtins**、21 个是 libunwind 的、159 个 libcxx、51 个 libcxxabi。也就是说它最大的一块此前声明在 `mcpp:c++-abi` 名下 —— 而 `__udivti3` 及其同类是一个**纯 C 程序**需要的东西, 与 C++ 无关。 把 builtins 算作 C++ 运行时的一部分,等价于断言 C 程序不需要整数除法。 该断言已经产生过一次实测缺陷:一个交叉到 macOS 的 C 程序被问「有没有 C++ 运行时」,答「没有」,链接行因而保留了编译器载荷自带的 libc++, 把一个 Linux 共享对象递给了 Mach-O 链接器。 provides = [..., "mcpp:compiler-runtime=compiler-rt"] ── requires ────────────────────────────────────────────── libc++ 的源码、尤其它的 std 模块源,由 clang 编译。递给 gcc 的实测结果: fatal error: __config: No such file or directory 该消息命名一个读者从未打开过的文件,以及一个 mcpp 从未作出的决定。 把需求写在包里,构建工具就能在编译任何东西之前拒绝这个组合, 并且能够指出族名,而不必把这条事实写进构建工具: requires = ["mcpp:compiler=llvm"] 实测(mcpp 2026.8.24.2): error: `openkal-llvm-runtime@0.1.1` requires the compiler to be `llvm`. compiler gcc (16.1.0, payload) required llvm (required by openkal-llvm-runtime@0.1.1) Select that compiler — yours outranks mcpp's own default: mcpp toolchain default llvm ── 兼容性 ────────────────────────────────────────────────⚠️ 实测:**旧引擎(mcpp 2026.8.24.1)读带 `requires` 的清单构建成功** —— TOML 侧忽略未知键。因此本次声明不要求使用者先升级。 `hosted-standard-library` 与 `mcpp:c++-abi=libc++` 两条拼写均保留。 engine: mcpp-community/mcpp#494 * feat: require an llvm-family compiler, and name the compiler-runtime layer⚠️ 实测:该层名在 2026.8.24.2 之前的每一个已发布构建工具上都让整份清单 加载失败 —— 不是「该层被忽略」,是这个包用不了: error: dependency 'openkal-llvm-runtime': mcpp.toml: error: `provides = ["mcpp:compiler-runtime=compiler-rt"]` names no capability mcpp knows. 那条拒绝本身已在 mcpp 2026.8.24.2 修掉(依赖的清单里出现未知层名改为警告并 忽略,根工程自己的仍然报错),但**修复不能追溯到已经发布出去的工具**。 本仓 CI 的 MCPP_VERSION 目前是 2026.8.19.4。 `requires = ["mcpp:compiler=llvm"]` 保留 —— 实测旧引擎忽略未知的 [package] 键, 因此这一半今天就能发。声明留在注释里,连同它的依据与解除条件。 engine: mcpp-community/mcpp#494
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.
Summary
一次真实使用暴露了十条问题:一个 hello-world 工程,
[dependencies]里只加了一行openkal-llvm-runtime,随后在四个目标上连续失败,每一次的错误信息都来自编译器,没有一条提到 mcpp 作出的决定。
01d6cef把「目标侧从哪来」收敛到了一处解析,本 PR 补齐模型本身。compiler-runtime。 实测openkal-llvm-runtime编译的 729 个对象里 498 个是 compiler-rt 的 builtins、21 个是 libunwind 的 —— 此前全部声明在mcpp:c++-abi名下。__udivti3是一个纯 C 程序需要的东西。compiler同时成为一层(唯一一个包不能供给的层),因为规则二需要一个被检查的对象。requires = ["mcpp:<层>=<实现>"]。 在引擎里不出现实现名的前提下执行分层规则。检查在编译开始之前运行。[build]段仍进入命令行。std-module*从[package]移入[build]。 位置决定的那件事就是可条件化:-D_GNU_SOURCE对 musl/glibc 是对的、对 picolibc 是错的,此前没有拼写能表达。MCPP_VERBOSE=1输出五层;诊断始终输出全部。Family去掉OpenkalLlvm。 一份载荷挂两个族名 ⇒ 可用列表里出现两次,第二份被报成未安装并推荐给已经装了它的人。拼写归一为llvm保留。修复前后,同一条命令
让全局默认压过词表 pin:一个无依赖的工程、全局默认
llvm@22.1.8、--target x86_64-windows-gnu,从能构建变成不能构建 —— clang 单独不携带该目标的C 运行时。那是升级把可用的构建变成不可用的,已回退。
行所 pin 的不是「偏好的编译器」而是「供给该目标 C 库的载荷」,用户默认能否代替它
取决于是否有别的东西供给目标侧 —— 那要到图解析之后才知道。因此保留行为并补上两条
它一直欠缺的话(状态行说明替换 + 图已知后指出这次替换本可不必)。
结构性修法是把 pin 的决定后移,未在本 PR 落地:
tc在解析后到图之间被读写 39 处。兼容性
hosted-standard-library继续表示 C++ 层openkal-llvm拼写继续解析(e2e 269 守着)[package]下三个 std-module 键继续被接受requires的清单构建成功 —— TOML 侧忽略未知键,xpkg 侧警告而非报错。已发布的包可以先行声明。Test plan
test_targetside26 个(五层 × 四来源、能力语法五层全覆盖、规则一二各自的诊断文本);全套 93 passed / 0 failed280_target_side_layers(报告收窄 + verbose 五层 + 编译器层报族名)、281_target_side_rules(requires 拒绝 / 两个供给者 / 包不得供给 compiler),均本机通过MCPP_VERBOSE读取全栈 —— 意图不变,变的是默认报告不再打印载荷层gcm.cache)。CI 是判据。check_docs_style.sh通过(中英标题层级序列一致、参考文档无第二人称)生态侧(独立 PR)
mcpplibs/openkal-llvm-runtime与mcpplibs/openkal-windows的适配随后提交。设计文档
.agents/docs/2026-08-24-target-side-design.md;规范docs/spec/target-side.md(SPEC-002);使用文档docs/14-target-side.md+ 中文版。