Skip to content

Commit d38b841

Browse files
committed
plan: three items measured rather than assumed, and one of them is not a new target
I1's premise, measured. Not "it breaks" but three of three, each of them correct POSIX: `open("/dev/urandom")`, `fopen("/dev/null")` and a write under `/tmp` all fail on x86_64-windows-gnu and all succeed on x86_64-linux-gnu. Reading the port: `okm_resolve()` is the single chokepoint every path-taking syscall passes through, so the synthetic nodes belong there and NOT in open --- recognising them only in open leaves `stat("/dev/null")` failing, and POSIX programs do stat it. `/tmp` is a directory mapping rather than a character device and probably belongs to the preopen set instead. I2's engine-side criterion, measured: a minimal C library declaring `presents = "windows"` with llp64 and 16-bit wchar builds for x86_64-windows-gnu with ZERO engine changes, and the consumer's own translation unit asserts `_WIN32` present, `__unix__` absent, `__MCPP_TARGET_WINDOWS__` present. What remains for I2 is the package. I3 is new and is NOT a new target. `x86_64-windows-musl` already exists at tier `preview`, and that row wrote its own promotion criterion: verified means built AND RUN, and openkal's CI has the wine step. Measured here: it builds and runs, LP64 with a 32-bit wchar and no `_WIN32`, into its own output directory. The promotion still has to come from CI rather than from a laptop, and the ecosystem is still on `-gnu` --- which puts the one thing this C library is not into its identity, its output directory, its `cfg(env = ...)` and its packed ABI tag. The descriptor-side risk is zero by enumeration: `cfg(env = "gnu")` appears nowhere, and the three descriptors naming the triple do so in comments. One of those comments matters: openkal-uefi's consumer is a different use of the PE target and keeps `-gnu`, so the retarget's scope is the openkal-musl stack, not every PE user.
1 parent e9230df commit d38b841

1 file changed

Lines changed: 76 additions & 2 deletions

File tree

‎.agents/docs/2026-09-21-openkal-ecosystem-completion-and-acceptance.md‎

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,87 @@ macOS,缺 SDK):
454454
**它不是新层**:`openkal-musl` 的 `port/src/okm_fd.c` 已经造了两样同源的东西(描述符表、
455455
单一全局根的名字解析)。合成节点是第三样。
456456
457-
**判据**:节点集合**写死**,不迭代扩张;conformance 逐条断言;集合外的路径行为不变。
457+
**前提已实测(2026-09-21)**,而且比本文初稿写的更锋利——不是「会坏」,是三条全坏。
458+
探针声明 `openkal-llvm-runtime = "0.14.0"`,同一份源码两个目标:
459+
460+
| 判据 | `x86_64-linux-gnu` | `x86_64-windows-gnu`(wine) |
461+
|---|---|---|
462+
| `open("/dev/urandom", O_RDONLY)` + 读 8 字节 | ok | **FAIL** |
463+
| `fopen("/dev/null", "w")` | ok | **FAIL** |
464+
| `fopen("/tmp/…", "w")` | ok | **FAIL** |
465+
| 合计 | `failures: 0` | `failures: 3` |
466+
467+
**插入点是唯一的,而且不在 open 里。** `port/src/okm_fd.c:414` 的 `okm_resolve()` 是
468+
**所有**路径型 syscall 的收口(`okm_syscall.c` 里六个以上调用点经过它)。只在 open 里认
469+
合成节点,`stat("/dev/null")` 仍然会失败,而 POSIX 程序确实会 stat 它。
470+
471+
**`/tmp` 与前四个不是一回事。** 前四个是字符设备,`/tmp` 是目录映射;它更可能属于已有的
472+
预打开目录那一套(`okm_preopen`)。混进同一张表会让这张表同时承担两种语义。
473+
474+
**判据**:节点集合**写死**,不迭代扩张;conformance 逐条断言;集合外的路径行为不变——
475+
这一条要有**反向腿**:`/dev/sda`、`/dev/fd/999`、`/proc/self/maps` 必须仍然按原样失败,
476+
否则这张表就成了吞掉所有 `/dev` 的黑洞。另:`openkal.random` 是可选接口(`kal_random_fill`
477+
在 `okm_syscall.c` 里是弱引用),所以 `/dev/urandom` 在不提供它的实现上必须**仍然失败**。
458478
459479
#### I2 — P6:`openkal-win-ucrt` 形态
460480
461481
**状态**:未实现。设计 §5.6。已验证**引擎侧改动数为 0**。
462482
463-
**判据**:一个 `presents = "windows"` 的 C 库在同一引擎下构建,引擎不认识任何新名字。
483+
**判据(已通过,2026-09-21 实测)**:一个最小的 `presents = "windows"` C 库
484+
(`data-model = "llp64"`、`wchar = 16`)加一个消费者,为 `x86_64-windows-gnu` 构建,
485+
**引擎零改动**:
486+
487+
```
488+
c-abi ucrt (fake-win-ucrt@0.1.0, graph)
489+
Finished dev
490+
```
491+
492+
消费者的一个翻译单元里三条断言全过:`_WIN32` **在**(呈现 windows 就是保留平台自己的
493+
宏)、`__unix__` **不在**、`__MCPP_TARGET_WINDOWS__` **在**(它答的是目标,不是环境)。
494+
495+
**所以 I2 剩下的全部是包本身**(一个真的基于 UCRT 的 C 库),不是引擎。顺带一条读数:
496+
gcc 路线会 warn「宿主 C 库头仍会被搜索」并给出 `llvm@<version>` 的 hint,这正是
497+
host 依赖规则在这里的表现。
498+
499+
#### I3 — 生态改用 `x86_64-windows-musl`(新增,2026-09-21)
500+
501+
**不是新增一个目标——它已经存在**(`triple.cppm`,tier `preview`,PE,pin
502+
`llvm@22.1.8`)。缺的是两件已经到期的事。
503+
504+
**一、tier 可以晋级,而判据由那一行自己写下:**
505+
506+
> `verified` 在这张表里意味着产物**被构建并被运行**过。在 Linux 宿主上跑 PE 需要 wine,
507+
> 而 openkal 的 CI 有那一步——所以这是可测的,tier 在**被测量之后**移动。
508+
509+
本机 + wine 实测(`openkal-llvm-runtime@0.14.0`,mcpp 2026.9.21.2):
510+
511+
```
512+
PE32+ executable (console) x86-64, for MS Windows, 18 sections
513+
ok windows-musl, long=8, wchar=4 exit=0
514+
```
515+
516+
`_WIN32` 不在、`long=8` 即 **LP64**(不是 Windows 的 LLP64)、`wchar=4`、输出目录
517+
`target/x86_64-windows-musl/`。**但晋级要由 CI 给读数**,那一行说的是「openkal 的 CI
518+
有那一步」——所以次序是:先把生态 CI 改到这个目标,读数由 CI 产出,再动那一行。
519+
520+
**二、生态还在用 `-gnu`,而那正是这一行要修的毛病:**
521+
522+
| | mcpp 的身份 | 交给 clang 的 | 真实 c-abi |
523+
|---|---|---|---|
524+
| 今天 | `x86_64-windows-gnu` | `x86_64-w64-windows-gnu` | **musl** |
525+
| 应该 | `x86_64-windows-musl` | `x86_64-w64-windows-gnu` | musl |
526+
527+
两行交给 clang 的字符串**相同**,mcpp 的身份**不同**。用 `-gnu` 把「这个 C 库偏偏不是的
528+
那个东西」写进了身份、输出目录、`cfg(env = …)` 与打包的 ABI 标签。
529+
530+
**描述符侧的风险面实测为零**:`grep -rn 'env = "gnu"' pkgs/` 命中 0 处;提到
531+
`x86_64-windows-gnu` 的三个描述符全是注释。其中 `openkal-uefi.lua` 那条是要点——UEFI
532+
消费方是 PE 目标的**另一种**用法,它继续用 `-gnu` 是对的。**retarget 的范围是
533+
openkal-musl 那一栈,不是所有 PE 用户。**
534+
535+
**单独一轮,不并进 2026.9.21.2**:改测量的目标会改 30 成员测量的**分母**。本轮自己的
536+
判据:同一个成员集合在两个目标上各测一次,逐格比对,任何一格从 `runs`/`builds` 退到
537+
`fails` 都要点名。
464538
465539
### 2.4 生态数据侧
466540

0 commit comments

Comments
 (0)